iOS Development | Andy Ibanez https://www.andyibanez.com Teaching you cool stuff since 2012. Mon, 19 Aug 2019 22:08:54 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.10 39653125 HTTP/2 Apple Push Notification Service Introduction. https://www.andyibanez.com/http2-apple-push-notification-service-introduction/ https://www.andyibanez.com/http2-apple-push-notification-service-introduction/#respond Tue, 02 May 2017 18:00:33 +0000 https://www.andyibanez.com/?p=562 A few years ago, Apple announced new APIs to interact with their push notification services. In late 2015, these APIs were finally made available for developers to use. In this post we will talk about the very basics of using Apple’s new Push Notification services, with basic bash cURL code. 1. Advantages Let’s talk about […]

The post HTTP/2 Apple Push Notification Service Introduction. appeared first on Andy Ibanez.

]]>
A few years ago, Apple announced new APIs to interact with their push notification services. In late 2015, these APIs were finally made available for developers to use.

In this post we will talk about the very basics of using Apple’s new Push Notification services, with basic bash cURL code.

1. Advantages

Let’s talk about why Apple decided to make new APIs for push notifications in the first place.

Those who have worked with the first iteration of the system – the one that has existed since the iOS 3.0 days – know how daunting it was to get this to work. You had to provision two different push notification certificates, one for development, and one for production, and you had to keep track of them. Not only that, but the API was entirely socket based, and it was very unreliable. You had to take into account what could happen if you sent a lot of push notifications at once – if you sent more than one notification per second, the notification would often get lost, and many of your users would never get the notification. So developers had to create timers and let the socket “rest” for a little while before sending another notification. For small sets of notifications, this was no issue, but imagine having to send 30,000 push notifications at once – waiting one second per notification would make it take 8 hours to send all the notifications to all the devices!

The new APIs are now HTTP/2 based, and it’s expected that the socket-based implementation will get deprecated soon and eventually removed, so you should start using the new APIs now.

One of the advantages to the new system is that you only need to create one certificate that can be used for production and development deployments of your app. Yes, that’s right, you no longer need to keep track of two sets of public key-pairs to achieve this anymore.

You can simply generate a Production push notification certificate and it will work for both cases. In my tests, creating a Development push notification certificate did not seem to work (I got an error message in the lines of curl: (16) Error in the HTTP2 framing layer).

And yes, if you are using Fastlane as part of your development flow, you can simply use the pem command to generate a production certificate. You never have to specify you want a development certificate because you will never need it anymore. Woot!

Type pem, fill in your Apple ID and app bundle identifier, and you are ready to go. You can use that set of certificates for both development and production push notifications.

And to make things even better, you don’t actually need a push notification certificate for this anymore. It now supports JWT-based authentication tokens. I will try to explore this possibility in a future post. This post will focus on using certificates for your notifications still, but keep that in mind when you decide to implement your own push notifications system.

Another advantage is that the new system is based on HTTP/2. Most developers know how to work with the HTTP protocol instead of using pure raw sockets. This makes it very easy to write a push notification implementation and to test them easily (you can use cURL in your terminal for this).

Finally, one of the biggest advantages is that you no longer need to implement the feedback calls to get a list of devices that no longer exist. The new system gives you back standard HTTP codes. If you are sending a push notification to a device that is no longer valid, the service will return a 410 error, indicating that you can deal with that token in your database accordingly.

All the HTTP status codes return something meaningful to you. Other than 410, you can also receive 413 when your payload is too large, or 403 when there is something wrong with your certificate or authorization token. Thanks to this, debugging your own APNS systems is much easier to do, and this was not very easy to do with the old one.

A full list of status codes can be found Apple’s Developers Website, scrolling down to Table 8-4.

3. A Test Environment for Push Notifications

In order to take advantage of these new APIs in your development environment, you need to install cURL v7.38 or newer, and you need to specify the -with-nghttp2 flag in order to support HTTP/2.

You can do this easily on your Mac by installing Homebrew and typing:

brew install curl --with-nghttp2
brew link curl --force

While macOS does come with cURL installed, it comes with an old version that does not support HTTP/2.

Then you need your push notification certificate. Using Fastlane, you can just write

pem

And follow the next prompts to generate your push notification certificate. The next two prompts will only ask you for your Apple ID and bundle identifier.

That’s it! With this we can send push notifications to your device.

Remember to ensure your deployment server also has a supported version of cURL in order to avoid issues. At the time of this writing, HTTP/2 is not widely used yet, so you may need to compile cURL with the -with-nghttp2 flag yourself.

#4. Playing Around with new Push Notificaitons

Once you have a push notification token received from your app, you can test this on your terminal.

We will use the token 34828574985 here (very pseudo, yeah) and the bundle identifier com.andyibanez.APNSFoobers for this example:

curl -d '{"aps":{"alert":"YOUR ALERT","sound":"default"}}' --cert "PATH_TO_YOUR_PUSH_CERTIFICATE.pem":"" -H "apns-topic: com.andyibanez.APNSFoobers" --http2 https://api.development.push.apple.com/3/device/34828574985

The push notification payload is the same one. It needs the "aps" key. Everything else you need to specify is your bundle ID, device token, and push notification certificate (PEM file).

The above example will send a development push notification. For production, simply change api.development.push.apple.com to api.push.apple.com and that’s it. You can use the same PEM file, and the only thing that could change is the token ID.

You can easily adapt this code to any language. I will try to write the PHP cURL based version of this in the future.

The post HTTP/2 Apple Push Notification Service Introduction. appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/http2-apple-push-notification-service-introduction/feed/ 0 562
Writing “Lite” And “Pro” Versions Of Your App (In Swift) https://www.andyibanez.com/writing-a-lite-and-pro-versions-of-your-app-in-swift/ https://www.andyibanez.com/writing-a-lite-and-pro-versions-of-your-app-in-swift/#comments Wed, 10 Feb 2016 04:17:32 +0000 https://www.andyibanez.com/?p=440 Learn to use Targets to build a "Lite" and a "Pro" version of your app.

The post Writing “Lite” And “Pro” Versions Of Your App (In Swift) appeared first on Andy Ibanez.

]]>
I recently decided to monetise the upcoming version of Mignori as a free “Lite” app and a paid “Pro” app. This was a prevalent business model before IAPs were a thing, and it almost died off completely when they were introduced. Despite all that, some apps still monetise this way, and I think it’s worth talking about how to do it properly.

Before we get started, I hate writing iOS SDK tutorials and specifying I’m going to be using an specific language. SDK tutorials should be written to be language-agnostic (while the code snippets can be in an specific language), because anyone who knows Objective-C can pick up Swift and vice versa. Despite all that, I’m explicitly stating that we will be using Swift here because to achieve this, you need to know about macros, and many people think Swift doesn’t support macros the way Objective-C does, so many people think that what I’m going to show you in this tutorial is simply not possible. Let me say beforehand that the techniques here apply in both languages, but the things you have to tinker with will be slightly different depending on what language you are writing your app in.

The techniques described here will be useful for many other things. Some apps release different “versions” of their apps that are not necessarily “Lite” and “Pro” only (MoneyWiz comes to mind). This post will walk you through doing exactly that.

So let’s get started!

What Not To Do

If you have been writing for iOS for a long time, chances are you have attempted to create both versions of your app, and you did it wrong. Let me tell how you shouldn’t approach the idea of writing a “Lite” and “Pro” versions of your app.

Mulitple Projects

So you just finished writing the “Pro” version of your app and you decided to build the “Lite” version of it. No easier way than to Right Clicking your project in Finder and hitting “duplicate”, right?

This will cause an unnecessary mess because you will have two projects to maintain. Even if the projects are exactly the same at first, as you “numb down” the second project to make it the “Lite” version, chances are you are going to break things in the existing codebase. Not only that, but when you find a bug in one of your versions, you will have to fix it in both projects. And not only that, but if your Lite version is heavily modified, what guarantees you the same fix will work in both projects?

Subversion Branches

Another chaotic way of doing things is to maintain one project, but to branch out to different versions of your app.

Subversion tools like Git do a great job trying to keep your codebase consistent across different branches, so you may be thinking that keeping a common “core” branch and then two different branches for your app versions is a good idea. It isn’t. It will still be chaotic to maintain.

What To Do Instead

Enter Targets

Targets are the right way to create “Lite” and “Pro” versions of your app. Targets, amongst other things, allow you to compile different projects with the same sources.

From Apple’s Documentation:

A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product. Projects can contain one or more targets, each of which produces one product.

So each Target produces exactly one product. In this case, your “Lite” app will be a target, and the “Pro” one will be another. If you have written App Extensions or Apple Watch apps, you have worked with Targets before.

From here on out I will show specific techniques and configurations I did on Mignori, as well as related techniques that, while I personally did not use, they may be useful to you in your projects.

Getting Started

We are going to assume you just finihed your “Pro” app, and are ready to numb it down to “Lite”. Click your Project’s “Blueprint” and then take a look at your targets (if your target’s don’t show up, click the Screenshot 2016-02-09 22.24.56 button to show them). Depending on how you configured your project (whether you added unit tests or not, UI tests, etc), you may have more than just your main app target.

Project Blue Print Targets

In the unlikely case you don’t know what these configurations are, you basically configure your targets, and the Bundle Identifier must be unique for each app target, otherwise your users won’t be able to have both versions installed at the same time. Doing this mistake was and is still pretty common. Please don’t do it. If you plan on having exportable data from the “Lite” version to the “Pro” version, you are gonna have a hard time if you make that mistake.

Viewing your targets, right-click your app target and click “duplicate”. This will do exactly what you expect it to do.

Initial Target Configurations

We have been through this already, so the first thing you should do is to change the bundle identifier of the new app.

I personally follow the standard reverse DNS format, and then the last “period” contains the app name, along with a version identifier.

com.fairese.ios.NewMignori-ProVersion
com.fairese.ios.NewMignori-LiteVersion

You can also rename the target itself, by slowly double-clicking it. My two targets are named “Mignori” and “MignoriLite” respectively. If your target name contains a space, it won’t compile – I have searched heavens and oceans to find the solution to this, but couldn’t. By default, apps will have the same name of your Target. I do not want the “Lite” app to be called “MignoriLite” in my users’ screens, but I’d rather call it “Mignori Lite”. To fix this, open the “Info” tab of the target you want to rename and search for the “Bundle name” key. You can type your app name with spaces here to add the “Lite”.

The app is called “NewMignori” because it has been rewritten from scratch. That’s besides the point and don’t worry about giving such words to your own apps.

App Icon

With that essential configuration out of the way, the easiest thing to change is the app icon. To change the icon of your targets (you may want to do this to add a “Lite” label, for example), open the graphics assets file (Assets.xcassets), click the “+” icon to the bottom, hover over “App Icon & Launch Images”, and select “New iOS App Icon”. You can rename the assets here as you wish. My “Pro” app’s icon is simply called “AppIcon”, and the “Lite” apps’s icon is called “AppIcon-Lite”.

Go back to your Targets and select your new “Lite” target from the previous step. Find the “App Icons and Launch Images” section. When you click the drop down in “App Icons Source”, you will see all your app icons sources (if you named your icons like mine, you will see “AppIcon” and “AppIcon-Lite”. You know which one to select. Easy!

Screenshot 2016-02-10 00.12.37

Target-Specific Sources

If you select a file – any file (other than the Blueprint) – you can select what target it belongs to. Take a look at the Utilities window and find the “Target Membership” section. This allows you to create target-specific resources and even code files. Creating target-specific code files is probably going to be overkill in most cases. I will show you how to execute code specific to each target in just one file later, but the option to do it is there, if you ever really need to. Some valid uses for this may be, for example, different “License.txt” files, or even different demo data sources.

Screenshot 2016-02-09 23.08.30

The Fun Part – Target-Specific Code, In The Same File

Like I said, creating whole new Code files for targets can be overkill and won’t be necessary 99% of the time. If you were to do that for every source file, you would have the same problem as if you created different projects for both versions of your app. Think about it – You would be creating redundant code that you would have to maintain in at least two different places!

Compiler Custom Flags

If you have written lots of Objective-C and even pure C or C++ code before, you know you can create conditionalyl-compilated code. You do this using #define macros:

#define DEBUG 1

#if DEBUG
// Conditional code to run when the DEBUG flag is set.
#endif

This code would only be run when the macros “DEBUG” exists. As you may know, before the compiler actually compiles anything, it searches for and replaces appearances of #define macros with their current value. Chances are you have seen header guards in good ol’ C or C++ (or even on bridge files from Objetive-C to Swift!).

#ifndef Bridge_h
#define Bridge_h

#import "SWRevealViewController.h"

#endif /* Bridge_h */

This prevents the #import statements from being run more than once, as multiple same includes wouldn’t compile (technically they would, as #import and #include work differently, but when you create a bridging header, the header guard is there). In C and C++, anything that starts with a pound sign (#) is known as a preprocessor directive, and it’s code that gets “replaced” before the compiler tries to do its job.

Why all this discussion on the C and C++ macros? Because as Objective-C is a superset of C, it is expected you can use them with Objective-C too. And you can. What many people don’t know about is that they (sorta) work with Swift, too. At least for our intents and purposes, they work.

I’m telling you all this because there’s a particular limitation on how Swift deals with preprocessor macros vs. Objective-C (or its subset). In Objective-C, you can grab the actual value of the macros to use it later. Consider this example:

#define MY_STRING @"OH EM GEE"

NSLog(MY_STRING)

This would work because the preprocessor will actually replace MY_STRING with @”OH EM GEE”, then the code will be handed to the compiler to do its job.

But in Swift, this is not the case. The most useful thing you can do with macros is to check if a definition has taken place. You can do pretty insane stuff with macros, so it makes sense the people behind Swift chose not to fully support them.

Just cut to the chase already…

Basically, you can do this in Swift (and in Objective-C):

#if PRO_VERSION
// Code to compile if the app is the pro version
// Adapt your UI, do anything that you need for your app's full version.
#endif

#if LITE_VERSION
// Code to compile if the app is the lite version
// Limit functionality, add (annoying) reminders to buy the pro version, etc..
#endif

How do we achieve this? For each target, open the “Build Settings” tab and search for “Swift Compiler – Custom Flags”. You set the “flags” (in the example above, LITE_VERSION and PRO_VERSION are flags) you want to use here, and not only can you set them per target, but also per build configuration (debug or release).

For example, this is what my app’s Lite version looks like:

Screenshot 2016-02-09 23.45.29

And for my Pro version:

Screenshot 2016-02-09 23.46.26

Each flag, like you can see, needs to be preceded by a “-D”. This tells your app that Swift will provide those definitions to it.

Slightly irrelevant to this post, you can also see that I have -DDEBUG and -DRELEASE flags. I tend to do more verbose logging when running in debug mode, and these flags help me do just that.

Finally…

You need to compile and run each project separately, so keep that in mind if you use autoincrementing build numbers (so you don’t wonder why the build numbers of your main and lite apps are so different). You also need to archive them individually for App Store submission. But even with these extra steps, it’s much easier and faster than keeping track of separate projects or subversion branches.

I hope you also realised there’s a lot you can do with the techniques described here. Each target has their own extensive configuration, so you can play around and see what else you can do. You can even change the deployment target of each app, so if you ever need to support older iOS versions but the chances of breaking new code are high, you can just create a new target and work from there. The options are vast, and I hope you learned something new.

Photo Feb 09, 11 48 58 PM

I based the initial draft of this post on http://www.raywenderlich.com/68613/create-paid-lite-version-iphone-app about the same topic. However, not only is that tutorial outdated, but I also personally think it’s overkill to create a whole demo project to talk about this. Tutorials that cover everything, from the “File > New Project” Step to the point of the tutorial, can be helpful for newcomers, but they can be overly verbose for people who are already familiar with the topic in hand (in this case, Xcode and iOS development). That said, I apologise for pointing out the obvious, but a post can sound weird if it doesn’t have certain words or instructions (like “right-click” and “duplicate”).

The post Writing “Lite” And “Pro” Versions Of Your App (In Swift) appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/writing-a-lite-and-pro-versions-of-your-app-in-swift/feed/ 1 440
Embracing the Swift Standard Library. https://www.andyibanez.com/embracing-the-swift-standard-library/ https://www.andyibanez.com/embracing-the-swift-standard-library/#respond Fri, 03 Jul 2015 23:10:35 +0000 https://www.andyibanez.com/?p=378 Swift is a truly powerful language. But a powerful language is nothing if it doesn’t have a powerful standard library. In this post we will get started with the Swift Standard library (which is small compared to the standard library of other languages, but by no means does that mean it isn’t powerful). The Swift […]

The post Embracing the Swift Standard Library. appeared first on Andy Ibanez.

]]>
Swift is a truly powerful language. But a powerful language is nothing if it doesn’t have a powerful standard library. In this post we will get started with the Swift Standard library (which is small compared to the standard library of other languages, but by no means does that mean it isn’t powerful). The Swift Standard library goes hand in hand with Apple’s new programming paradigm – Protocol-Oriented Programming. If you are acquainted with Protocol-Oriented Programming, you know how different it is compared to the so-known OOP. Swift’s Standard Library adopts Protocol-Oriented Programming really well (and that’s to be expected, since they created this paradigm!)

To be more specific, we will explore three protocols from Swift’s Standard Library here – GeneratorType, SequenceType and ArrayLiteralConvertible. We are going to build a Shopping List that behaves like an array – You will be able to create a Shopping List passing it an array of Shopping Items, and you will be able to fast-iterate (using for-in) over this list to get its elements as if it were a normal array. But this shopping list also has its own methods, so we are not just creating a new array with a fancy name.

A Simple Shopping List

If you wanted to create a shopping list of things, you would probably start by creating a class or an struct (in this post, we will use an struct to also embrace the power of value types in Swift). This struct would probably represent a simple shopping item, with a name and a price.

struct ShoppingItem {
    let name: String
    let price: Float
    
    init(name: String, price: Float) {
        self.name = name
        self.price = price
    }
}

And if you wanted to keep a list of these items, you would probably just put them in an array.

let apples = ShoppingItem(name: "Apples", price: 12.76)
let carrots = ShoppingItem(name: "Carrots", price: 15.43)
let bananas = ShoppingItem(name: "Bananas", price: 32.53)

let shoppingList = [apples, carrots, bananas]

Then whenever you need, you would just operate things “on the fly”. Need to calculate the total? Let’s just iterate over the array, and add the values. Same if you want to calculate the average price of the items on your list.

var total: Float = 0
for item in shoppingList {
    total += item.price
}

var avg: Float = total / Float(shoppingList.count)

This works fine. It does it’s job. But it’s not ideal. If you want to calculate the calculate the total or average in different places, you will end up having duplicate code everywhere.

But you already know how to fix that, don’t you?

Let’s Just Encapsulate Everything

If you thought of making a new struct, called ShoppingList or something like that, you are already in the right path. You would create a ShoppingList struct that would encapsulate an array of ShoppingItems. In that way, you could just create computed properties to get the total and average price of everything on the list. You’d end up with something like this.

struct ShoppingList {
    
    private let items: [ShoppingItem]

    var count: Int {
        get {
            return items.count
        }
    }

    var total: Float {
        get {
            var total: Float = 0
            for item in self.items {
                total += item.price
            }
            return total
        }
    }
    
    var average: Float {
        get {
            return self.total / Float(self.count)
        }
    }

    subscript(index: Int) -> ShoppingItem {
        return self.items[index]
    }
    
}

That works pretty well, right? the ShoppingItems are nicely encapsulated inside the ShoppingList. We don’t need to access the underlying array because we have a subscript operator that lets us get the elements of the array directly. We can count the number of elements in said list without querying the underlying array directly. We forgot to add an initialisator though, so let’s go ahead and create an initialisator that takes an array:

struct ShoppingList {
    
    private let items: [ShoppingItem]

    var count: Int {
        get {
            return items.count
        }
    }

    var init(array: [ShoppingItem]) {
        self.items = array
    }

    var total: Float {
        get {
            var total: Float = 0
            for item in self.items {
                total += item.price
            }
            return total
        }
    }
    
    var average: Float {
        get {
            return self.total / Float(self.count)
        }
    }

    subscript(index: Int) -> ShoppingItem {
        return self.items[index]
    }
    
}

You could create a better initialisator by using the elipsis (…) operand, so you could pass in a variable amount of shopping items without putting them in array.

init(items: ShoppingItem...) {

}

But later we are going to do something much neater. Trust me on this one!

Fine and dandy. Let’s create a new ShoppingList now:

let apples = ShoppingItem(name: "Apples", price: 12.76)
let carrots = ShoppingItem(name: "Carrots", price: 15.43)
let bananas = ShoppingItem(name: "Bananas", price: 32.53)

let shoppingList = ShoppingList([apples, carrots, bananas])

Getting the total and average of the items on your list is much better now.

print("\(shoppingList.total)")
print("\(shoppingList.average)")

What’s that? You want to iterate over the items? Err. I mean, you can. But you will have to do it with an old fashioned for loop (not even for-in!). We need to get the number of elements in the underlying array, using our count property, and then use a for loop like we all know.

for var i = 0; i < shoppingList.count; i++ {
    print("\(shoppingList[i].name) cost \(shoppingList[i].price)")
}

And with that, you can do anything you want with each item of the shopping list. Yay!

A Better Way of Doing Things

But of course, this code is slightly awkward, and many of us have written a variation of it at some point. Wouldn’t it be nice if we could treat the ShoppingList as an array, and create it using Array-like Syntax? And wouldn’t it be nice to be able to iterate through it using a for-in loop, instead of having to grab the count and then use an old-fashioned for-loop on it?

The good news is that you can! Thanks to the Swift Standard Library and Swift’s focus on Protocols, we can make our code elegantly blend with the features of the language.

Elegant Array Syntax

First, we will talk about one of the simplest Protocol’s in Swift’s Standard Library – ArrayLiteralConvertible.

This protocol allows your own structs, classes, and even enums to be initialised with array-like syntax.

For example, Foundation’s NSSet object, does this:

let mySet: NSSet = ["foo", "bar", "cheese"]

We can create a set by assigning it an array. In this case, Type Annotation is important, otherwise Swift will think we are creating an Array instead.

We can do with ArrayLiteralConvertible. This protocol has only one requirement:

init(arrayLiteral elements: Self.Element...)

First we make ShoppingList comply with this protocol. Then we implement that only method, which is just one assignment. I will also delete the old init method from before:

struct ShoppingList : ArrayLiteralConvertible {
    //...

    /// MARK: - ArrayLiteralConvertible
    
    init(arrayLiteral: ShoppingItem...) {
        self.items = arrayLiteral
    }

    //...
    
}

Like you can see, it’s really simple – We assign the protocol, we implement the init, and assign the passed array in that init.

With this, you can already create shopping lists neater:

let apples = ShoppingItem(name: "Apples", price: 12.76)
let carrots = ShoppingItem(name: "Carrots", price: 15.43)
let bananas = ShoppingItem(name: "Bananas", price: 32.53)

let shoppingList: ShoppingList = [apples, carrots, bananas]

Just like Apple’s NSSet, the only catch is we need to use type annotation.

Making our Struct Iterable

Finally, we need to make the shopping list enumerable so we can treat it as an array. The work around from above works, but we can definitely make that neater.

Making the struct enumerable is slightly more complicated and involved than adding the natural array initialisation syntax. I will try to explain everything that is going on. You will need to make your struct comply with both SequenceType and GeneratorType

SequenceType

SequenceType’s only job is to make sure you can use your objects in for-in loops. If you check SequenceType’s documentation (linked above), you will see that it has many methods and one typealias. We do not need to comply with all, and in this post, I won’t. You just need to comply with the typealias, and the filter and generate methods:

struct ShoppingList : SequenceType, ArrayLiteralConvertible {
    //...
    
    /// MARK: - SequenceType
    
    typealias Generator = ShoppingList
    
    func filter(includeElement: (ShoppingItem) -> Bool) -> [ShoppingItem] {
        var fItems = [ShoppingItem]()
        for itm in self.items where includeElement(itm) == true {
            fItems += [itm]
        }
        return fItems
    }
    
    func generate() -> Generator {
        return self
    }

    //...
}

According to Swift’s docs, “A generator is a sequence that is consumed when iterated”. To be completely honest with you, I couldn’t make total sense of that definition of generator, but after playing with this for a while, I came with my own definition of generator: A generator gives you the items that are being iterated through. Each time an iteration passes, you are given one item.

The typealias needs to be defined. Like you can see, it is part of the signature of the generate() method, and we are returning self. Why? Well, we can say ShoppingList is a generator because it contains the ShoppingItems, and we want to receive one shopping item each time for-in goes through it.

The filter method is the interesting part. Not all items “match” the filter for-in uses when iterating (I will talk about why later – bear with me for now). So we need to manually check all the items against the filter closure that this method gives us. We are using slight pattern matching here to do just that. At the end of this method, we return an array of elements that match our filter.

GeneratorType

Finally, the last protocol to make our struct enumerable is GeneratorType. Again it has very few requirements, and it’s one of the easiest to implement. You can think of it’s only job to give whoever is requesting it’s data the corresponding element.

    //...
    /// MARK: - GeneratorType
    
    var currentElement = 0
    
    mutating func next() -> ShoppingItem? {
        if currentElement < self.items.count {
            let curItem = currentElement
            currentElement++
            return self.items[curItem]
        }
        return nil
    }

    //...

next() is declared as mutating, because it alters the internal state of our struct. We need to manually keep track of all the iterated items so we can give the right ones at all times.

And that’s it! Making your objects comply with those protocols make it possible to have a nice object that can be initialised an array, has it’s own methods, and can be iterated through with the natural for-in syntax.

Wrapping Up

Before I finish this post, let me tell you what the filter of SequenceType is for – Pattern Matching. for-in, in Swift 2, supports Pattern Matching. When you are using for-in with pattern matching in Swift, the filter block has all the logic to make sure you don’t include incorrect elements.

For example, we can use pattern matching to iterate only through the items whose cost is under 13:

for item in shoppingList where item.price < 13 {
    print("\(item.name) cost \(item.price)")
}

This prints: “Apples cost 12.76” and nothing else, and this behaviour was given for free by just correctly implementing the filter method of SequenceType.

You can download the code for this post from here and copy-paste it in a new Playground.

And with that, I encourage to take a look at Swift’s Standard Library in more depth. There’s many interesting protocols you can adopt to make your code neater and more Swift-like. Currently, there is not much documentation about them besides Apple’s official documentation, so if you find an interesting one, I encourage you to write about it.

The post Embracing the Swift Standard Library. appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/embracing-the-swift-standard-library/feed/ 0 378
Using The iOS Keychain. https://www.andyibanez.com/using-ios-keychain/ https://www.andyibanez.com/using-ios-keychain/#comments Wed, 11 Jun 2014 23:00:56 +0000 http://andyibanez.com/?p=295 Learn how to enable your app to use the iOS Keychain. The iOS Keychain is essential to keep sensitive data secure.

The post Using The iOS Keychain. appeared first on Andy Ibanez.

]]>
Keychain

If you’re a developer, you know you will, you know you will have to store sensitive data in your app sooner or later. Storing sensitive data in NSUserDefaults is a big no-no, so you just can’t store sensitive data there. Instead, just like OS X, iOS provides a keychain your app can use to store all sorts of sensitive data. The keychain is they key place to store all those user passwords or bank information your app may need to store in the app. If you are just starting with iOS development, or just mid-level, the idea of having to store sensitive data is scary. The good news is, iOS has a very easy API to use with the keychain. Interacting with the keychain on iOS is very simple as the API is composed of just four essential functions.

The Keychain Essentials.

The iOS Keychain Is Much Different Than The OS X Keychain

The OS X keychain is much, much more complex than the iOS keychain. This tutorial is specifically for the iOS keychain.

First, in OS X, any app can request access to any info currently stored in the keychain. If you’re an OS X user, you may recall those prompts notifying you that a given app would like to access data in your keychain. They look like this:

mac-os-x-105-leopard-keychain-access-password-dialogue-box

 

Once you put in your password, the keychain will open and grab the data it needs, and hand it over to the app requesting access to it.

Second, the OS X Keychain has one more feature you cannot find in iOS, and this is one of the reasons the iOS Keychain is so simple: In OS X, the user can create more than one keychain for different things. One for certificates, one for passwords, one for anything else that may be sensitive (not many people do this, but this keychain feature is there for those who need it).

In iOS, each app has their own keychain and this keychain cannot be accessed by any other apps, unless  both apps that want to access this keychain are made and maintained by you, have the Keychain Sharing entitlement enabled, and they are both in the same Keychain Access Group(s). This is a completely different paradigm than the OS X Keychain, because now other apps cannot tamper with your private keychain. Also, each app in iOS has one keychain only, where you can add one or more keychain items.

Also, unlike OS X, the user may not even be aware the keychain exists in iOS. When you’re dealing with the iOS Keychain, the user never gets any prompts and nothing gets in the way of your user for interacting with your app. The keychain is completely hidden for the end user, and you are responsible to make the user interaction details as abstract as possible.

iOS Keychain Concepts And Structure

The keychain is the storage, secure and encrypted your app can use to store sensitive data. It is important that your app and all subsequent versions of it are all signed by the same mobile provision profile. If they aren’t, you will have many troubles later on.

A Keychain Item is the unit of sensitive data stored in your app. If you visualize a keychain, like the one your grandma has for all her keys, a keychain item is an ‘key’. Keychain items have the sensitive data you want to store, and are accompanied by one or more attributes. The attributes describe the keychain item, and what attributes you can use depend on the item class of the keychain item. The item class is “what kind” of data you are going to store. This can be a user/password combination, a certificate, a generic password, and things like that.

Keychain Search Dictionaries.

Search dictionaries specify the attributes for the keychain item you want to update or create.

All dictionary items have a very similar structure. First, they contain the key-value class pair, to specify “what” you’re going to store (again, this can be a user/password combination, a generic password, a certificate, etc).

Second, they contain one or more key-value pairs that set the attributes for the item. This can be a label to give the item a name, the creation time, and anything other that may describe the item.

Third, they specify search attributes and return attributes, to tell your app how it should retrieve this item from the keychain.

Search dictionaries are also known as queries.

Getting Our Hands Dirty

Once you have absorbed all that theory, let’s build a small app that is going to store a few user/password pairs in the keychain and retrieve them.

1. Create a new XCode project for iPhone only, and make it a single-view application. Make sure you are using Storyboards and ARC.
2. The Keychain Services API is part of Security.framework. Go ahead and add it to your project (yourAppBlueprint > Build Phases > Link Binary with Libraries).
3. Add text fields and buttons like this:

Screenshot 2014-06-10 19.39.53

(The “Password” field would normally be set to hide the characters you type with circles. I am not using this field as a password field so you can see what you type on it – Naturally don’t do this in a real world app).

This app will be very simple. It will allow users to save and modify their user/password combination. The bottom part (everything after the “Fetch Data” label) will be used to get the password, and to delete the keychain item.

Create outlets for all the text fields, actions for all the buttons, and an extra outlet for the “Password” label at the bottom. Your header should look like this (nwUsernameTxtFld refers to the top most username text field):

#import <UIKit/UIKit.h>

@interface TKViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *nwUsernameTxtFld;
@property (weak, nonatomic) IBOutlet UITextField *passwordTxtFld;
@property (weak, nonatomic) IBOutlet UITextField *usernameTxtFld;

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

- (IBAction)saveButtonPressed:(id)sender;
- (IBAction)updateButtonPressed:(id)sender;
- (IBAction)getPasswordPressed:(id)sender;
- (IBAction)deleteItemPressed:(id)sender;


@end

4. Now go to the view controller implementation file (.m) and import Security.framework.

#import <Security.framework>

5. Add the following code to your saveButtonPressed method. I will explain everything below:

- (IBAction)saveButtonPressed:(id)sender
{
    //Let's create an empty mutable dictionary:
    NSMutableDictionary *keychainItem = [NSMutableDictionary dictionary];
    
    NSString *username = self.nwUsernameTxtFld.text;
    NSString *password = self.passwordTxtFld.text;
    NSString *website = @"http://www.myawesomeservice.com";
    
    //Populate it with the data and the attributes we want to use.
    
    keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassInternetPassword; // We specify what kind of keychain item this is.
    keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleWhenUnlocked; // This item can only be accessed when the user unlocks the device.
    keychainItem[(__bridge id)kSecAttrServer] = website;
    keychainItem[(__bridge id)kSecAttrAccount] = username;
    
    //Check if this keychain item already exists.
    
    if(SecItemCopyMatching((__bridge CFDictionaryRef)keychainItem, NULL) == noErr)
    {
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"The Item Already Exists", nil)
                                                        message:NSLocalizedString(@"Please update it instead.", )
                                                       delegate:nil
                                              cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                              otherButtonTitles:nil];
        [alert show];
        
    }else
    {
        keychainItem[(__bridge id)kSecValueData] = [password dataUsingEncoding:NSUTF8StringEncoding]; //Our password
        
        OSStatus sts = SecItemAdd((__bridge CFDictionaryRef)keychainItem, NULL);
        NSLog(@"Error Code: %d", (int)sts);
    }
}

The first thing we need to do is to create a search dictionary. We are creating a mutable dictionary to which we will add all our keychain item related data. Then we grab all our data, such as username and the server the password is for, and put it in variables to make our life easier.

We are creating a keychain item with the item class (kSecClass) kSecClassInternetPassword. We need to do a bridge cast to the keys and all constants in ARC, otherwise the compiler is going to complain. The Keychain Services API works with Core Foundation objects, so throughout this tutorial you will see bridge casts and direct casts of Objective-C objects to their CF counterparts.

When we specify the class we are going to use, we need to check what keys can we give to the search dictionary. To do that, we head over to Apple’s Keychain Item Class Keys and Values reference and we look for the key we are using. We are using kSecClassInternetPassword, so we search for kSecClassInternetPassword and then we find that this dictionary can have the following keys:

kSecAttrAccessible
kSecAttrAccessGroup
kSecAttrCreationDate
kSecAttrModificationDate
kSecAttrDescription
kSecAttrComment
kSecAttrCreator
kSecAttrType
kSecAttrLabel
kSecAttrIsInvisible
kSecAttrIsNegative
kSecAttrAccount
kSecAttrSecurityDomain
kSecAttrServer
kSecAttrProtocol
kSecAttrAuthenticationType
kSecAttrPort
kSecAttrPath

You do not need to add them all. What kind of data these keys expect can also be found on the same page I linked you to.

One important key is kSecAttrAccessible. We are giving it kSecAttrAccessibleWhenUnlocked. This keys specify when should the data be accessible. The key we gave it specifies that the data is only accessible when the user unlocks the device. You can also make the keychain be accessible only on the specific device the user is using, make it always accessible, and a few other options. Check Apple’s Keychain Accessibility Constants to learn what other constants you can use with this key.

The kSecAttrServer and kSecAttrAccount keys can be pretty much anything you want, but it’s better to keep them relevant. They are strings, and it makes sense to make them the website a user login is used for and the username for it.

You may have noticed that we are not using the password yet. Before we store the password, it is better to make sure it doesn’t exist yet. To do that, we use the SecItemCopyMatching() function. This function takes, as the first parameter, a search dictionary, or query, to look for an existing keychain item. We have specified the search criteria, and you can add a few more keys if you want, such as kSecAttrProtocol and kSecAttrAuthenticationType. The second parameter is a pointer that will store the returned data, where the keychain will populate the search results. This parameter can be NULL, meaning that we don’t need to have the result handed back to us. In this case, we only want to know if an item with the specified criteria already exists and we don’t care about returning it.

This function searches our app’s keychain for items that match the criteria. You can optionally give it a Search Key to refine the search more. Note that not all these keys will work for the Internet Password class. The search keys also allow you to specify wether the function should return more than one matching keychain item or all of them. This is useful if you’re building an app for a web service, where the user can have various different usernames and passwords, and you want to fetch them all.

You can also give the dictionary a Return Type Keys, specifying how the return dictionary should be formed. You can make a dictionary return the value stored, all it’s attributes, whether it should be persistent, and so on. You can find the documentation for this in the last few links I posted.

All keychain-related functions (a grand total of 4) have OSStatus as their return type. It’s very important you check for this value. In the example above, we are checking if SecItemCopyMatching()’s return code is noErr. For this tutorial, we are going to assume that noErr means no error at all. But in a real-world scenario, you may want to check for Keychain Services Result Codes to properly debug your program. It is very common to get a errSecParam return code. It usually means the search dictionary you’re providing to your function is malformed. If you get this code, check that your search dictionary only has acceptable keys for its item class.

Now you know that after creating the initial parts of the dictionary, you check whether you have a keychain item with that criteria or not. If a keychain item exists with this criteria, we will show a alert view asking the user to update the data instead. If there isn’t, we will attempt to insert the keychain item into our keychain. First we add the last search dictionary item, whose key is kSecValueData (depending on how you need to store data, the key may change – check the last part of the Keychain Services Programming Guide). This is the actual password, and you need to convert it to NSData (failing to do this step results in the Sec functions to return errSecParam).

Finally, we create an OSStatus and assign the return value of the SecItemAdd() function. This function takes the search dictionary we want to add into the keychain, and additionally (yep, can be NULL), a second nil dictionary that will contain the resulting dictionary of the operation.

After this line is done, we will print into the console the result code of SecItemAdd(). It should print 0. If it doesn’t, compare your status result code with the table I linked to above and debug accordingly (errSecParam is -50 – If you have this code, check your dictionary).

Add a few dictionary items and make sure the console logs 0. If it does, you can now move on to implement the update method.

5.

- (IBAction)updateButtonPressed:(id)sender
{
    //Let's create an empty mutable dictionary:
    NSMutableDictionary *keychainItem = [NSMutableDictionary dictionary];
    
    NSString *username = self.nwUsernameTxtFld.text;
    NSString *password = self.passwordTxtFld.text;
    NSString *website = @"http://www.myawesomeservice.com";
    
    //Populate it with the data and the attributes we want to use.
    
    keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassInternetPassword; // We specify what kind of keychain item this is.
    keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleWhenUnlocked; // This item can only be accessed when the user unlocks the device.
    keychainItem[(__bridge id)kSecAttrServer] = website;
    keychainItem[(__bridge id)kSecAttrAccount] = username;
    
    //Check if this keychain item already exists.
    
    if(SecItemCopyMatching((__bridge CFDictionaryRef)keychainItem, NULL) == noErr)
    {
        //The item was found.
        
        //We can update the keychain item.
        
        NSMutableDictionary *attributesToUpdate = [NSMutableDictionary dictionary];
        attributesToUpdate[(__bridge id)kSecValueData] = [password dataUsingEncoding:NSUTF8StringEncoding];
        
        OSStatus sts = SecItemUpdate((__bridge CFDictionaryRef)keychainItem, (__bridge CFDictionaryRef)attributesToUpdate);
        NSLog(@"Error Code: %d", (int)sts);
    }else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Item Doesn't Exist.", nil)
                                                        message:NSLocalizedString(@"The item you want to update doesn't exist.", nil)
                                                       delegate:nil
                                              cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                                           otherButtonTitles:nil];
        [alert show];
    }
}

You should be able to understand everything up to the if. In the if we check for the existence of the keychain item, giving the user an error if the keychain item they want to update doesn’t exist.

Afterwards we need to create a dictionary with all the attributes we want to update. In this case, we only want to update the password for a given user, so we pass in the value data key to update it.

The SecItemUpdate() function takes two parameters: The search query that brings the records you want to update, and a dictionary with the attributes you want to use to replace the ones already stored. Like all other Sec functions, it returns an status code, which you can check to see if the operation was successful or if it found any problems.

Add some new user/password combinations and edit them. The keychain should update the data correctly. After that you can move on to the fetch data method.

6.

- (IBAction)getPasswordPressed:(id)sender
{
    //Let's create an empty mutable dictionary:
    NSMutableDictionary *keychainItem = [NSMutableDictionary dictionary];
    
    NSString *username = self.usernameTxtFld.text;
    NSString *website = @"http://www.myawesomeservice.com";
    
    //Populate it with the data and the attributes we want to use.
    
    keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassInternetPassword; // We specify what kind of keychain item this is.
    keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleWhenUnlocked; // This item can only be accessed when the user unlocks the device.
    keychainItem[(__bridge id)kSecAttrServer] = website;
    keychainItem[(__bridge id)kSecAttrAccount] = username;
    
    //Check if this keychain item already exists.
    
    keychainItem[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue;
    keychainItem[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue;
    
    CFDictionaryRef result = nil;
    
    OSStatus sts = SecItemCopyMatching((__bridge CFDictionaryRef)keychainItem, (CFTypeRef *)&result);
    
    NSLog(@"Error Code: %d", (int)sts);
    
    if(sts == noErr)
    {
        NSDictionary *resultDict = (__bridge_transfer NSDictionary *)result;
        NSData *pswd = resultDict[(__bridge id)kSecValueData];
        NSString *password = [[NSString alloc] initWithData:pswd encoding:NSUTF8StringEncoding];
        
        self.passwordLbl.text = password;
    }else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"The Item Doesn't Exist", nil)
                                                        message:NSLocalizedString(@"No keychain item found for this user.", )
                                                       delegate:nil
                                              cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                              otherButtonTitles:nil];
        [alert show];
    }
}

Fetching data is arguably the hardest thing to do when it comes to keychain items. One of the few things you will notice is that this search dictionary has two new keys, kSecReturnData and kSecReturnAttributes, and that they accept core foundation booleans. The first key will specify that it wants to return the securely stored data only, whereas the second key tells the API that it wants to fetch all the attributes. This is very important: If you only have kSecReturnData as true but not kSecReturnAttributes, the second parameter of the SecItemCopyMatching() function will only return the encrypted data and store it in a CFDataRef object. Whereas, if you also set kSecReturnAttributes to true, then the second parameter of the function will return a dictionary, that is, a CFDictionaryRef. They are different types and if you accidentally give it the wrong pointer to the second parameter, your app may crash eventually.

If the if evaluates to true, then it’s all nice and dandy. We create a new NSDictionary to which we transfer ownership of our old CFDictionaryRef while casting it as a NSDicitonary, and then we can just use it like a normal Objective-C object. We grab the NSData with the kSecValueData key, and then we convert it into a string, that later we give it the password label.

When you type in a username in the second username textfield, the user’s password should show up in the password label below. Try it and play with it. When you are certain it works, let’s move to the last method.

7.

- (IBAction)deleteItemPressed:(id)sender
{
    //Let's create an empty mutable dictionary:
    NSMutableDictionary *keychainItem = [NSMutableDictionary dictionary];
    
    NSString *username = self.usernameTxtFld.text;
    NSString *website = @"http://www.myawesomeservice.com";
    
    //Populate it with the data and the attributes we want to use.
    
    keychainItem[(__bridge id)kSecClass] = (__bridge id)kSecClassInternetPassword; // We specify what kind of keychain item this is.
    keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleWhenUnlocked; // This item can only be accessed when the user unlocks the device.
    keychainItem[(__bridge id)kSecAttrServer] = website;
    keychainItem[(__bridge id)kSecAttrAccount] = username;
    
    //Check if this keychain item already exists.
    
    if(SecItemCopyMatching((__bridge CFDictionaryRef)keychainItem, NULL) == noErr)
    {
        OSStatus sts = SecItemDelete((__bridge CFDictionaryRef)keychainItem);
        NSLog(@"Error Code: %d", (int)sts);
    }else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"The Item Doesn't Exist.", nil)
                                                        message:NSLocalizedString(@"The item doesn't exist. It may have already been deleted.", nil)
                                                       delegate:nil
                                              cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                              otherButtonTitles:nil];
        [alert show];
    }
}

This is the easiest method to implement. We do what we have been doing all along: Create a search dictionary and then check if we have items with that criteria. If it finds a dictionary, we simply call SecItemDelete(), which only takes one parameter that is the search dictionary, and like all the previous 3 Sec functions you have seen, it returns an OS Status.

Play with the whole app now and see if it behaves like you would expect it to behave.

Wrapping Up

You should know have a firm understanding of how the iOS Keychain works.

Keep in mind that the keychain can be used to store other data, even private keys and certificates. The iOS keychain, while keeping the API simple, is really powerful with all its features. The way search dictionaries work makes a lot of sense with the whole API.

You have seen the 4 functions that come with the Keychain Services API:

  • SecItemCopyMatching
  • SecItemAdd
  • SecItemUpdate
  • SecItemDelete

And you also learned how to use them.

As usual, any comments and feedback are very welcome. You may also download this project’s source code from here.

How to tell what each error code means:

If you get an error code (like -50), and you can’t tell what it means on the internet, you can open up the Terminal in your Mac and type:

security error -50

That will tell you what the error is so you can go about fixing it. In the case of error -50, the Terminal will tell you:

Error: 0xFFFFFFCE -50 One or more parameters passed to a function were not valid

The post Using The iOS Keychain. appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/using-ios-keychain/feed/ 26 295
Multithreading on iOS And Mac OS X Using NSOperations. https://www.andyibanez.com/multithreading-ios-mac-os-x-using-nsoperations/ https://www.andyibanez.com/multithreading-ios-mac-os-x-using-nsoperations/#comments Sat, 13 Oct 2012 02:35:15 +0000 http://andyibanez.com/?p=117 Multithreading in iOS and OS X (This tutorial was written with Apple’s Documentation as a “root” base text, combined with my own knowledge on the topic. I have essentially taken bits and pieces of Apple’s documentation and modified them with what I know. Additionally, I have created full examples, instead of the mere snippets Apple […]

The post Multithreading on iOS And Mac OS X Using NSOperations. appeared first on Andy Ibanez.

]]>
Multithreading in iOS and OS X

(This tutorial was written with Apple’s Documentation as a “root” base text, combined with my own knowledge on the topic. I have essentially taken bits and pieces of Apple’s documentation and modified them with what I know. Additionally, I have created full examples, instead of the mere snippets Apple tends to add to it’s documentation. All in all, this tutorial should be really easy and pleasant to follow, but there’s a slight chance I have made a few mistakes too. If you find something out of place, please let me know.)

Multithreading: Easy Implementation on iOS And OS X.

Since the introduction of multithreading, people have found the whole thing to be intimidating and hard, because well, it IS intimidating and hard. Most of the time, anyway. Multithreading implementations vary a lot, from super low level APIs (such as the POSIX pthread APIs), to very high level APIs that are friendlier and easier to use (like NSOperations, which is what we will be talking about today!). The high level APIs are naturally built on top of the low level ones. Multithreading on iOS and Multithreading on OS X is really easy with high level APIs nowadays.

In this tutorial, I will teach you how to do multithreading on iOS and OS X using a higher level API than GCD. You will learn how to use NSOperations and NSOperationQueues to write multithreading programs as fast and painlessly possible. Nowadays, there’s very little use for programmers to drop at a very low level to deal with threads, (we won’t be touching NSThreads because they are not really needed), so a high level API that is powerful and easier to use, will be welcomed by most. The GCD is a powerful API for multithreading, but it still has it’s complexities, and actually NSOperation is at a higher level than the GCD.

For this tutorial, I foolishly assume that you are a “high intermediate” developer at the very least. If you are just learning about iOS/OS X development, then this tutorial is not for you. Build an app or two with no concurrency first and then come back to this tutorial – Like usual, it won’t be going anywhere.

”Wait wait wait, what’s all this concurrent chit-chat Yoda lingo you are talking about, anyway?”

Concurrency is about executing multiple paths of code at once. This is useful to speed up your application and making it much more responsive to the user. Suppose you want to create a game – It would be outrageous to make it play sound and deal with the gameplay on the same thread. Instead, you deal with your game events in one thread and let it play the soundtrack in another (in case you’re writing your game from scratch without using any frameworks such as Cocos2D).

So, let’s get started!

First, a word on terminology is due

Before we move to the real sausage of this tutorial, you need to have three concepts clear in your mind. These concepts adapt to modern Apple technologies. The terminology of these words are different in very old or basically obsolete Apple technologies. We will use as a reference iOS 4.0+ and latest versions of OS X starting on Intel chips to call them “modern”. This is an estimate of mine, I cannot guarantee the meanings of this words are different or the same on older versions of the aforementioned technologies. If you are supporting anything pre-iOS 4 or pre-Intel based Macs you probably should adapt your code to newer technologies because they are not going to last very long.

Anyway, here are a couple of definitions. Make sure you burn them in your head:

  • A “thread” is a different path of execution for code.
  • Every UI code is ran in what we call the “main thread“. The main thread takes care of changing of updating your user interface. That’s it’s main job. If you want to calculate the distance between the Earth and the Black Sun, you should probably run that in a new thread as to not block your main thread.
  • A “process” is a running executable – any running executable.. A process can have one to many threads.
  • A task is simply a fancy way of saying “work” – some work that has to be performed.
  • A “Concurrent Operation” takes place in a different thread than the one it was started in. If you start a concurrent operation on your main thread, the operation will take place in a different thread, either by creating it or by getting it handled to by someone else.
  • A “Condition” will prevent a thread from proceeding if it is not met. This is done for synchronisation purposes.
  • A “Critical Section” can only be accessed by one thread at any given time.
  • A “Mutex” is a ‘lock’ that provides mutually exclusive access to a shared resource. Only one thread may have an specific lock at any time. If another thread attempts to get the lock that is currently held by another thread, the attempting thread will be sent to sleep until the other thread gives the lock up.
  • A “Semaphore” is a protected variable that restricts access to a shared source. Both mutexes and conditions are semaphores.

Swallowing a Little Bit More of Multithreading Theory

NSOperation and its Subclasses

Concurrent programming using NSOperations and such are all about creating “operation objects”. Operation objects are instances of NSOperation and they encapsulate the code of your work you want to perform. NSOperation can be considered an “abstract class” (strictly speaking it really isn’t an abstract class because Objective-C has no support for marking classes as abstract) – that means that this class cannot be directly instantiated but rather it must be subclassed if you want to use it. The Foundation framework provides you with two subclasses ready to be used for you. You will use them most of the time. If they don’t suit your needs, you can subclass NSOperation yourself.

Here is a list of the operation classes provided by Foundation, along with a small description of them. Note that unlike their parent class these are not considered abstract so you can use them as-is.

  • NSInvocationOperation: You create an instance of this class by using an already existing object and an existing selector from your application. This is helpful when you have an object with a method that can be called both on a concurrent thread or on the main thread. This allows you to create operation objects more dynamically and with less restrictions. You could check for a condition (in this sentence I’m using “condition” as an “if-else” block, not condition in the threading terminology) to see if you will need to execute the method either concurrently or in your current thread. Very helpful and easy to use.
  • NSBlockOperation: As its name implies, you can use this class to execute various block objects at once. Note that due to the nature of this class, this operation is only considered completed when all its block objects have finished executing.

All operation objects support the following key features:

  • Dependencies. You can make a given operation execute after another one has finished. A practical example of this would be a program that downloads an image from the internet and applies an image filter to it. If your program download images from the internet and applies filters to them in the main thread, your app is going to be really, REALLY bulky and slow. Because we don’t want that to happen, we can separate the downloading and filtering into two different operations. Now, it wouldn’t make sense to apply a filter to an image that hasn’t been downloaded yet. So, to make sure that filtering operation takes places after the image is downloaded, you can add the download operation as a dependency of the filtering operation. That is, the filtering operation “depends” on the downloading operation.
  • Completion blocks. These are optional. If you are a “high intermediate” iOS developer like I assumed I assume you know why you would want to use this, but if you don’t, they are a way of asking your code to do something after an operation has finished.
  • You can monitor changes on the execution state of the operation using KVO (Key-Value Observing notifications – read my tutorial in KVO in case you don’t know this).
  • Prioritizing. You can define which tasks should be executed earlier than others. This will naturally alter the execution order of your operations.
  • You can cancel an operation at any time while it is executing. You can implement your own cancelation events if you need them.

It is pretty common to execute operations by adding them to an operation queue (NSOperationQueue), but it’s not strictly the only way to do it. You can start an operation anytime by calling its “start” method; but there’s a little gotcha – Doing this will not guarantee that your operation will run concurrently with the rest of your code. To determine whether your operation is running in a concurrent thread or not, you can call the isConcurrent method of the NSOperation class. This will return NO in case the thread is running synchronously (IE not in a different thread). So, in short, you will use NSOperationQueues 99.9% of the time.

Let’s Play With Some Operations

As usual, this is where you get your hands dirty. In this section we are going to play with NSInvocationOperation, NSBlockOperation, and a custom NSOperation. I have written this section of the tutorial thinking about you. Learning about Concurrency can be really energy draining, so at this point, I recommend you take breaks if you want or need to. Did you start reading this tutorial at 2:00 AM in the morning? That’s no problem, if you have energy left to read about NSInvocationOperations go ahead, but if by the time you are done reading that you are tired, you should definitely go to sleep and commit this knowledge to your brain, because attempting to go any further won’t do any good.

All the projects here are going to be done in simple command line tool projects. One of the bad things I noticed about concurrent programming tutorials for iOS or OS X is that people do a lot of platform-specific example. That doesn’t help when you just need a simple push to understand everything. Personally, I find general-purpose tutorials that only program for an specific platform dreadful. If a topic supports both OS X and iOS, then the logical thing is to keep it simple, because after all, you may be an iOS developer but the tutorial you found only uses examples for OS X. Because of this, the command line examples here should be useful for everyone, since every person reading this has written a command line tool writing “Hello World” to the Terminal (if you haven’t, you have offended the Tiki Gods!).

Buuuut let’s move on:

NSInvocationOperation

Like I have said above, an invocation operation works with an object and a selector. This is helpful when you have a task that may be called concurrently many times, or when you need to decide whether you can call it on your main thread or somewhere else.

For now just, just create a Command Line Tool (you should SERIOUSLY know this by now!) and write the code below. I will explain everything in a sec.

And a final note: For the sake of simplicity I have omitted details such as memory management. I trust you know how to deal with memory management both manually or ARC, and that you will always code responsibly in your projects.

//
//  main.mm
//  invocationoperation
//
//  Created by Andy Ibanez on 10/6/12.
//  Copyright (c) 2012 Andy Ibanez. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface numberCounter : NSObject
{

}
- (void)startCounting;
- (void)printCount;
@end

@implementation numberCounter
-(void)startCounting
{
    //First we have to create the invocation operation.
    NSInvocationOperation *countingOp = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(printCount)
                                                                              object:nil];
    NSOperationQueue *theQueue = [[NSOperationQueue alloc] init];
    theQueue.name = @"Counting Queue";
    [theQueue addOperation:countingOp];
}

-(void)printCount
{
    for(int i = 1; i <= 10; i++)
    {
        NSLog(@"%d", i);
    }
}
@end

int main(int argc, const char * argv[])
{
    numberCounter *numbah = [[numberCounter alloc] init];
    [numbah startCounting];
    for(int i = 1; i <= 10; i++)
    {
        NSLog(@"Sakura Kinomoto");
    }
    return 0;
}

The code here isn’t useful but I believe it illustrates it’s purpose really well. First, you may have noticed I have created an NSOperationQueue. This class takes care of managing operations. I have told you can run concurrent code without these queues, but that is barely needed. addOperation:, like its name states, adds an operation to the queue. The operation you add to the queue will start executing immediately if there are any threads available for you to use. This class also includes many helpful methods such us operations (an NSArray with all the operations on queue), operationCount (The number of operations left to execute), and cancelAllOperations. You can set the max amount of operation count by setting it’s maxConcurrentOperationCount property, you can suspend all the operations too. A very useful method included by this class is waitUntilAllOperationsAreFinished, which will freeze the thread that spawned the new thread until all the operations in the spawned thread are finished.

It is a helpful thing to give the new queue a name, since it provides you an easy way to refer to it.

You may have noticed that the only thing we ask our new thread to do is to print numbers from 1 to 10 to the Terminal window. We create this operation by passing it the selector and the object with that selector (for the curious, the “object” parameter is an object you can pass to the selector. It is of type id so you can pass any object your selector may take. Since in our case it doesn’t our selector doesn’t need any additional parameters, we pass in nil).

Once the operation is created, we add it to our newly created queue. In this example’s case, the operation starts executing right away.

I want you to look at the main function now. Here we create our numberCounter object (sorry for breaking the naming convention – I started writing this tutorial late at night and I sure ate some details). Then we call the method that creates and spawns the new thread. The loop below this one prints “Sakura Kinomoto” 10 times to the console. What are you expecting the result to be? You have a minute to think about it.

Got the answer? Oh, you got a solid answer? The truth is that you don’t know. Will it print the numbers 1 – 10 an then “Sakura Kinomoto” 10 times? Nope. Will it print a number, followed by “Sakura Kinomoto”, followed by another name, and followed by “Sakura Kinomoto” again? Nope. The answer is that this can be arbitrary. In fact, running the program many times will barely if ever print the same result.

I ran the program once. I got this result:

2012-10-07 01:06:21.341 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.342 invocationoperation[2180:1903] 1
2012-10-07 01:06:21.345 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.345 invocationoperation[2180:1903] 2
2012-10-07 01:06:21.346 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.346 invocationoperation[2180:1903] 3
2012-10-07 01:06:21.347 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.347 invocationoperation[2180:1903] 4
2012-10-07 01:06:21.347 invocationoperation[2180:1903] 5
2012-10-07 01:06:21.347 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.348 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.348 invocationoperation[2180:1903] 6
2012-10-07 01:06:21.349 invocationoperation[2180:1903] 7
2012-10-07 01:06:21.349 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.349 invocationoperation[2180:1903] 8
2012-10-07 01:06:21.349 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.350 invocationoperation[2180:1903] 9
2012-10-07 01:06:21.350 invocationoperation[2180:303] Sakura Kinomoto
2012-10-07 01:06:21.350 invocationoperation[2180:1903] 10
2012-10-07 01:06:21.351 invocationoperation[2180:303] Sakura Kinomoto

But if I run it again I will get a different output:

2012-10-07 01:08:08.681 invocationoperation[2190:1a03] 1
2012-10-07 01:08:08.680 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.689 invocationoperation[2190:1a03] 2
2012-10-07 01:08:08.689 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.689 invocationoperation[2190:1a03] 3
2012-10-07 01:08:08.690 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.690 invocationoperation[2190:1a03] 4
2012-10-07 01:08:08.690 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.691 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.691 invocationoperation[2190:1a03] 5
2012-10-07 01:08:08.691 invocationoperation[2190:1a03] 6
2012-10-07 01:08:08.691 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.692 invocationoperation[2190:1a03] 7
2012-10-07 01:08:08.692 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.692 invocationoperation[2190:1a03] 8
2012-10-07 01:08:08.693 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.693 invocationoperation[2190:1a03] 9
2012-10-07 01:08:08.694 invocationoperation[2190:303] Sakura Kinomoto
2012-10-07 01:08:08.694 invocationoperation[2190:1a03] 10
2012-10-07 01:08:08.695 invocationoperation[2190:303] Sakura Kinomoto

This is very important to notice, because after all, this is the point of concurrency. The threads are running in parallel printing output to the console at the same time. It is important to see that things will not work as you expect them to work. Even with all the beautiful threading abstraction provided by Apple, your code will not be predictable when working with threads.

What if you wanted to print all the numbers first and then print “Sakura Kinomoto” 10 times? You could create a new selector that will print Sakura Kinomoto and then create another NSInvocationOperation object using this selector, or you could freeze the thread “Sakura Kinomoto” prints on until the numbers thread is done printing.

We will do the latter first. Remember I told you about NSOperationQueue’s “waitUntilAllOperationsAreFinished” method? Simply call this method at the end of the method:

-(void)startCounting
{
    //First we have to create the invocation operation.
    NSInvocationOperation *countingOp = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(printCount)
                                                                              object:nil];
    NSOperationQueue *theQueue = [[NSOperationQueue alloc] init];
    theQueue.name = @"Counting Queue";
    [theQueue addOperation:countingOp];
    [theQueue waitUntilAllOperationsAreFinished];
}

This will print all the numbers 1 – 10 first and then “Sakura Kinomoto” 10 times, as expected:

2012-10-07 01:15:55.158 invocationoperation[2208:1703] 1
2012-10-07 01:15:55.166 invocationoperation[2208:1703] 2
2012-10-07 01:15:55.166 invocationoperation[2208:1703] 3
2012-10-07 01:15:55.167 invocationoperation[2208:1703] 4
2012-10-07 01:15:55.167 invocationoperation[2208:1703] 5
2012-10-07 01:15:55.168 invocationoperation[2208:1703] 6
2012-10-07 01:15:55.168 invocationoperation[2208:1703] 7
2012-10-07 01:15:55.169 invocationoperation[2208:1703] 8
2012-10-07 01:15:55.169 invocationoperation[2208:1703] 9
2012-10-07 01:15:55.169 invocationoperation[2208:1703] 10
2012-10-07 01:15:55.171 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.172 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.172 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.172 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.173 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.173 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.173 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.174 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.174 invocationoperation[2208:303] Sakura Kinomoto
2012-10-07 01:15:55.174 invocationoperation[2208:303] Sakura Kinomoto

Okay, this works wonderfully.

But suppose after a couple of months your boss asks you he wants a change in the program. He wants you to get rid of the loop printing “Sakura Kinomoto” 10 times. Instead, he wants you to print the numbers 11 – 20. The gotcha is that he doesn’t want you to wait until all threads are finished, and he wants you to print the numbers in order, too.

How to tackle this? Well naturally first you get rid of the “Sakura Kinomoto” loop in the main function. Then you will write the selector that prints 11 – 20 and add it to the queue you added the other selector to:

Here is the full code:

//
//  main.mm
//  invocationoperation
//
//  Created by Andy Ibanez on 10/6/12.
//  Copyright (c) 2012 Andy Ibanez. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface numberCounter : NSObject
{

}
- (void)startCounting;
- (void)printCount;
- (void)printCountTo20;
@end

@implementation numberCounter
-(void)startCounting
{
    //First we have to create the invocation operation.
    NSInvocationOperation *countingOp = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(printCount)
                                                                              object:nil];
    NSOperationQueue *theQueue = [[NSOperationQueue alloc] init];
    theQueue.name = @"Counting Queue";
    [theQueue addOperation:countingOp];
    
    NSInvocationOperation *to20 = [[NSInvocationOperation alloc] initWithTarget:self
                                                                       selector:@selector(printCountTo20)
                                                                         object:nil];
    [theQueue addOperation:to20];
    [theQueue waitUntilAllOperationsAreFinished];
}

-(void)printCount
{
    for(int i = 1; i <= 10; i++)
    {
        NSLog(@"%d", i);
    }
}

-(void)printCountTo20
{
    for(int i = 11; i <= 20; i++)
    {
        NSLog(@"%d", i);
    }
}
@end

int main(int argc, const char * argv[])
{
    numberCounter *numbah = [[numberCounter alloc] init];
    [numbah startCounting];
    return 0;
}

(One important thing – in this specific case it is very important you call waitUntilAllOperationsAreFinished. If you don’t, main will return with 0, meaning the program finished successfully, and the background thread won’t be executed).

Ahhh, you’re finished doing what your boss asked you to – or at least that’s what you think. When you run the program… Ohh the horror.

2012-10-07 01:28:57.076 invocationoperation[2237:1b03] 1
2012-10-07 01:28:57.076 invocationoperation[2237:1703] 11
2012-10-07 01:28:57.095 invocationoperation[2237:1b03] 2
2012-10-07 01:28:57.095 invocationoperation[2237:1703] 12
2012-10-07 01:28:57.096 invocationoperation[2237:1703] 13
2012-10-07 01:28:57.096 invocationoperation[2237:1b03] 3
2012-10-07 01:28:57.096 invocationoperation[2237:1703] 14
2012-10-07 01:28:57.096 invocationoperation[2237:1b03] 4
2012-10-07 01:28:57.097 invocationoperation[2237:1b03] 5
2012-10-07 01:28:57.097 invocationoperation[2237:1703] 15
2012-10-07 01:28:57.098 invocationoperation[2237:1703] 16
2012-10-07 01:28:57.098 invocationoperation[2237:1b03] 6
2012-10-07 01:28:57.099 invocationoperation[2237:1b03] 7
2012-10-07 01:28:57.099 invocationoperation[2237:1703] 17
2012-10-07 01:28:57.099 invocationoperation[2237:1b03] 8
2012-10-07 01:28:57.099 invocationoperation[2237:1703] 18
2012-10-07 01:28:57.100 invocationoperation[2237:1b03] 9
2012-10-07 01:28:57.100 invocationoperation[2237:1703] 19
2012-10-07 01:28:57.100 invocationoperation[2237:1703] 20
2012-10-07 01:28:57.100 invocationoperation[2237:1b03] 10

Okay now that’s what you wouldn’t call “printing the numbers in order”. How to solve this? One way to solve this would be to call the queue’s waitUntilAllOperationsAreFinished method after adding the first operation, but then this really wouldn’t be concurrent, as the current would be frozen until the other one was done executing, so you wouldn’t be able to do more work on it.

The right solution is to add a dependency. The operation that prints the numbers 11 – 20 depends on the operation that prints 1 – 10. That is, in this specific case, “to20” depends on “countingOp” to run.

To add dependencies to an operation, simply call it’s “addOperation” method, which takes an NSOperation as a parameter.

Since to20 depends on countingOp, we do this:

[to20 addDependency:countingOp];

The full method would look like this:

-(void)startCounting
{
    //First we have to create the invocation operation.
    NSInvocationOperation *countingOp = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(printCount)
                                                                              object:nil];
    NSOperationQueue *theQueue = [[NSOperationQueue alloc] init];
    theQueue.name = @"Counting Queue";
    [theQueue addOperation:countingOp];
    
    NSInvocationOperation *to20 = [[NSInvocationOperation alloc] initWithTarget:self
                                                                       selector:@selector(printCountTo20)
                                                                         object:nil];
    [to20 addDependency:countingOp];
    [theQueue addOperation:to20];
    [theQueue waitUntilAllOperationsAreFinished];
}

And finally, the result will be as expected. The code will run beautifully and concurrently with the right dependencies.

2012-10-07 01:36:02.639 invocationoperation[2259:1b03] 1
2012-10-07 01:36:02.658 invocationoperation[2259:1b03] 2
2012-10-07 01:36:02.659 invocationoperation[2259:1b03] 3
2012-10-07 01:36:02.660 invocationoperation[2259:1b03] 4
2012-10-07 01:36:02.660 invocationoperation[2259:1b03] 5
2012-10-07 01:36:02.660 invocationoperation[2259:1b03] 6
2012-10-07 01:36:02.661 invocationoperation[2259:1b03] 7
2012-10-07 01:36:02.661 invocationoperation[2259:1b03] 8
2012-10-07 01:36:02.662 invocationoperation[2259:1b03] 9
2012-10-07 01:36:02.663 invocationoperation[2259:1b03] 10
2012-10-07 01:36:02.670 invocationoperation[2259:1803] 11
2012-10-07 01:36:02.671 invocationoperation[2259:1803] 12
2012-10-07 01:36:02.671 invocationoperation[2259:1803] 13
2012-10-07 01:36:02.672 invocationoperation[2259:1803] 14
2012-10-07 01:36:02.672 invocationoperation[2259:1803] 15
2012-10-07 01:36:02.674 invocationoperation[2259:1803] 16
2012-10-07 01:36:02.675 invocationoperation[2259:1803] 17
2012-10-07 01:36:02.675 invocationoperation[2259:1803] 18
2012-10-07 01:36:02.676 invocationoperation[2259:1803] 19
2012-10-07 01:36:02.676 invocationoperation[2259:1803] 20

You can have threads in different queues, and the operations contained in this queues can have as dependencies operations in different queues.

Also note that cancelling an operation with dependencies means that the dependant code won’t be run.

Creating NSBlockOperation Objects

Apple has been moving away from the target-selector model in favour of blocks starting on iOS 4. Because of this the NSBlockOperation class has been introduced to deal with operations based on blocks. This provides a much better design in some cases – You no longer have to create a whole shiny new method if you know you will only execute a task concurrently once.

NSBlockOperations can have one or more blocks. Normally you provide the first block the moment you create the block. The operation is considered finished when all it’s contained blocks are done executing.

Luckily, I have already taught you most things about concurrency on the previous section so I don’t have much to say here, but there’s some things.

First, have this code:

//
//  main.mm
//  invocationoperation
//
//  Created by Andy Ibanez on 10/6/12.
//  Copyright (c) 2012 Andy Ibanez. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface numberCounter : NSObject
{

}
- (void)startCounting;
@end

@implementation numberCounter
-(void)startCounting
{
    //First we have to create the invocation operation.
    NSOperationQueue *theQueue = [[NSOperationQueue alloc] init];
    theQueue.name = @"Counting Queue";
    NSBlockOperation *theBlock = [NSBlockOperation blockOperationWithBlock:^{
        for(int i = 1; i <= 10; i++)
        {
            NSLog(@"%d", i);
        }
    }];
    [theBlock addExecutionBlock:^{
        for(int i = 11; i <= 20; i++)
        {
            NSLog(@"%d", i);
        }
    }];
    [theQueue addOperation:theBlock];
    [theQueue waitUntilAllOperationsAreFinished];
}
@end

int main(int argc, const char * argv[])
{
    numberCounter *numbah = [[numberCounter alloc] init];
    [numbah startCounting];
    return 0;
}

You create an NSBlockOperation by passing it the initial block. Then you can add more blocks as needed. What you need to know is that the blocks added to the operation are executed concurrently, so the example above doesn’t print the numbers in the right order. To do so, you will need to create a new NSBlockOperation and add the dependencies as needed.

Second, if you add any block objects to the operation after creating it, you have to add them before the operation starts executing (IE before adding the whole operation to the queue). If you add more blocks to the operation while it is running or after it has finished, the program will raise an exception.

Your Own NSOperation

In case the previous classes don’t suit your needs, as an emergency measure you may create your own NSOperation. We are not going to cover a full example of this because it is rarely needed, but I will give you the base so you can be prepared in case you stumble with a rare case where you will need your own NSOperation.

Your NSOperations should at least:

  • have a custom initialisation method.
  • Override NSOperation’s main method.

And of course, you may add any other methods your operation will need.

The initialisation method is mainly used to put your custom operation into a known state.

The main methods contains all the code your operation will execute. That is, here is where you would put any asynchronous URL downloading code or image filtering code.

Your own subclasses of NSOperation can start without being added in a queue. The only gotcha is that, if you want to create concurrent NSOperations, a lot of work has to be done. Firstly, you will have to observe the operation’s change state using Key-Value Observing, and responds to this changes accordingly.

If you’re planning on creating concurrent tasks by subclassing this class, then you have to override 4 additional methods that id with the management of the thread:

  • start
  • isConcurrent
  • isExecuting
  • isFinished

start should start your operation in an asynchronous manner. It should do whatever is necessary to do this, such as spawning a new thread for your operation. This method is also responsible for updating the thread state according to what the last 3 methods report.

The other three are pretty much self explanatory: One checks if the operation is concurrent, isExecuting checks if the operation is currently executing, and isFinished should check if the operation is finished.

I Need To Update My UI! What Do I Do?

It is very likely you will want to update your UI from a background thread. To update your UI according to the background thread, you need to get the main operation queue, and submit all UI-updating operations to this queue.

To get a handle to this thread, simply call the mainQueue method of NSOperationQueue.

[NSOperationQueue mainQueue]

And submit your operations as you would submit them to any other queue.

Cancelling Operations.

It is important to note that once you submit an operation to a queue, that operation is out of your control. The queue takes care of it. But one of the advantages of NSOperations over the lower-level GCD is that you can actually cancel operations anytime.

Individual NSOperations have a method called cancel, which as its name states, cancels the operation from executing. NSOperationQueues have a method called cancelAllOperations, which calls cancel in all the operations that are currently present in the queue.

It is also important to note that cancelled operations won’t stop their work right away. You are responsible for checking the value returned by isCancelled and abort your operation accordingly. Additionally, when you abort an operation manually, you should set isExecuting and isFinished to YES. Indeed in other words, you are responsible for managing your thread’s state at this point.

That’s it! This is a very large post. I tried to make it as easy as possible by using extremely trivial examples. So I hope you find it useful.

CHANGELOG:


October 12, 2012 at 10:35 PM [America/La_Paz]: First version of this tutorial.

The post Multithreading on iOS And Mac OS X Using NSOperations. appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/multithreading-ios-mac-os-x-using-nsoperations/feed/ 7 117
Key-Value Coding, Key-Value Observing, and Cocoa Bindings: A Basic Tutorial. https://www.andyibanez.com/key-value-coding-key-value-observing-cocoa-bindings-basic-tutorial/ https://www.andyibanez.com/key-value-coding-key-value-observing-cocoa-bindings-basic-tutorial/#comments Thu, 13 Sep 2012 23:19:04 +0000 http://andyibanez.com/?p=113 Key-Value Coding is an integral part of Cocoa and Cocoa Touch. Key-Value Coding allows you have more control over member changes, and to act accordingly.

The post Key-Value Coding, Key-Value Observing, and Cocoa Bindings: A Basic Tutorial. appeared first on Andy Ibanez.

]]>
Key-Value Coding Is Important.

Key-Value Coding and Key-Value Observing are really powerful concepts found throughout Apple’s frameworks. They allow you to write code more dynamically and even observe and act accordingly when properties in your classes change. This can be really useful, because you can do anything when a property changes, including but not limited to check if its value is valid, send a message to someone when something changes to a certain value and so on. The options are unlimited.

Key-Value Coding (KVC) and Key-Value Observing (KVO) are key when writing Mac OS X applications. Cocoa Bindings allow you to wrap your variables with Cocoa objects and this is done via KVC and KVO (note that iOS does not support Cocoa Bindings – instead, it uses the classic target-action concepts you already know). Cocoa Bindings are really powerful and very easy to work with.

KVC and KVO are found throughout many Apple frameworks for both iOS and Mac OS X. I will show you some examples of frameworks that make use of KVC and KVO in both iOS and Mac OS X so you can see how important they really are.

For some reason, KVC and KVO are tough topics to understand for many people, regardless of how simple they really are. In this tutorial, I will teach you KVC and KVO, and I will leave Cocoa Bindings as a little extra for those interested – it is not obligatory reading. If you’re interested in writing iOS apps and just iOS apps then Cocoa Bindings are irrelevant to you. But if you plan on writing more code for Apple and move on to the Mac, you may benefit a bit from that section.

Finally, before moving on, this post is for both Objective-C newcomers and people who have been writing code for way longer. No matter your experience, there is a slight chance you will get something out of this small tutorial.

‘Aight, let’s get started!

Key Value Coding: What Is It And Why Is It Needed?

KVC is a form of coding that allows you to access an object’s properties indirectly, using strings to access them instead of the property’s accessors or instead of accessing the variables directly.

To enable such mechanism, your classes must comply to the NSKeyValueCoding informal protocol. Luckily for you, NSObject complies with it and it also has default implementations of its methods, so most of the time you won’t need to modify anything in order to use KVC.

We are going to write KVC code shortly.

Why Would Anyone Want To Do That? How Can This Be Applied?

This is a very important question. What’s the point in using KVC to access properties when you can just use the accessors to do it?

Firstly, KVC allows you to do KVO: That is, if you are observing a variable, you will only be notified of its changes if and only if the changes take place using KVC. If you modify a variable directly using its setter you are not going to be notified of its changes. Does this sound abstract? Don’t worry if you don’t understand this paragraph just yet. You are going to understand everything a lot more once we get to the KVO section.

Secondly, like I said at the beginning of this tutorial, many of Apple’s frameworks use it for both iOS and Mac OS X. Core Data, for example, is one of the most powerful frameworks of Apple’s and it can use KVC, not to mention it is available in both Mac OS X and iOS. If you are using the NSManagedObject class instead of your own subclass of it, you “must” use KVC to access your Core Data fields with the object.

NSManagedObject *character; //Lets assume the core data object has been fetched.

//Giving the object some values to save later.
[character setValue:@"Sakura Kinomoto" forKey:@"characterName"];
[character setValue:38 forKey:@"ownedCards"];

//Fetching those values using KVC.

NSString *sakura = [character valueForKey:@"characterName"];
NSInteger numberOfClowCards = [character valueForKey:@"ownedCards"];

KVC can be avoided when using Core Data if you subclass NSManagedObject. Regardless, it’s important to know what’s happening under the hood.

So enough yaddas. Let’s write some KVC code. Go to Xcode and create a new Command-Line Tool project (please note I hate giving explicit instructions such us “Launch Xcode, navigate to file, a new window will show up, go to X section, and select Command-Line tool” because for all my tutorials I assume you are familiar with your tools and you should know how to use them without instructions). I named my project “CardCaptorChars”.

A couple of things need to be changed before we move on with the example. First, rename main.cpp to main.m. Then delete all the code in this file and just write the basic skeleton of the program. Don’t forget to import the Foundation framework:

#import <Foundation/Foundation.h>

int main()
{

}

Afterwards, create an Objective-C class with a couple of properties and methods (feel free to do it in the same file. The point of this tutorial is not to show how can files be separated and such). Here’s mine:

@interface Character : NSObject
{
	NString *characterName;
	NSInteger ownedClowCards;
}
@property (nonatomic, copy) NSString *characterName;
@property NSInteger ownedClowCards;
-(void)hasLostClowCard;
-(void)hasGainedClowCard;
@end

If you’re following with my example, here’s the implementation:

@implementation Character
@synthesize characterName;
@synthesize ownedClowCards;

-(void)hasLostClowCard
{

}

-(void)hasGainedClowCard
{

}

@end

The methods are going to be filled in the KVO section.

Now we are going to create some objects and set and get the variables using KVC. So lets implement main():

int main()
{
	Character *sakura;
	Character *shaoran;

	//Create and give the properties some values with KVC...
	sakura = [[Character alloc] init];
	[sakura setValue:@"Sakura Kinomoto" forKey:@"characterName"];
	[sakura setValue:[NSNumber numberWithInt:20] forKey:@"ownedClowCards"];

	shaoran = [[Character alloc] init];
	[shaoran setValue:@"Li Shaoran" forKey:@"characterName"];
	[shaoran setValue:[NSNumber numberWithInt:21] forKey:@"ownedClowCards"];

	//Done! Now we are going to fetch the values using KVC.

	NSString *mainCharacter = [sakura valueForKey:@"characterName"];
	NSNumber *mainCharCards = [sakura valueForKey:@"ownedClowCards"];

	NSString *rival = [shaoran valueForKey:@"characterName"];
	NSNumber *rivalCards = [shaoran valueForKey:@"ownedClowCards"];

	NSLog(@"%@ has %d Clow Cards", mainCharacter, [mainCharCards intValue]);
	NSLog(@"%@ has %d Clow Cards", rival, [rivalCards intValue]);
}

And that’s it! Setting and getting variables with KVC is really, really straightforward. It is a bit more of work but it is needed in some cases.

Key Value Observing

The main reason you would want to work with KVC is to observe object properties when they change. KVO simply allows you do to that. Any object can observe any variable in any “key path”.

But First, a word on Key Paths.

What’s a key path? The name “Key Path” sounds intimidating. Actually, I got scared when I first saw that term. A Key Path is simple a “full route” to a property. “self.name” is the full key path to self’s name property. If you have a person that has a Clock that has a Time with a given Hour, its key path would be “clock.time.hour”.

Sakura has 20 Clow Cards and Shaoran has 21. Wouldn’t it be interesting to know when they lose or earn a new Clow card? At least our program could tell us when such a thing happens.

Implementing KVO is as easy as adding an observer for the desired key path and implementing a fixed method that gets called whenever the observer notices changes in its observed variable. To register an object as an observer you use NSKeyCodingProtocol’s addObserver:forKeyPath:options:context: method. The observeValueForKeyPath:ofObject:change:context: method is called whenever a change takes place.

So first, you need to add this method to your class:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

}

This is the essential method that gets called when the value changes. You can also get notified when the value at the key path is about to change and you can get notified after the change takes place, using the methods willChangeValueForKey and didChangeValueForKey respectively. We are not going to implement these methods but their use is really straightforward.

Once you do, we are going to register Sakura to observe her own changes. You could naturally ask Shaoran to be notified when Sakura’s Clow card counter changes and vice-versa. Add this after declaring the characters.

[sakura addObserver:sakura forKeyPath:@"ownedClowCards" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

I want you to pay special attention to the options. NSKeyValueObservingOptionNew and NSKeyValueObservingOptionOld. With these two options we are specifying the the change NSDictionary should contain both the new value and the old value. In our case we need to know both to know if the Clow card count has increased or decreased.

A little note. At the end of your program make sure you remove Sakura as her own observer. Otherwise the console prints a nasty message.

[sakura removeObserver:sakura forKeyPath:@"ownedClowCards"];

We are going to implement our two empty methods now:

-(void)hasLostClowCard
{
	NSLog(@"%@ has lost a card! Cards now: %ld", characterName, ownedClowCards);
}

-(void)hasGainedClowCard
{
	NSLog(@"%@ has earned a card! Cards now: %ld", characterName, ownedClowCards);
}

Very simple, but lets keep it like that for the sake of demonstration.

Now we are going to implement observeValueForKeyPath:ofObject:change:context: in such a way that hasLostClowCard gets called when the character has less cards than before and hasGainedClowCard when the character has more. Like I told you before, the options define what will be passed in the change dictionary, so make sure you use the Apple documentation when you need it.

The implementation simply looks like this:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	if([keyPath isEqualToString:@"ownedClowCards"])
	{
		NSInteger oldC = [change objectForKey:NSKeyValueChangeOldKey];
		NSInteger newC = [change objectForKey:NSKeyValueChangeNewKey];
		if(oldC < newC)
		{
			[self hasGainedClowCard];
		}else
		{
			[self hasLostClowCard];
		}
	}
}

And that’s all. It’s pretty straightforward: First we make sure that the key we are observing is the one being changed. If it is, We save the old and new values in variables, and we compared them to see what message should be sent.

This is really, really powerful. Having control even on the change of your properties is a really powerful feature and I’m sure you will find great cases to use in your own projects.

As usual, you can find the source code of the above project on my Pastebin here. And of course, feel free to ask questions shall you have them.

A Little Extra: Cocoa Bindings in OS X.

If you are just writing iOS apps, the tutorial ended with section 2. If you are a Mac Developer too (or want to be), then you should read this section to understand how Cocoa Bindings work with KVC and KVO and how powerful they can be.

Cocoa Bindings is about binding a variable to a GUI object, so when one changes, the other changes as well and are therefore “kept in sync”. Using Cocoa Bindings is a way of creating target-action for whenever you do something with your GUI objects.

To show you how Cocoa Bindings work, we are going to create a Mac app with a slider and an NSLog() that will let us know whenever the slider has changed and the value it changed to. So create a new Mac Cocoa Application with Xcode and drag a slider to it. The slider should have a range of 0 to 100. You should have something like what I have below:

Now on your app delegate’s header add a new property called sliderValue.

@property NSInteger sliderValue;

And don’t forget to synthesise it.

(Not showing full code here, because again, I expect you know your way around this stuff for now. But as usual, you will find a link to download the example project at the end of this tutorial.

Now open the Bindings Inspector. The bindings inspector is the icon that looks weird, and is the second to last icon. Picture below:

Expand the Value drop down. Check the “Bind to” checkbox and the select “App Delegate” in the drop down menu next to it. Now finally, write “self.sliderValue” in Model Key Path.

We just bonded sliderValue with our slider so they will be kept in sync whenever one changes. We still won’t receive notifications when there are changes, so register the App Delegate to observe sliderValue as well.

[self addObserver:self forKeyPath:@"self.sliderValue" options:NSKeyValueObservingOptionNew context:nil];

And implement observeValueForKeyPath:ofObject:change:context:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	NSInteger newVal = (NSInteger)[change objectForKey:NSKeyValueChangeNewKey];
	NSLog(@"changed %ld", newVal);
}

Now you just bonded both items together without having to do much effort! There’s many other things you can do with Cocoa Bindings – You could, for example, keep the slider and a label in sync at the same time. Everything you would need to do is to create the label and observe its title property.

And that’s it! I hope this tutorials helps you understand some nifty concepts better. KVC and KVO are important concepts that everyone should know.

CHANGELOG:


September 13, 2012 at 8:00 PM [America/La_Paz]: First version of this tutorial.

The post Key-Value Coding, Key-Value Observing, and Cocoa Bindings: A Basic Tutorial. appeared first on Andy Ibanez.

]]>
https://www.andyibanez.com/key-value-coding-key-value-observing-cocoa-bindings-basic-tutorial/feed/ 20 113