I am implementing some Facebook functionality in my iPhone app right now which needs an app login. The login itself isn't a problem any more, it's working.
But due to the fact that the Facebook SDK works with events, I don't know how to perform my action as a reaction to a successful login.
For example:
I have a method
- (void)refreshEvents;
This method needs to call the login method to make sure that the action can actually be performed. So I call [self checkLogin]
- but what now? How can I wait for an event that's not really bound to my method? As checkLogin triggers asynchronous actions/events I cannot just tell it to wait until the login is performed.
In the method
- (void)request:(FBRequest *)request didLoad:(id)result;
while handling the resulting access token, how can I tell it what's been the initial action, so it can continue?
My idea is to use an instance variable for an array that's holding a queue of "actions to perform after login", but this seems to be a really nasty workaround.
Thanks for your help
Arne
The simplest solution would be to pass a completion block that can be executed once the login completes. In addition, you could pass a block that gets called if there is an error. In my applications I have wrapped this into a 'responder' pattern where you define a class that contains a completion and error block. That is passed as an argument to asynchronous methods. The only catch here is that you have to write the login to 'execute' the blocks at the appropriate time.
I have implemented this pattern several times on applications that use asynchronous API's (including the Facebook SDK).
UPDATE (added some code samples):
In its simplest form, you could just add a completion block. First, you would want to create a typedef for your completion block. In this case, we'll use a block that returns no value and has an id input:
Next, you could create a controller that creates a facade for your interaction with the Facebook class. In this facade, you could create a login method that has a signature like this (this assumes you have an iVar of type successBlock):
Finally, in your FBSessionDelegate implementation, you can execute this block:
}
The 'Responder' pattern I mentioned above is a bit more involved than this, but this should be enough to get you going.