Sunday, September 23, 2012

The evolution of lazy initialization

Lazy initialization is tent pole of Objective C. Apple placed a lot of emphasis on using the pattern in the early iPhone days. That was justified especially considering that the original iPhone shipped with 128MB of RAM, compared to the latest iPhone 5 with 1024MB of RAM.

In the beginning

The ARC evolution

The ARC evolution was fairly tame, allowing us to move the ivar into the implementation files. While the original method was great, and served me well until ARC. With no need to dealloc, and the ability to have iVars that aren't declared in the public interfac.

Clang takes it up a notch

With the most recent versions of Clang you no longer have to use the @synthesize & @dynamic keywords when making @property declarations.
This is all well and good, but I don't want to write my own ivars if I don't have to. So I've set about exploring ways that I can do away with having to create my own ivars.

Option 1.

This approach is comprised of three steps
  1. Public readonly property declaration
  2. Private readwrite property (re)declaration in a class extension
  3. Assign our instance to the ivar

The problem with this is that there is still the ability to overwrite the ivar. Granted it's only from within the class, but still not ideal. This could be an advantage as if you decide to move away from the pattern all you need to do is set the ivar via the mutator.

Option 2.

Another alternative, is to take advantage of another clang feature, where we use the @synthesize directive, to generate a backing ivar on request, without having to explicitly declare the ivar, or at least declare it in a conventional way.
Along with being the smallest version, we can specify the format of our private ivars, so if you want to suffix your underscore rather than prefix it, you have that option.

Whats the solution?

Quite frankly, i don't know. I'm leaning towards Option 2 as it doesn't provide an mutator for the ivar, and so there is almost no suggestion that the ivar should be mutated by anything thing other than the lazy accessor. However I'm interested to hear the opinions of others.

Thursday, September 20, 2012

I Took a Picture [Cambodia Edition]

A sunset in Sihanoukville, Cambodia


It feels like an eternity since it was announced but iOS 6 is finally available to the masses, and we can now talk about the all the (few) new goodies that it contains.
Apple included the Social Framework in iOS 6 as an abstraction layer for accessing the various social services that are now included with iOS. The key feature here is that you never have to deal with the Facebook SDK again if you wish...
So let's explore how you can use the new Social framework classes to replace REST API access functionality that is provided via the Official Facebook SDK
TL;DR; Sample code

Create an ACAccountStore

According to Apple's developer documentation the ACAccountStore
[ACAccountStore] provides an interface for accessing, manipulating, and storing accounts. To create and retrieve accounts from the Accounts database, you must create an ACAccountStore object. Each ACAccount object belongs to a single ACAccountStore object.
A simple alloc && init sent to ACAccountStore will suffice. Perhaps the easiest thing you'll do this week.

Get the Facebook ACAccountType

The 2nd easiest thing you'll do this week

Request access to currently logged in Facebook User

Before the callback block is called the User will be presented with a UI to confirm that they want your app to have permission to access this API. In the event that initial permission has been revoked, or disabled you will be given a negative boolean value.

Select an authenticated ACAccount

Your block will need to reference your ACAccountStore instance in order to see which accounts you have access to. To actually access the accounts you need to call the accountsWithAccountType: method which returns a NSArray of ACAccount objects. Where the type argument is account type we got in the previous section.
Apple has designed the ACAccountStore class to support multiple authorised user accounts. While iOS 6 only supports a single Facebook account, it does support multiple Twitter accounts. So while it is safe to assume that first (and only entry) in this collection is the ACAccount you want to use, the same cannot be said when you are working with Twitter accounts. Ideally you would want to present a 'picker' UI to the end user.

Construct a SLRequest

SLRequest is the Social frameworks NSURL request abstraction to enable it to support request signing, and token passing, features used by Twitter and Facebook. The SLRequest class also has a convenience method for dispatching this request.
If you are a fan of request queuing, and application wide request management there is also the option to extract a prepared NSURLRequest object with you can then pass to something like an AFNetworking request operation (See below).

That's it! If you weren't able to string the process together in your head magically, you can view the entire gist. Thanks for reading!