Logo

iNVASIVECODE - Blog

  • Archive
  • RSS
  • Ask us anything about iOS
banner
What I would like to see at WWDC 2013

As the Apple WWDC 2013 conference approaches, the spotlight has begun shining on the possibilities of what Apple will soon reveal. This year, the major topics revolve around flat UI, anti-skeumorphism, and black and white UI. However, these thoughts are very end-user-centric. What about developers? What will iOS 7 bring to developers?


Well, it is hard to predict these things, but the following is a wish-list of what I really would like to see during the WWDC sessions:

Dev Tools: better LLDB documentation. LLDB is really an amazing tool, but it’s a pity it is documented so poorly. The LLDB documentation is unavailable in the Apple Documentation (but you can still find the GDB documentation). It seems that people writing the documentation did not realize Apple deprecated GDB and introduced LLDB. Today, if you want to learn how to use LLDB, you need to go to this website and combine that poor set of examples with an equally poor help command from the console. I learnt LLDB mainly by watching Apple engineers using it, but damn, how can you find out what you can really do with LLDB from the doc? Additionally, not every LLDB command is implemented in the Xcode UI and the most useful commands are only available through the console. So, I would really see a revamp of the Apple documentation for LLDB at the upcoming WWDC.
Dev Tools: the ability to attach LLDB to a running app from the terminal. At the moment, you can attach LLDB to a running iOS app only through Xcode. However, there are situations where you need to launch the app on a device and attach LLDB from the Terminal.app, because maybe you don’t have the source code of that application, but you developed a framework that application is using. In this case, attaching LLDB from the terminal and using it to debug your framework would save you a lot of trouble. This feature is really missed and it would be great to have it.
Dev Tools: A working merging mechanism to solve NIB and Storyboard conflicts. Why are we still fighting against NIB conflicts in 2013? At Invasivecode, we use NIBs and Storyboards a lot and to reduce the pains at the moment of a merging conflict, we established some internal policies and modify the GIT settings in a certain way to overcome this problem. I would really like to see Xcode solving this issue for us.
Dev Tools: live code injection. When you are debugging some real-time rendering algorithm (for example, while rendering a gradient or a path), you absolutely want this feature. It is really annoying to code, compile, look at the result, stop Xcode, modify the source code and compile again to see the new results. I spend hours with this “boring” cycling procedure to make the rendering perfect. So, can we do that while the application is running on a device or the simulator and inject new code at run-time using Xcode? There is a third-party Xcode plugin that already does that, and it would be great to get it from Apple.
Dev Tools: live preview. I do a lot of image processing work. There, you usually code the algorithm, run it, save some partial results (usually tons of images), then go to the Organizer and download the data from the iPhone or iPad, unzip the files and load the images in the Preview.app to look at the results. Then, if needed, you change again the source code, and go again through the previous procedure. So, what about showing the partial results directly in Xcode while debugging? The same feature could be used for video processing, graphic rendering and so on.
Dev Tools: Xcode plugins. Ok, why did Apple remove this feature from Xcode? For those of you who have never worked with Xcode 3, you should know that you could extend its functionalities by creating and adding plugins. I had some really cool Xcode plugins solving some very specific needs, but when Xcode 4 came out, I lost all of them. Now, since there are some very specific functionalities you want depending on your work, why can’t we build these functionalities by ourselves? I would like to see Xcode plugins again.
Dev Tools: custom Interface Builder objects. This was also available in a previous versions of Developer Tools. Say, you always use a toolbar with 3 buttons or some specific tableview custom cell. In Xcode 3 (when Interface Builder was a standalone application), you could create and add this new object to your IB library and re-use it in every new project. This feature disappeared in Xcode 4. So, can we get it back again?
Dev Tools: Better integration of the project files with GIT. If you are using the Source Control System integrated in Xcode and you work with other developers, I am sure you got this problem. If you did not correctly set up the .gitignore file, the Xcode project files start to give you a lot of merging problems. Last year, I spoke with a couple of Tools Apple engineers during the WWDC. They told me that the problem would have disappeared with the future Xcode releases. It did not. So, I hope this year, the management of the Xcode project files gets better.
Dev Tools: better Certificate and Provisioning Profile management. I have to admit this is improving every year, but it is not perfect yet. We still need to go to the web, login in to the Apple developer portal, generate the digital certificates, download and install them from Xcode. Can we just do everything from Xcode? And can we get a solution to manage multiple identities? This is an issue if you work for different customers and need to create a different identity for each of them. Then, to use the right certificate, you need either to avoid to store your login and password in the keychain or every time you need to change your identity in the keychain.
Dev Tools. Instruments flags. Why have the flags been removed from Instruments? Some months ago, I published this post. This really useful feature has unfortunately been removed from Instruments in iOS. Please, give it back.
Dev Tools. Bug tracker app. It would be great to have a simple tool to track your bugs. Something similar to Radar. Maybe an OS X Server application, you can install on your machine that stores bug reports created by an Xcode client. That would be fantastic.
MapKit. Routes. I think this is one of mine most requested features. It is already available in the Google Map API, but it would be nice to also have it in MapKit. So, given two locations, I would like to be able to get the driving or walking directions between two points and draw them in my app with no need to launch Maps and quit my app. It would be a better user experience.
MapKit. Automatic tiling. In the past, we have developed some iOS apps that needed custom map textures on top of a map view. To do it efficiently, you need to tile the usually large texture at different zoom levels and then, load and render only the tiles corresponding to visible region. I think this feature would be useful for many other developers if it was a standard feature of MapKit.
MapKit. Annotation views clustering. When you have too many annotation views on the map view, you should cluster these views at lower zoom levels to avoid completely covering the map. This is what Apple taught us during one of the past WWDC. So, why isn’t this feature available for everybody as a standard feature?
Networking. Reachability. Why do I need to add the Reachability class to every app I develop when I need to connect to the Internet? This happens mainly for 80% of the iOS apps, right? Can we simply get this feature for free maybe in NSURLConnection?
UIKit. UI customization. There are still portions of UIKit you cannot fully customize. For example, just to mention a few: the title of UIBarButtonItem (yes, I know you can do it using a UIButton, but aren’t we trying to write less code?) or the section index of a UITableview. 
UIKit. State preservation and restoration. These features are very well integrated in Storyboard, but if you are using NIBs, you have to type more code. It would be great to get the same level of integration in the NIB files.
Core Animation. Physics engine. To create more dynamic UIs similar to Facebook Home or create effects similar to the scrollview or tableviews bounces, you need to use a physics engine like Box2D or Chipmunk. It would be great to see any of these open source frameworks fully integrated in Core Animation to simulate gravity, collisions, elasticity and compression.
AVFoundation. API reorganization. This would be a huge change and I don’t think I will see any of it at the next WWDC, but I like to hope. I use AVFoundation a lot in my work, but I don’t understand why it is such a peculiar framework. I am referring to its design. For example, to switch from the rear iPhone camera to the front one, why do I have to loop on all the available cameras and then, exit the loop when I find the camera I want? Or to render the camera frames on GL context, why do I need to write all that source code. Can we also get an update of the examples? Many of them are still using the manual reference count.
iCloud. Well, no comments here. What about deprecating it and starting from the scratch? Instead, can we get a service similar to Parse that allows you to build the functionality in Cocoa and push it to the server?
Siri. Public API. I hope this would be the WWDC dedicated to Siri. I would like to see a new API not only in iOS, but also in Mac, so that we can integrate Siri in our applications.
MapKit. OS X version. Ok, I know Apple Maps were not really a success last year, but still I think they are much better than Google Maps, because fully integrated in iOS. I think Apple should port MapKit to the Mac and to the web. This will allow us to make uniform user experience applications. Why do I have to use Google Maps on my Mac to find directions or places and then, when I am on the road use the Apple Maps? Apple, let developers build cross-platform location service solutions, and you will see that Google Maps will be forgotten.
OpenCL. iOS version. I am tired of using OpenGL to do image processing and you cannot really implement every image algorithm with OpenGL. OpenCL would be the solution. Apple introduced OpenCL for Mac in OS X 10.6 Snow Leopard.
PassKit. The reader. This is a piece missed in the chain. We can build applications generating Passes, but we cannot easily build the reader side of that passes. Can we get the 2D barcode reader functionality?
Core Image. Custom filters. Well, I think it’s time to get this feature. It is already possible on the Mac to build your own custom Core Image filters. Let developers build custom filters.
We develop iOS and OS X apps and have taught iOS (and exclusively iOS) development since 2008. We have not jumped into the multi-platform game yet. However, during the last few months, we are seeing a consistent number of iOS developers starting to work with other mobile platforms searching for new revenues and business models. Apple should stop this migration otherwise this will slowly kill the platform in combination with the smaller competitive advantages. Apple needs to create technologies which will lock developers in the iOS platform (such as Passbook or Siri or Core Bluetooth). These technologies should be easy to integrate and very difficult to replicate on other platforms without the support of Google and Microsoft.

If developers stop to develop the same app for every mobile platform, users will prefer to buy a smartphone providing only the best and most useful apps. This is the issue Microsoft is facing now: the phones are great piece of hardware, but useless because most of the most useful applications are still missing.

I hope Apple will continue to listen to developers.

Geppy
Pop-upView Separately

What I would like to see at WWDC 2013

As the Apple WWDC 2013 conference approaches, the spotlight has begun shining on the possibilities of what Apple will soon reveal. This year, the major topics revolve around flat UI, anti-skeumorphism, and black and white UI. However, these thoughts are very end-user-centric. What about developers? What will iOS 7 bring to developers?

Read More

    • #wwdc
    • #WWDC 2013
    • #wishlist
    • #apple
    • #iOS
    • #iOS 7
    • #Xcode
    • #Developers Tools
    • #Instruments
    • #Core Image
    • #AVFoundation
    • #Networking
    • #LLDB
  • 2 weeks ago
  • 1
  • Permalink
  • Share
    Tweet
iNVASIVECODE & iDEVELOPER TV are pleased to announce:

WWDC BASH MINI

Venue: The Runway, 1355 Market St, San Francisco

Date: June 10

Time: Starting at 7pm

No registration is required.
Pop-upView Separately

iNVASIVECODE & iDEVELOPER TV are pleased to announce:

WWDC BASH MINI

Venue: The Runway, 1355 Market St, San Francisco

Date: June 10

Time: Starting at 7pm

No registration is required.

    • #wwdc
    • #wwdc 2013
    • #bash
    • #invasivecode
    • #idevelopertv
  • 1 month ago
  • Permalink
  • Share
    Tweet
Customization of UI controls

Before the launch of iOS 5, the customization of some UI elements (navigation bars, switches, etc.) was possible only writing a lot of code, subclassing or adding categories for each UI component. With iOS 5 Apple provided developers with a simpler way of customizing UI elements. Later, with iOS 6, every UI component became quite fully customizable.



Here, I’ll be covering the customization of just some of the UI elements, but after this small tutorial, it should be easy for you to explore by yourself the remaining UI components.

A remark before you dive into this tutorial: although it’s true that you can now customize the UI elements easily, you should still stick to the Human Interface Guidelines. Please, review those guidelines and apply some common sense to your customizations.

Fig. 1 highlights the results, one by one, of what we are going to see below.



Fig. 1. The results of the customization

The customization of the UIStepper controller

In iOS 6, Apple introduced a batch of properties that allow you to change the appearance of the UIStepper controller.  Item 1 of Fig. 1 is the out-of-the-box version of the UIStepper. Let’s try now to change its appearance.

Tint Color

This is a very simple modification. The tint color of the UIStepper can be modified using the following line of code:

[self.stepper setTintColor:[UIColor redColor]];


The result can be seen in item 2 of Fig. 1.

Background image

Additionally, you can set an image as background of the UIStepper. Different images can be set depending on the stepper state. Item 3 of Fig. 1 is obtained using the following line of code:

[self.stepper setBackgroundImage:[UIImage imageNamed:@"pattern"]
          forState:UIControlStateNormal];


Now, the Apple documentation says: “For good results, image must be a stretchable image”. What does that mean? I will show you this later in the ‘Tiling and stretching images’ section below. Let’s continue with the stepper appearance.

Note: The image used in the above example can be downloaded here: pattern.png and pattern@2x.png.

Divider

The divider (the vertical line between the left and right button) can be modified setting a new image and the following line of code shows how to obtain item 4 in Fig 1:

[self.stepper setDividerImage:[UIImage imageNamed:@"divider"] 
            forLeftSegmentState:UIControlStateNormal
            rightSegmentState:UIControlStateNormal];


The divider image used in the example is a 5x50 image and you can download it here: divider.png and divider@2x.png.

Increment and Decrement Image

You can set an image for the increment and decrement button depending on the button state with the following lines of code:

[self.stepper setDecrementImage:[UIImage imageNamed:@"less"] 
            forState:UIControlStateNormal];
[self.stepper setIncrementImage:[UIImage imageNamed:@"more"] 
            forState:UIControlStateNormal];


Find an example in Fig.1 item 5.

The images used in the above example can be downloaded here: less.png, less@2x.png, more.png, and more@2x.png.

Customizing UISwitch

UISwitch is another control that can be fully customized. We have again a few properties available. Let’s see how to implement them one by one. You can see the default appearance of a UISwitch in Fig. 1 item 6.

Tint Color

Again, this is similar to the UIStepper case:

[self.switch setTintColor:[UIColor darkGrayColor]];


This line of code produces item 7 of Fig. 1 as a result.

On Tint Color

You can change the color used to tint the appearance of the switch when it is turned on. See the result on Item 8 using the following line of code:

[self.switch setOnTintColor:[UIColor blackColor]];


Thumb Tint Color

To change the color of the switch thumb, you can do this (check the result in Item 8 of Fig 1):

[self.switch setThumbTintColor:[UIColor yellowColor]];


Background Image

You can apply a background image to the switch. On and Off states are independent, so you can set a different image for each position. Note that if you want to use this property, you should probably add some text as a hint to the user. See Item 9 of Fig. 1 and check that is kind of difficult to understand what this switch would do compared to the default, where On is clearly written.

[self.switch setOnImage:[UIImage imageNamed:@"pattern"]];
[self.switch setOffImage:[UIImage imageNamed:@"pattern"]];


Customizing bars

UINavigationBar, UIToolbar and UITabBar have now a shadow image. The navigation bar shows a shadow at the bottom, while a tab bar shows it at the top. The toolbar shows a shadow at the top or at the bottom, depending on its position on the screen. You can change the custom shadow and apply your own shadow image with a simple line of code. Here are some examples and you can see the outcome from the first line of code on Item 10 of Fig. 1:

[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar"] 
            forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setShadowImage:[UIImage imageNamed:@"shadow"]];


If you are using a UIToolBar, the shadow image is set depending of the position of the toolbar (top/bottom):

[self.toolBar setBackgroundImage:[UIImage imageNamed:@"toolbar"] forToolbarPosition:UIToolbarPositionTop barMetrics:UIBarMetricsDefault];


Customizing same elements through the whole application

What we’ve seen so far is really useful and easy to use, but maybe you want to use the same customization of a UI element along your application. Apple gives us a way to customize a UI element and keep that customization in the whole app. To do so, you need to use the UIKit UIAppearance protocol. You customize the appearance of instances of a UI element by sending appearance modification messages to these protocol.

There are two ways to customize appearance for objects:

Customization of all instances of a class
Customization for instances of a class contained within a container class
Let’s see how to customize the text in the UINavigationBar for the whole application. In the application:didFinishLaunchWithOptions: method in your AppDelegate class, write the following:

[[UINavigationBar appearance] setTitleTextAttributes:@{
UITextAttributeTextColor : [UIColor whiteColor],
UITextAttributeTextShadowColor : [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0],
UITextAttributeTextShadowOffset : [NSValue valueWithUIOffset:UIOffsetMake(-0.1, -1.0)],
UITextAttributeFont : [UIFont fontWithName:@"Papyrus" size:21.0] }];


Here, we’ve been setting the text attributes of the UINavigationBar title. Then, we’ve passed the dictionary with these attributes to the appearance.
These attributes will be applied to every navigation bar in the application.

You can see the visual result on our Item 10 of Fig. 1. Sometimes, you can use appearanceWhenContainedIn: in place of appearance, when you want to provide a different customization to a UI element that is contained in a container class. For example, suppose you want every UIBarButtonItem have a red background color, except when they are added to a toolbar. In this case, you can use the appearanceWhenContainedIn: method to customize those bar button items.

Tiling and stretching images

The retina display is amazing, especially on the iPad. I really love it. However, this kind of display introduced so many technical challenges. One of them is the final application size. For example, think of a navigation bar on the new iPad (with retina display). Imagine you want to customize it with a background image. You need to prepare a 768x44 image (non-retina version) and a 1536x88 image (retina version). Sometimes, you need also to add the landscape versions of the same navigation bar, so a 1024x44 image and a 2048x88 image. So, you end up with four images just for the navigation bar.
Same rule applies to every UI element. Well, there is a way to reduce the application size.

If you are not using any special texture on the navigation bar, you can simply pass a 3x44 image for both landscape and portrait low-resolution and a 6x88 image for both the landscape and portrait high-resolution cases. How? Check the following Fig.2:



Fig. 2. UIEdgeInsets structure

You can associate to an image a UIEdgeInsets structure. As highlighted in Fig. 2, the structure contains 4 float numbers: top, left, bottom and right. Those are the portions of the image that are kept fixed during the image scaling. The intermediate portion of the image (horizontally and vertically) gets instead stretched or tiled by UIKit if you ask so.

You can do this in the following way:

UIImage *imageIn = [UIImage imageNamed:@"image"];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(5.0f, 13.0f, 5.0f, 13.0f);
UIImage *imageRes = [imageIn resizableImageWithCapInsets:edgeInsets];


The first line simply loads an image. The second line creates the edge insets. Finally, the third line resizes the input image using the previously defined edge insets. The resulting image imageRes is identical to the original image imageIn, but during scaling or resizing, areas covered by a cap are not scaled or resized. Instead, the pixel area not covered by the cap in each direction is tiled, left-to-right and top-to-bottom, to resize the image. For best performance, Apple suggests to use a tiled area that is a 1x1 pixel area in size.

What if you want to stretch instead of tiling. You can use the resizableImageWithCapInsets:resizingMode: method and pass UIImageResizingModeStretch as a second argument.

Final remarks

You will agree with me that the customization of the iOS UI has become simpler, right? You can create custom elements very easily like we’ve been doing through this tutorial.

Hope this post was useful! Thanks for reading!

Javi
Pop-upView Separately

Customization of UI controls

Before the launch of iOS 5, the customization of some UI elements (navigation bars, switches, etc.) was possible only writing a lot of code, subclassing or adding categories for each UI component. With iOS 5 Apple provided developers with a simpler way of customizing UI elements. Later, with iOS 6, every UI component became quite fully customizable.

Read More

    • #iostrainig
    • #invasivecode
    • #ui
    • #customization
    • #uiappearance
    • #uikit
    • #custom
    • #controlls
    • #ui element
  • 2 months ago
  • 2
  • Permalink
  • Share
    Tweet
Mixing ARC and MRC source code in the same class

The Automated Reference Counting (ARC) mechanism was introduced with iOS 5 to make developer’s life easier. Until iOS 5 the developer had to manually keep track of the number of references (Manual Reference Counting or MRC) to every allocated object and release correctly it after that object was not anymore needed.

So, for example, before iOS 5, you had to write something like this:

NSArray *anArray = [[NSArray alloc] initWithObjects:@"one", @"two", nil];
self.myArrayProperty = anArray;
[anArray release];


The last line of code was necessary to release the anArray object and avoid a memory leak. When you use ARC, the previous 3 lines of code become:

self.myArrayProperty = [[NSArray alloc] initWithObjects:@"one", @"two", nil];


Really cool. So, developers don’t need anymore to keep track of the number of references to the allocated object and (also very important), developers write now less code.

Let’s make clear this too. ARC is NOT a runtime mechanism. It has nothing to do with the Garbage Collection previously available in Cocoa (Mac) and still available in Java and other languages. ARC is a compiler level feature that automatically inserts the release and retain during the compilation phase.

Now, to keep backward compatibility with old MRC code you can mark in Xcode those files you want ARC to ignore. But you can also mix in the same class ARC and MRC code, using the __has_feature compiler macro. This macro is part of Clang, part of LLVM. For more information about LLVM, you should absolutely check this website: http://llvm.org.

So, for example, imagine you are building next killer iOS app and using ARC in your project. It could be you need to integrate quickly some MRC code you got from Github or somewhere else. Yes, sure you can convert that code to ARC, but maybe it’s faster if you do this:

#if !__has_feature(objc_arc)
    // here you put the MRC code
#endif


And if you need you can obviously also do this:

- (void)dealloc {
#if !__has_feature(objc_arc)
    [super dealloc];
    // here you put the MRC code
#else
    // here you put the ARC code (maybe removing the notifications from NSNotificationCenter)
#endif


If you want ARC to exclude an entire class file (the .m), you need to go to Target Build Phases and in the Compiler Sources you add the -fno-objc-arc flag as shown in the following figure:



Keep coding,

Geppy
Pop-upView Separately

Mixing ARC and MRC source code in the same class

The Automated Reference Counting (ARC) mechanism was introduced with iOS 5 to make developer’s life easier. Until iOS 5 the developer had to manually keep track of the number of references (Manual Reference Counting or MRC) to every allocated object and release correctly it after that object was not anymore needed.

Read More

    • #arc ios iostraining invasivecode memory xcode
    • #developers tools
  • 3 months ago
  • 3
  • Permalink
  • Share
    Tweet
CAEmitterLayer and the iOS particle system

Let’s talk today about particle systems… particle, what? Yes, you’ve heard it right. You’ve probably seen it already in many iOS apps, particularly in game applications. I think this is a really cool Core Animation tool you can use in your projects.

Apple introduced with iOS 5 an entire family of specialized layers, subclasses of the CALayer class: CAEAGLLayer, CAEmitterLayer, CAGradientLayer, CAReplicatorLayer, CAScrollLayer, CAShapeLayer, CATextLayer, CATransformLayer. Each of those classes has been designed for a very specific task.

Before we move forward, I highly recommend you to give a look at the following posts where you can find an introduction about basic concepts of Core Animation:

Part I: Warm Up
Part II: Layers Everywhere
Part III: Basic Animations
Part IV: Grouping Animations
Part V: Keyframe Animations 
Part VI: Replicator Layers
Replicator Layers
Transform Layers 
The concept of particle systems

We are going to dive today into the CAEmitterLayer class, which is the class that provides a particle emitter system in Core Animation.

Let’s start reviewing the main concepts. The term particle system is defined in computer graphics. A particle system is composed of a large number of small graphic objects that work together to simulate different group dynamics, like fire, smoke, fog, snow, rain, explosions, meteor tails,…

There are two classes that you need to use in order to create a particle systems: CAEmitterLayer and CAEmitterCell. The CAEmitterLayer acts as the particle emitter (the source of the particles) and the CAEmitterCell represents the particle being emitted.

Let’s build a project

Let’s put all the theory in practice with a very simple example. Launch Xcode and create a new Single-View Application iPhone project. Name it ParticleEmitter. Add the QuartzCore framework to the project and in the ViewController.h add:

#import <QuartzCore/QuartzCore.h>


Now, go the ViewController.m and edit the viewDidLoad method as follows:

CAEmitterLayer *emitterLayer = [CAEmitterLayer layer]; // 1 
emitterLayer.emitterPosition = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.origin.y); // 2
emitterLayer.emitterZPosition = 10; // 3
emitterLayer.emitterSize = CGSizeMake(self.view.bounds.size.width, 0); // 4
emitterLayer.emitterShape = kCAEmitterLayerSphere; // 5


Line 1 creates a particle emitter system, line 2 and 3 specifies the position where the layer will be, line 4 specifies the size of the particle emitter shape and line 5 specifies the emitter shape. If you check the CAEmitterLayer in the documentation you will learn about different geometries you can set for the emitter layer. In our example, I chose a sphere and I set the position accordingly, but if you choose a shape point. you will have to set only its position.

Now, that we have the particle emitter, let’s create the particles. First of all, we need an image of what our particle will be. I created a simple colored ball and I imported my .png file to the project.

Now, let’s go back to the viewDidLoad method and add the following lines of code:

CAEmitterCell *emitterCell = [CAEmitterCell emitterCell]; // 6
emitterCell.scale = 0.1; // 7
emitterCell.scaleRange = 0.2; // 8
emitterCell.emissionRange = (CGFloat)M_PI_2; // 9
emitterCell.lifetime = 5.0; // 10
emitterCell.birthRate = 10; // 11
emitterCell.velocity = 200; // 12
emitterCell.velocityRange = 50; // 13
emitterCell.yAcceleration = 250; // 14


Line 6 creates the emitter cell. Line 7 specifies the scale factor applied to the cell and line 8 the range over which the scale value can vary during the animation (the system controls that). Line 9 sets the angle defining a cone around the emission angle. From line 10 to 14 we set different emitter cell temporal attributes like the lifetime of the cell (in seconds), the birth rate (the number of emitted objects created every second), the initial velocity of the cell, the velocity range (the amount by which the velocity of a cell can vary) and the y component of the acceleration vector applied to the cell.

Let’ now provide the cell content:

emitterCell.contents = (id)[[UIImage imageNamed:@"WaterDrop.png"] CGImage]; // 15


and finally, let’s add the emitter cell to the emitter layer:

self.emitterLayer.emitterCells = [NSArray arrayWithObject:emitterCell]; // 16


The last thing we need to do is to add the emitter layer to our view’s layer, so that all the work we’ve done is actually visible. To do that, add the following line of code:

[self.view.layer addSublayer:emitterLayer]; // 17


Now, just build and run and you should see the following result:



Particle System in iOS from iNVASIVECODE.

Very cool, right? I encourage you to play with the properties we used in our small example and check the documentation where you will find other properties you could use. I am attaching here an example. There, I added 2 emitter cells to get more cell types.

I hope you enjoyed,

Eva
Pop-upView Separately

CAEmitterLayer and the iOS particle system

Let’s talk today about particle systems… particle, what? Yes, you’ve heard it right. You’ve probably seen it already in many iOS apps, particularly in game applications. I think this is a really cool Core Animation tool you can use in your projects.

Read More

    • #core animation
    • #@coreanimation
    • #emitter layer
    • #caemitterlayer
    • #caemittercell
    • #particle system
  • 3 months ago
  • 2
  • Permalink
  • Share
    Tweet
Google Maps API for iOS with Interface Builder

Today, Google released the Google Map API for iOS. Here you can find all the necessary information you need. You have to register and get the API Key as usual.



In the section “Adding the Google Maps SDK for iOS to your project”, they explain how to build a simple example. However, they add the map view programmatically. If you are like me that prefer using Interface Builder, follow these steps to fix this.

After you add the framework to your project, open the view controller in which you want to add the map. Then, go to the main view controller view and add a new view (a UIView object). Select the view and in the Identity Inspector (next figure), change the class from UIView to `GMSMapView’. If you want, you can also change the name of the object fixing the Label to GMSMapView.



Now, you simply treat this view as the standard Apple MKMapView. You can add an outlet to your code and from there do the rest of you work.
I am attaching here an example show this. Don’t forget to add your API key in the application:didFinishLaunchingWithOptions: of the App delegate.

The same solution works for the iPad. Just add to the iPad app the view as shown above and you are done.

Eva
Pop-upView Separately

Google Maps API for iOS with Interface Builder

Today, Google released the Google Map API for iOS. Here you can find all the necessary information you need. You have to register and get the API Key as usual.

Read More

    • #MapKit
    • #GoogleMaps
    • #iOS
    • #iOS 6
    • #SDK
    • #Framework
    • #Interface Builder
    • #Xcode
  • 3 months ago
  • Permalink
  • Share
    Tweet
Auto Layout and Core Animation

Auto Layout was introduced by Apple in OS X 10.7 Lion and now, it is available in iOS 6. Auto Layout is really an interesting and useful technology: it solves one of the most important issues layout the user interface to screen size changes. These changes can be either due to screen orientation changes (landscape to portrait and vice versa) or due to new screen size (iPhone 5).

Before Auto Layout, you had to code the layout for each UI element and interface orientation. Additionally, if there were variations of the content size (for example, change of the text length in the button title, because of the text localization or different height of the tableview cells because of the different text content, and so on), you had again to manage that by yourself adding a lot of extra code just to make things look right.

Auto Layout fixes all these problems for you: it automatically adjustes the layout of the UI elements according to some simple rules you provide.

Now, there are already different tutorials about Auto Layout in the Internet and I don’t want to provide here a new one. If you want to know more about Auto Layout, check the WWDC12 videos or check here our on-site training classes.

Instead, what I want to show you here is how to combine correctly Auto Layout and Core Animation. In fact, if you already tried to use both, you noticed that it is really hard to animate a view and keep the constraints you fixed in Interface Builder or programmatically. This is especially true, if you are trying to animate the view frame.

Let’s give a look at this particular problem. Launch Xcode and create a Single View Application. Name it LayoutMagic. Open the ViewController.xib file. Make sure Auto Layout is active (it should be already active by default): the Use Autolayout flag should be selected  (Fig.1).



Then, add a navigation bar to view top as shown here:



Make sure the navigation bar has the same constraints shown in the following picture:



Here, you can see that the navigation bar is constrained to the top, the leading and trailing space to its superview. This means if the superview layout changes, the navigation bar will be constrained to the top of the view.

Let’s see what happens if you animate the navigation bar frame in the usual way. Let’s add a tap gesture recognizer to the main view, so that every time you tap onto this view, the navigation bar moves out of or into the screen with a smooth animation. Obviously, we need an outlet to the navigation bar. So, I create its property in the ViewController.h file:

@property (weak, nonatomic) IBOutlet UINavigationBar *navbar;


and connect it to the navigation bar in Interface Builder. Now, go to the viewController.m file and add the following instance variable:

@implementation ViewController
{
    BOOL _isVisible;
}


We need this boolean to check if the navigation bar is on the screen. In the viewDidLoad, add the following lines of code:

_isVisible = YES;

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)];
[self.view addGestureRecognizer:tap];


As you know, the handleTapFrom: method will be fired every time you tap on the view. Now, if we had no Auto Layout, we could simply write the implementation of this method in this way (maybe in a more elegant way than here, but this is enough for this example):

- (void)handleTapFrom:(UIGestureRecognizer *)gesture {
    if (_isVisible) {
        _isVisible = NO;
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar setFrame:CGRectMake(0, -44, 320, 44)];
        }];
    } else {
        _isVisible = YES;
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar setFrame:CGRectMake(0, 0, 320, 44)];
        }];
    }
}


As you can see, I check if the navbar is visible. Depending on that, I animate the navigation bar frame in or out of the screen.

Now, if you try it, the animation works perfectly here. But… try to change the orientation of the device to landscape and tap on the main view a couple of times (Fig. 4). Wrong, right? This is not what you really want.



This happens because the above source code is forcing the frame of the navigation bar to the size of the view in portrait and the Auto Layout constraints added in Interface Builder get broken. We could fix this detecting the UI orientation and adding some lines of code to adjust the UI layout depending if the UI orientation. But, you don’t want to do that again.

Auto Layout to the rescue!

So, let’s see how to fix the wrong layout of the previous picture using Auto Layout. In Auto Layout, each constraint is a UIKit object of type NSLayoutConstraint. Very important, this object is animatable. You know that a constraint is represented by the following linear equation:

attribute1 = multipler × attribute2 + constant 


In the particular case of our navigation bar, the top constraint (between the top edge of the navigation bar and the top edge of the superview) can be expressed in this way:

navbar.NSLayoutAttributeTop = multiplier x view.NSLayoutAttributeTop + constant


where in our initial conditions multiplier = 1.0 and constant = 0.0. Then, the previous equation becomes

navbar.NSLayoutAttributeTop = view.NSLayoutAttributeTop


Now, we want to animate the navigation bar, so that

navbar.NSLayoutAttributeTop = view.NSLayoutAttributeTop - 44.0


This means we want to move the top edge of the navigation bar 44 points away from the top edge of the main view.

Let’s translate everything in code, but first, we need an outlet to the constraint we want to animate. So, select the Vertical Space - Navigation Bar - View constraint and create this outlet:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;


Connect this property to the constraint in Interface Builder. Now, the previous handleTapFrom: method becomes:

- (void)handleTapFrom:(UIGestureRecognizer *)gesture {
    if (_isVisible) {
        _isVisible = NO;
        self.topConstraint.constant = -44.;    // 1
        [self.navbar setNeedsUpdateConstraints];  // 2
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded]; // 3
        }];
    } else {
        _isVisible = YES;
        self.topConstraint.constant = 0.;
        [self.navbar setNeedsUpdateConstraints];
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded];
        }];
    }
}


Here, the important steps are:

You fix the final value of the constraints. In this case, we want to change the constant of the topConstraint property to -44.0.
Then, you notify the navigation bar that needs to update the constraints
And finally, within the animation block, you force the layout of the navigation bar 
Build and run it. Check the portrait and landscape orientation. Everything works fine.
You can download the example from here.

Keep coding.

Geppy
Pop-upView Separately

Auto Layout and Core Animation

Auto Layout was introduced by Apple in OS X 10.7 Lion and now, it is available in iOS 6. Auto Layout is really an interesting and useful technology: it solves one of the most important issues layout the user interface to screen size changes. These changes can be either due to screen orientation changes (landscape to portrait and vice versa) or due to new screen size (iPhone 5).

Read More

    • #autolayout
    • #core animation
    • #uikit
    • #appkit
    • #iOS training
    • #animation
    • #frame
  • 4 months ago
  • 4
  • Permalink
  • Share
    Tweet
Core Bluetooth for iOS 6

Core Bluetooth was introduced for the first time in iOS 5 to allow iOS devices to consume data provided by devices used in healthcare, sport/fitness, security, automation, entertainment, proximity and so on. In iOS 6.0, this API was extended to allow also iOS devices to serve data.

The Core Bluetooth API is based on the Bluetooth 4.0 Low Energy (LE) specifications. This framework takes care of all the details of the Bluetooth LE standard. However, it is designed to provide developers with the necessary level of control.

Only the latest iOS devices and Macs are compliant with the Bluetooth LE specifications: iPhone 4S, iPhone 5, Mac Mini, the New iPad, MacBook Air, MacBook Pro. Additionally, the iOS 6 iPhone Simulator supports the same standard. This is really useful during the development of your app, because it allows you to test it against the iPhone Simulator with no need to have an extra device.

Involved classes

In the Core Bluetooth (CB) framework, you have 2 major players: Peripheral and Central. The entire framework is designed around these two major components and based on a set of callbacks exchanged between them. Next Fig. 1 highlights the Peripheral, the Central and their relationship.



The Peripheral is the device generating or serving the data. The Central is the device consuming these data. Starting with iOS 6, an iOS device can be both a Peripheral and a Central (never at the same time).

Each of the two components is represented by a class of the Core Bluetooth framework. The Central is represented by the CBCentralManager class, while the Peripheral is represented by the CBPeripheralManager one.

On the Central, a CBPeripheral object represents the corresponding Peripheral that the Central is connected to. Similarly, on the Peripheral, the CBCentral object  represents the client the Peripheral connected to.

You can also think of the Peripheral as the device broadcasting the data. It starts advertising to the external world that it has some data. So, it advertises that it can provide services. On the other side, the Central starts to scan the environment looking for some service. If the Central finds the wanted service, then it asks the Peripheral to connect. Once the connection is established, the 2 devices start to exchange data.

Besides the Central and the Peripheral, we have to consider the structured data they exchange. These data are structured in Services. Each Service is then composed by different Characteristics. Characteristics are defined attribute types that contain a single logical value. If you go to http://developer.bluetooth.org, you can find the list of the standardized services and characteristics.

On the Central, services are represented by the CBService class. Each of the services is then composed by characteristics represented by the CBCharacteristic class. Similarly, the services and the characteristics on the Peripheral are represented by the CBMutableService class and the CBMutableCharacteristicclass, respectively. The following Fig. 2 highlights the structure of the classes as explained until now.



The CBUUID and CBATTRequest are 2 helper classes that Apple added to the framework to make easier for the developer to manipulate data. We will see later how to use them.

Usage

Unfortunately, the Apple documentation of the Core Bluetooth framework is currently not complete. Some of the involved classes actually miss the documentation. The only way to understand how this framework works is to watch the 2 WWDC videos on Core Bluetooth and then navigate its header files. So, since I have already done it some time ago, I decided to share this with you. At iNVASIVECODE, we already developed a few applications using the Core Bluetooth framework. We are really impressed by the quantity of new applications you can start to develop. So, I hope this tutorial is really helpful for you. You can also learn more on this framework (and others), if you are able to attend to one of our training classes. Check at http://training.invasivecode.com for our next class.

Building a Peripheral

Let’s build a full example. You need to have 2 iOS devices. I will show you how to connect 2 iOS devices via Bluetooth and exchange data. Remember to check if your devices are in the above list of the Bluetooth LE compliant devices.

Let’s start with the Peripheral. We need to follow these steps:

Create and start the Peripheral Manager
Setup and publish its services
Advertise the services
Interact with the Central
Create a new Xcode project using the Single-View Application template. Name it BlueServer (use ARC). Once the project is created, add the CoreBluetooth.framework to it. Then, open the ViewController.h file and add the following line:

#import <CoreBluetooth/CoreBluetooth.h>


Make the view controller conform to the CBPeripheralManagerDelegate protocol. Also add this property:

@property (nonatomic, strong) CBPeripheralManager *manager;


In the ViewController.m, add the following line to your viewDidLoad method:

self.manager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];


This line initializes the Peripheral Manager (first item of the above todo list). The first argument sets the delegate (in this case the view controller). The second argument (the queue) is set to nil, because the Peripheral Manager will run on the main thread. If you want to use a different thread to do more sophisticated things, then you need to create a queue and pass it here.

Once the Peripheral Manager is initialized, we need to check immediately its state. This allows to check if the device your application is running on is compliant with the Bluetooth LE standard. You do this implementing the following delegate method (here you can do more sophisticated things and gracefully notify the user in case the device is not compliant with the Bluetooth LE):

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    switch (peripheral.state) {
        case CBPeripheralManagerStatePoweredOn:
            [self setupService];
            break;
        default:
            NSLog(@"Peripheral Manager did change state");
            break;
    }
}


Here, I check the state of the Peripheral. If its state is CBPeripheralManagerStatePoweredOn, then the device is using Bluetooth LE and you are good to go.

Service and Characteristic

The -setupService method is a helper method I created to prepare the service and its characteristics. For this example, I am going to use only one service with one characteristic.

Each service and characteristic must be identified by a unique identifier (UUID). UUIDs can be 16- or 128-bit values. If you are building your client-server (central-peripheral) application, then you need to create your own 128-bit UUIDs. You need to make sure they won’t collide with other existing services provided by other applications maybe closer to your device. If you are building a new device, this is achieved requesting the UUID to the standard committee. If you are building your client-server application (as we are doing now), I suggest you to use the uuidgen command in the Terminal.app. This command generates 128-bit UUIDs. So, open the Terminal.app and generate 2 of them (one for the service and one for the characteristic). Then, you need to add them to the Central and the Peripheral app. For the moment, let’s add the following lines before the implementation of the view controller:

static NSString * const kServiceUUID = @"312700E2-E798-4D5C-8DCF-49908332DF9F";
static NSString * const kCharacteristicUUID = @"FFA28CDE-6525-4489-801C-1C060CAC9767";


Notice that the UUIDs you get from the Terminal app are different than mine. And this is good. So, for this example, just use the UUIDs you obtained with the uuidgen command.

Now, this is the implementation of the -setupService method I used in the previous chunk of code:

- (void)setupService {
    // Creates the characteristic UUID
    CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID];

    // Creates the characteristic
    self.customCharacteristic = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];

    // Creates the service UUID
    CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID];

    // Creates the service and adds the characteristic to it
    self.customService = [[CBMutableService alloc] initWithType:serviceUUID primary:YES];

    // Sets the characteristics for this service
    [self.customService setCharacteristics:@[self.customCharacteristic]];

    // Publishes the service
    [self.peripheralManager addService:self.customService];
} 


First, I create the UUID object for the characteristic using the +UUIDWithString: method. Then, I create the characteristic with that UUID. Notice that I pass nil to the third argument (the value) of the init method. Doing so, I am telling Core Bluetooth that I am going to add the value of the characteristic later. This is usually done, when you want to create the data dynamically. If you already have a static value to transmit, then you can pass it here.

In the same method, the first argument is the UUID previously created. The second argument (the properties) determines how the characteristic value can be used. These are the possible values:

CBCharacteristicPropertyBroadcast: permits broadcasts of the characteristic value using a characteristic configuration descriptor. Not allowed for local characteristics.
CBCharacteristicPropertyRead: permits reads of the characteristic value.
CBCharacteristicPropertyWriteWithoutResponse: permits writes of the characteristic value, without a response.
CBCharacteristicPropertyWrite: permits writes of the characteristic value.
CBCharacteristicPropertyNotify: permits notifications of the characteristic value, without a response.
CBCharacteristicPropertyIndicate: permits indications of the characteristic value.
CBCharacteristicPropertyAuthenticatedSignedWrites: permits signed writes of the characteristic value
CBCharacteristicPropertyExtendedProperties: if set, additional characteristic properties are defined in the characteristic extended properties descriptor. Not allowed for local characteristics.
CBCharacteristicPropertyNotifyEncryptionRequired  : if set, only trusted devices can enable notifications of the characteristic value.
CBCharacteristicPropertyIndicateEncryptionRequired: if set, only trusted devices can enable indications of the characteristic value.
The last argument of the same init method is the read, write, and encryption permissions for an attribute. Possible values are:

CBAttributePermissionsReadable
CBAttributePermissionsWriteable
CBAttributePermissionsReadEncryptionRequired
CBAttributePermissionsWriteEncryptionRequired 
After creating the characteristic, I create the service with again the +UUIDWithString:, passing it the previously defined service UUID string. Finally, I set the characteristic for the service. Remember, each service can contain more characteristics as shown in the next Fig 3.



So, we need to create an array of characteristics and pass it to the service. In this simple case, the array contains only one characteristic.

The last line of code is used to publish the service adding it to the Peripheral Manager. Once done that, the Peripheral Manager notifies its delegate with the method -peripheralManager:didAddService:error:. Here, if there is no error, you can start advertising the service:

- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error {
    if (error == nil) {
        // Starts advertising the service
        [self.peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey : @"ICServer", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:kServiceUUID]] }];
    }
}


When the Peripheral Manager starts advertising the service, its delegate receives the message -peripheralManagerDidStartAdvertising:error: and when the Central subscribes to the service, the delegate receives -peripheralManager:central:didSubscribeToCharacteristic:. This is the place where you can generate dynamic data for the Central.

Now, to send data to the Central, you need to prepare some chunk of data and then send updateValue:forCharacteristic:onSubscribedCentrals: to the Peripheral.

Building a Central

Now that we have the Peripheral, let’s build our Central (the client). Remember, the Central is the device consuming the data provided by the Peripheral. As I highlighted in Fig. 1, the Central is represented by the CBCentralManager object.

So, let’s create a new Xcode project and name it BlueClient. Use ARC. Add the CoreBluetooth.framework to your target and import it in the view controller header:

#import <CoreBluetooth/CoreBluetooth.h>


On the Central, your class must be conform to 2 protocols: the CBCentralManagerDelegate and the CBPeripheralDelegate.

@interface ViewController : UIViewController <CBCentralManagerDelegate, CBPeripheralDelegate>


Also add these two properties:

@property (nonatomic, strong) CBCentralManager *manager;
@property (nonatomic, strong) NSMutableData *data;


Now, as I already did for the Peripheral, I create a Central object:

self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];


Again, the first argument represents the CBCentralManager delegate (in this case the view controller). The second argument is instead the dispatch queue on which the events will be dispatched. Again, if you pass nil, you are telling the Central Manager that you want to use the main queue.

Once the Central Manager is initialized, its state can be checked. This will allow to verify that the device your application is running on is Bluetooth LE compliant. You do this implementing the following delegate method:

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    switch (central.state) {
        case CBCentralManagerStatePoweredOn:
            // Scans for any peripheral
            [self.manager scanForPeripheralsWithServices:@[ [CBUUID UUIDWithString:kServiceUUID] ] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
            break;
        default:
            NSLog(@"Central Manager did change state");
            break;
    }
}


The -scanForPeripheralsWithServices:options: method is used to tell the Central Manager to start looking for a specific service. If you pass nil as first argument, the Central Manager starts to look for any service.

The kServiceUUID is the same UUID string I used for the Peripheral, so add again these 2 lines of code before your class implementation:

static NSString * const kServiceUUID = @"312700E2-E798-4D5C-8DCF-49908332DF9F";
static NSString * const kCharacteristicUUID = @"FFA28CDE-6525-4489-801C-1C060CAC9767";


Remember to use the UUIDs you obtained from the uuidgen command.

As soon as a Peripheral is discovered during the scanning, the Central delegate receives the following callback:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI   


This call notifies the Central Manager delegate (the view controller) that a peripheral with advertisement data and RSSI was discovered. RSSI stands for Received Signal Strength Indicator. This is a cool parameter, because knowing the strength of the transmitting signal and the RSSI, you can estimate the current distance between the Central and the Peripheral. So, you can use the distance as a filter for a given service: only if the Central is close enough to the Peripheral, then your app does something.

Any advertisement/scan response data stored in advertisementData can be accessed via the CBAdvertisementData key. Here, you can now stop the scanning and connect to the Peripheral:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    // Stops scanning for peripheral
    [self.manager stopScan];

    if (self.peripheral != peripheral) {
        self.peripheral = peripheral;
        NSLog(@"Connecting to peripheral %@", peripheral);
        // Connects to the discovered peripheral
        [self.manager connectPeripheral:peripheral options:nil];
    }
}


The options parameter is an optional dictionary (NSDictionary) and can use the following keys if needed (their value is always a boolean):

CBConnectPeripheralOptionNotifyOnConnectionKey. This is a NSNumber (Boolean) indicating that the system should display an alert for a given peripheral, if the application is suspended when a successful connection is made. This is useful for applications that have not specified the Central background mode and cannot display their own alert. If more than one application has requested notification for a given peripheral, the one that was most recently in the foreground will receive the alert.
CBConnectPeripheralOptionNotifyOnDisconnectionKey. This is a NSNumber (Boolean) indicating that the system should display a disconnection alert for a given peripheral, if the application is suspended at the time of the disconnection.
This is useful for applications that have not specified the Central background mode and cannot display their own alert. If more than one application has requested notification for a given peripheral, the one that was most recently in the foreground will receive the alert.
CBConnectPeripheralOptionNotifyOnNotificationKey. This is a NSNumber (Boolean) indicating that the system should display an alert for all notifications received from a given peripheral, if the application is suspended at the time.
This is useful for applications that have not specified the Central background mode and cannot display their own alert. If more than one application has requested notification for a given peripheral, the one that was most recently in the foreground will receive the alert.
Depending on the result of the connection, the delegate can receive either centralManager:didFailToConnectPeripheral:error: or centralManager:didConnectPeripheral:. In case of success, you can ask the Peripheral which services is advertising. So, in the didConnectPeripheral callback you can do the following:

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    // Clears the data that we may already have
    [self.data setLength:0];
    // Sets the peripheral delegate
    [self.peripheral setDelegate:self];
    // Asks the peripheral to discover the service
    [self.peripheral discoverServices:@[ [CBUUID UUIDWithString:kServiceUUID] ]];
}


At this point, the Peripheral starts to notify its delegate with a bunch of callbacks. Since in the previous method I asked the Peripheral to discover the service, the Peripheral delegate receives -peripheral:didDiscoverServices:. If there is no error, the Peripheral can be asked to discover the characteristics for a given service. You can do it in this way:

- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverServices:(NSError *)error {
    if (error) {
        NSLog(@"Error discovering service: %@", [error localizedDescription]);
        [self cleanup];
        return;
    }

    for (CBService *service in aPeripheral.services) {
        NSLog(@"Service found with UUID: %@", service.UUID);

        // Discovers the characteristics for a given service
        if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
            [self.peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kCharacteristicUUID]] forService:service];
        }
    }
}   


Now, if a characteristic is discovered, the Peripheral delegate receives -peripheral:didDiscoverCharacteristicsForService:error:. At this point, the Peripheral can be asked to notify its delegate as soon as the characteristic value is updated using -setNotifyValue:forCharacteristic::

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if (error) {
        NSLog(@"Error discovering characteristic: %@", [error localizedDescription]);
        [self cleanup];
        return;
    }
    if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
        for (CBCharacteristic *characteristic in service.characteristics) {
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) {
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
        }
    }
}


Here, if the value of a characteristic is updated, then the Peripheral delegate receives -peripheral:didUpdateNotificationStateForCharacteristic: error:. Here, you can read the new value using -readValueForCharacteristic:

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
        NSLog(@"Error changing notification state: %@", error.localizedDescription);
    }

    // Exits if it's not the transfer characteristic
    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) {
        return;
    }

    // Notification has started
    if (characteristic.isNotifying) {
        NSLog(@"Notification began on %@", characteristic);
        [peripheral readValueForCharacteristic:characteristic];
    } else { // Notification has stopped
        // so disconnect from the peripheral
        NSLog(@"Notification stopped on %@.  Disconnecting", characteristic);
        [self.manager cancelPeripheralConnection:self.peripheral];
    }
}


When the Peripheral sends the new value, the Peripheral delegate receives -peripheral:didUpdateValueForCharacteristic:error:. The second argument of this method contains the characteristic. You can then read its value using the -value property. This is a NSData containing the value of the characteristic.

At this point, you can either disconnect or wait for other data.

Conclusions

I showed you a basic example on how to use the Core Bluetooth framework. I hope that this small tutorial, the WWDC videos and the documentation (the available one) can help you create new iOS applications using the Bluetooth LE. Check also the examples coming with the documentation. There, you will find all the delegate methods I used in this tutorial.

Keep coding,

Geppy
Pop-upView Separately

Core Bluetooth for iOS 6

Core Bluetooth was introduced for the first time in iOS 5 to allow iOS devices to consume data provided by devices used in healthcare, sport/fitness, security, automation, entertainment, proximity and so on. In iOS 6.0, this API was extended to allow also iOS devices to serve data.

The Core Bluetooth API is based on the Bluetooth 4.0 Low Energy (LE) specifications. This framework takes care of all the details of the Bluetooth LE standard. However, it is designed to provide developers with the necessary level of control.

Read More

    • #Cocoa
    • #Core Bluetooth
    • #Mac
    • #apple
    • #apple tv
    • #cocoa touch
    • #iOS
    • #iOS training
    • #invasivecode
    • #ipad
    • #iphone
    • #training class
    • #bluetooth
    • #low energy
    • #smart device
    • #bluetooth le
    • #smart ready
    • #bluetooth 4.0
  • 5 months ago
  • 15
  • Permalink
  • Share
    Tweet
An introduction to Collection Views (UICollectionView)

One of the new UIKit components of iOS 6 is Collection Views. This is a new tool you can use to manage different views on the screen in a grid or other shape format. When the number of views exceed the space on the screen, collection views, being a subclass of UIScrollView, display the cell in a scrollview.

A typical example of a collection view is represented by the Photo app, where the pictures are presented in a grid. The user can scroll up and down the pictures and then, for example, select one of them.

Very similar to table views, collection views brings together a set of cells. Each cell is represented by the UICollectionViewCell class. However, differently than the table view cells, the collection view cells come with no predefined style. They are simply an empty view. It’s responsibility of the developer to design the cells depending on the scope of the app.

Now, the content of each cell is provided by a datasource object as it happens for a table view and the methods you have to implement in your datasource class are very similar to the methods you implement in the datasource of a table view. So, let’s give a look at these methods:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView // 1

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section // 2

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath // 3

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath // 4


As you can see, the names of these methods are very similar to the datasource methods of the tableview. The last method needs some more explanation, but let’s check first each of them.

The first method returns the number of sections in the collection view. Similar to the tableviews, collection views are organized in sections. Each section contains a given number of cells. You pass this number using the second method of the above list: the number of cells for each section.

You can also associate special views to each section. These views are the Supplementary View. Tableviews have a header and a footer for each section. Instead, collection views just have supplementary views that you can use as header or footer or both, or you can use for other purpose.

The third of the above listed methods is what provides the collection view cell to the collection view for each index path. This is the place where you pass the actual content to the collection view to display.

Finally, the fourth method returns the supplementary view for each index path. The kind of supplementary view is defined by the layout object that supports the supplementary view.

Let’s build an example with a collection view and its datasource. We are going to create the cell and see how to dequeue them from the memory.

Launch Xcode and create a new single view iPad project. Name it Collector. Use ARC and Storyboard. Go to the Storyboard and drag a collection view object from the Library and drop it to the view controller view. You could use a UICollectionViewController instead of creating your own view controller with a collection view on it, but I prefer this way so you can understand better the implementation details.

We could use Nib files instead of Storyboard. The implementation of the collection view (as other UIKit elements) will be slightly different. If you have any questions about Nib, just contact us.



Figure 1. Collection view geometry.

Now, select the collection view just dropped on the view controller and go to the Size Inspector. As you can see (Fig. 1), you get a lot of controls on the size of each element. You can change the cell size, the header size, the footer size and so on. Let’s change here the cell size to 150x150. You can change these values dynamically using the UICollectionViewDelegateFlowLayout. This is a protocol that you have to use in combination with the UICollectionViewFlowLayout class.

Let’s clarify this point. Collection Views use three helpers to work: the data source (UICollectionViewDataSource), the delegate (UICollectionViewDelegate) and the layout (UICollectionViewLayout). The data source as we saw previously is used to provide the collection view with the content. The delegate is instead used to interact with the collection view (select a cell, add o remove a cell and so on). The layout is used to provide the collection view with the geometry information (cell size, spacing between cells and so). The UICollectionViewLayout is an abstract class (that means you cannot use it directly, but you have so subclass it). You need to create a subclass and describe there your custom layout. Now, Apple provides us with the grid layout and it calls it, the Flow Layout. So, there is a couple of extra classes you can use to manage this grid layout: UICollectionViewFlowLayout and the UICollectionViewDelegateFlowLayout. In this post, we can see how to use the grid layout. To learn how to create your own custom layout… well, the Apple documentation explains how or you can come to one of our training classes (check here next available classes).

Let’s go back to the exercise. We need to create a cell. Since we are using Storyboard, this is quite easy. You can edit the cell directly on the collection view object we just added to the view controller. Indeed, if you select the cell object as in the following Figure 2, you can edit it and add views to it.



Figure 2. Editing a cell in Storyboard.

Let’s, for example, add a label to the cell and center it as shown in Figure 3. I also change the background of the cell to yellow, so you can see it.



Figure 3. Refining a cell in Storyboard.

Now, we need to hook the cell to the source code. Let’s then add a new class (subclass of UICollectionViewCell) to our project. Let’s call it MyCell. Add to this class a property to connect to the label:

@property (nonatomic, weak) IBOutlet UILabel *cellLabel;


Go back to Storyboard and change the type of the cell to MyCell and connect the outlet to the label object as shown in Figure 4.



Figure 4. Connect the outlet to the cell label

The last very important step is to add a reusable identifier to the collection view cell object as shown in Figure 5.



Figure 5. Reusable identifier

Ok, now we need only to add the intelligence to all this. Go back to the ViewController.h and add an outlet and connect it to the collection view:

@property (nonatomic, weak) IBOutlet UICollectionView *cView;


Now, we need to make this view controller be conform to the datasource protocol. Go back to the Storyboard and right-click the collection view. Connect the dataSource outlet to the view controller. Then, open the ViewController.h and add UICollectionViewDataSource to the class interface:

@interface ViewController : UIViewController 


We can now implement our datasource methods. As explained previously, we need to pass the number of sections to the collection view. For this example, we will use just 2 sections. So, add the following piece of code to the view controller:

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 2;
}


Next, we need to tell the collection view how many items per section. For the moment, let’s add 100 items for each section:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 100;
}


Finally, we need to display the content on each cell. Here, for simplicity, we just display the index of the item in that label we add in the Storyboard:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"com.invasivecode.cell" forIndexPath:indexPath];
    NSString *str = [NSString stringWithFormat:@"%d", indexPath.row+1];
    cell.cellLabel.text = str;
    return cell;
}


Make sure that the identifier is the one you used in the Storyboard. Now, just a quick note. If you are not using the Storyboard, you need to register the collection view to either the cell class or the Nib file using one of the following methods:

– registerClass:forCellWithReuseIdentifier:
– registerNib:forCellWithReuseIdentifier:


If you just run Xcode, it should compile ed execute the app.

Conclusion

We have seen the basic concepts to build the collection view functionality. There is much more. You can create really custom shapes of collection views and change their shape dynamically using, for example, the touch gestures or the accelerometer. You can really have a lot of fun and invent new way to present the content to your user. Check the Apple documentation or check here our training classes to learn more advanced iOS topics.

Keep coding,
Geppy
Pop-upView Separately

An introduction to Collection Views (UICollectionView)

One of the new UIKit components of iOS 6 is Collection Views. This is a new tool you can use to manage different views on the screen in a grid or other shape format. When the number of views exceed the space on the screen, collection views, being a subclass of UIScrollView, display the cell in a scrollview.

Read More

    • #UICollectionView
    • #Collection View
    • #UICollectionViewFlowLayout
    • #UICollectionViewDataSource
    • #UICollectionViewDelegaye
    • #iOS
    • #iPhone
    • #iPad
    • #Training
    • #Class
    • #iNVASIVECODE
    • #UICollectionViewLayout
  • 7 months ago
  • 8
  • Permalink
  • Share
    Tweet
Attributed strings for iOS using Interface Builder

Most of the things that I highlighted during the last post can be built easily with Interface Builder. I tried to replicate the example I showed in that post and I was able to do 90% of it without writing a single line of code…how great is that! Let me show you how.

Erase the viewDidLoad method. Go to viewController.xib, drag a UILabel on the view, open the attributes Inspector and choose Attributed under Text. You will be able to edit your text from there. Now, change the font, size, color, highlight, add a shadow… You only have to choose the portion of text that you want to change and do it right there. You can see it on the following figure. I added 3 UILabels and I changed its properties trying to match the example from the previous post…and it worked quite well, right?



Thrilled to share those tricks with you!

Enjoy!

Eva
Pop-upView Separately

Attributed strings for iOS using Interface Builder

Most of the things that I highlighted during the last post can be built easily with Interface Builder. I tried to replicate the example I showed in that post and I was able to do 90% of it without writing a single line of code…how great is that! Let me show you how.

Read More

    • #attributed string
    • #nsattributedstring
    • #ios
    • #iphone
    • #ipad
    • #training
    • #class
    • #learning
    • #uikit
    • #tutorial
  • 7 months ago
  • 2
  • Permalink
  • Share
    Tweet
Introduction to NSAttributedString for iOS 6

I’ve been talking a lot in the past about how to customize text in your app to improve the UI of your applications. You need to show some text in a particular way or with some characteristics that are not standard and until now, you just were not able to accomplish that with simple methods and everyday-frameworks.

Before iOS 6, developers had to turn out to Core Text, which although a great framework is not easy to use. You can check the Core Text tutorial here and how much code you needed to implement to do things that I consider were fairly basic. Finally, Apple gave us what we were looking for and gratefully improved NSAttributedString in iOS 6. And I personally think that the most important thing that Apple has done is that it has put together some documentation, which still lacks for Core Text. Core Text still remains as a useful API to do some particular things like writing inside non-rectangular shapes, for example, but let’s see the new features of NSAttributedString.

Although NSAttributedString was with us since iOS 5, it was limited to few attributes. Now, not only new string attributes were added, but NSAttributedString is more pervasive in iOS and you can feed: UILabel, UIButton, UIPickerView, and UITableViewCell.

UILabel

For the UILabel, you can use the following property

@property (nonatomic,copy) NSAttributedString *attributedText


UIButton

For the class UIButton, you can instead use the following method:

- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state


UIPickerView and UITableViewCell

You can fill the last two classes (UIPickerView and UITableViewCell) through their property:

@property(nonatomic, readonly, strong) UILabel *textLabel


assigning an attributed string to this label.

Let’s go

Let’s write some code to see how easy it is to implement what we’ve been talking about so far.

Launch Xcode and create a new Single-View Application iPad project. Name it AttributedString. Open the ViewController.m and edit the -viewDidLoad method as follows:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSAttributedString *title;
    title = [[NSAttributedString alloc] initWithString:@"Visual Guide for NSAttributedString" attributes:@{ NSFontAttributeName : [UIFont fontWithName:@"Noteworthy-Bold" size:36], NSUnderlineStyleAttributeName : @1 , NSStrokeColorAttributeName : [UIColor blackColor]}]; //1
    UILabel *label;
    label = [[UILabel alloc] initWithFrame:CGRectMake( (self.view.bounds.size.width - title.size.width) / 2.0f, 40.0f, title.size.width, title.size.height)]; //2
    label.attributedText = title; //3
    [self.view addSubview:label]; //4
}


Line 1 creates an attributed string with a set of attributes. In this particular case, we set the font, the font size, the stroke color and underline attribute. Check the documentation (“) if you want to apply additional customizations, but for a quick reference I’m going to list them here (I think the name of the attribute is self explanatory):

NSString *const NSFontAttributeName;
NSString *const NSParagraphStyleAttributeName;
NSString *const NSForegroundColorAttributeName;
NSString *const NSBackgroundColorAttributeName; 
NSString *const NSLigatureAttributeName;
NSString *const NSBaselineOffsetAttributeName;
NSString *const NSStrikethroughStyleAttributeName;
NSString *const NSStrokeColorAttributeName; 
NSString *const NSStrokeWidthAttributeName;
NSString *const NSShadowAttributeName;


Line 2 creates a label and Line 3 applies the attributed string to the label. Finally (Line 4), we add our label as a subview to our view. Now, just build and run and you should see the following result:



Note that you can also add or remove attributes to a particular range of characters using NSMutableAttributedString. See the class description for NSMutableAttributedString for more information about the available methods.

Drawing made easier

There are also a couple of new categories that have been introduced with iOS 6. A basic category:

#import 
@interface NSAttributesString (NSStringDrawing)
- (CGSize)size;
- (void)drawAtPoint:(CGPoint)point;
- (void)drawInRect:(CGRect)rect;
@end


and a more sophisticated category:

@interface NSAttributesString (NSExtendedStringDrawing)
- (void)drawWithRect:(CGRect)rect 
        options:(NSStringDrawingOptions *)options 
        context:(NSStringDrawingContext *)context;
- (CGRect)boundingRectWithSize:(CGSize)size 
        options:(NSStringDrawingOptions *)options 
        context:(NSStringDrawingContext *)context;
@end


Let’s see how all of this works and let’s continue with our project. Create a new Objective-C class, subclass of UIView, and name it TextRenderingView. Create a NSAttributedString property and name it theString. Then, in the TextRenderingView.m edit the drawRect: method as follows:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    [theString drawInRect:CGRectMake((self.bounds.size.width - theString.size.width) / 2.0f, 40.0f, theString.size.width, theString.size.height)];
}


Here, we call the drawRect: on the super class to let it do all the setups. Then, we just use a method from the NSStringDrawing category:

- (void)drawInRect:(CGRect)rect;


Go back to the ViewController.m and import the TextRenderingView header:

#import "TextRenderingView.h"


Modify the viewDidLoad as follows:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSAttributedString *title;
    title = [[NSAttributedString alloc] initWithString:@"Visual Guide for NSAttributedString" attributes:@{ NSFontAttributeName : [UIFont fontWithName:@"Noteworthy-Bold" size:36], NSUnderlineStyleAttributeName : @1 , NSStrokeColorAttributeName : [UIColor blackColor]}]; //1

    TextRenderingView *textView; 
    textView = [[TextRenderingView alloc] initWithFrame:self.view.frame]; //5
    self.view = textView; //6
    textView.backgroundColor = [UIColor whiteColor]; //7
    textView.theString = title; //8
}


Line 1 creates the attributed string in the same way we did before. Now, we initialize our TextRenderingView (Line 5) and set it as the view of ViewController (Line 6). We set the background color to white (Line 7) and finally, we pass the created attributed string to the rendering view (Line 8). Now, just Run and if you did not make any mistake, you should see the same result as before.

I’m sure that if you followed the last tutorial regarding Core Text or even if you tried by yourself in the past, you will agree with me that it has become really simpler to render text in the way we want it to be. I think Apple has put a lot of effort and we should take advantage to improve our apps. I challenge you to add some creativity to the projects we’ve been working on and experiment with the different possibilities that NSAttributedString is offering us. It should be fairly easy now to build something like this:



The limits of NSAttributedString

There are a couple of things that I’m aware of that are not possible to do with those new methods and categories:

if you want to draw into a shape different from a rectangle, you will still have to use Core Text.
if you want to render your text on a non-horizontal line, you will probably have to pick either Core Text or CALayer.
See the next figure as an example of what can not be done with NSAttributedString:



Other than that, again, I think there is a lot of potential and I’m happy to share with you all those improvements regarding text rendering. I hope you found this post useful!

Enjoy!

Eva

Eva Diaz-Santana is co-founder of iNVASIVECODE. She is senior iOS developer and works mainly on location-based services, text and graphics processing, and core data.
Pop-upView Separately

Introduction to NSAttributedString for iOS 6

I’ve been talking a lot in the past about how to customize text in your app to improve the UI of your applications. You need to show some text in a particular way or with some characteristics that are not standard and until now, you just were not able to accomplish that with simple methods and everyday-frameworks.

Read More

    • #attributed string
    • #nsattributedstring
    • #ios 6
    • #uikit
    • #ios
    • #iphone
    • #ipad
    • #os x
    • #mountain lion
    • #Core Text
  • 9 months ago
  • 4
  • Permalink
  • Share
    Tweet
iNVASIVECODE goes Middle East

We are happy to announce that we are starting a new exciting business in Abu Dhabi (United Arab Emirates). We joined our new local partner, Immersive. 

This collaboration brings to the Middle East our world-class 5-days iOS training and provides local businesses with tailored, robust and scalable applications and solutions. Our office is located in the TwoFour54 collaborative campus, where Apple, BBC, Financial Times and other companies are located.

About Abu Dhabi

Abu Dhabi (Arabic: أبو ظبي‎ Abu Dhabi, Father of Deer) is the capital and the second largest city of the United Arab Emirates in terms of population and the largest of the seven member emirates of the United Arab Emirates. 
Abu Dhabi houses important offices of the federal government, and is the seat for the United Arab Emirates Government and the home for the Abu Dhabi Emiri Family and the President of the UAE from this family. Abu Dhabi has grown to be a cosmopolitan metropolis. Its rapid development and urbanization, coupled with the relatively high average income of its population, has transformed Abu Dhabi to a larger and advanced metropolis.

About TwoFour54

Named after the geographical co-ordinates of Abu Dhabi, twofour54’s vision is to enable the development of world class Arabic media and entertainment content, by Arabs for Arabs, and to position Abu Dhabi as a regional centre of excellence in content creation across all media platforms including film, broadcast, music, digital media, events, gaming and publishing.
TwoFour54 wants to create a collaborative and supportive campus community; stimulating creative and professional partnerships through our three key business pillars: tadreeb -the training academy; ibtikar - innovation & support; and intaj - state of the art production facilities. TwoFour54’s three pillars are supported by a business enabler tawasol, which provides support to organizations and individuals looking to join the twofour54 community.

About Immersive

Immersive is a company based in Abu Dhabi that offers world-class applications and solutions for the mobile world. Our main focus is Apple’s iOS based platform in which we leverage the knowledge and expertise of our partners to provide the best solutions for the local and regional markets. To compliment this, we also offer iOS support and highly acclaimed training.

About iNVASIVECODE

Since 2008, iNVASIVECODE provides tailored and robust solutions for iOS and OS X. Based in San Francisco, iNVASIVECODE provides also world-class 5-days iOS training classes for experienced software developers and enterprises that want to port their products to the Apple-based technologies.
Pop-upView Separately

iNVASIVECODE goes Middle East

We are happy to announce that we are starting a new exciting business in Abu Dhabi (United Arab Emirates). We joined our new local partner, Immersive.

Read More

    • #abu dahbi
    • #united arab emeirates
    • #uae
    • #ios training
    • #invasivecode
    • #immersive
    • #twofour54
    • #ios class
    • #ios 6
    • #iphone
    • #ipad
    • #apple
  • 9 months ago
  • 2
  • Permalink
  • Share
    Tweet
← Newer • Older →
Page 1 of 5
iNVASIVECODE is a design and development enterprise with the passion for engineering beautiful iOS and OS X apps.

iNVASIVECODE offers 5-days iOS training classes for professional developers and on-site technical consulting.

Pages

  • HOME
  • iOS TRAINING CLASSES
  • TUTORIAL ON CORE TEXT
  • QUARTZ CRASH COURSE
  • CONTACT US

More about us

  • @invasivecode on Twitter
  • Google
  • Linkedin Profile

loading tweets…

I Dig These Posts

See more →
  • RSS
  • Random
  • Archive
  • Ask us anything about iOS
  • Mobile

Copyright ©2008-2013 iNVASIVECODE, Inc. Effector Theme by Carlo Franco.

Powered by Tumblr