ObjectiveFlickr: ContactsBrowser Demo
ObjectiveFlickr is an OS X framework now. The project file that resides in its Google Code respository now builds the whole things into a nifty ObjectiveFlickr.framework. You can then in turn incorporate it into your own Flickr desktop application.
Currently the project file also builds two other demos. FlickrBasics is what I have done two weeks ago, using the basic “building blocks” (OFFlickrAPIContext, a URL generator, and OFFlickrRESTRequest, a HTTP request wrapper). Another new demo, ContactsBrowser, is a very simple table view that lists all of your contacts. A separate login sheet now guides the user through the interesting Flickr authentication process. That component should be able to be reused in your project, too.
A few notables things happening around the source code.
First of all, a whole new class called OFFlickrAPICaller. This is the “higher level” API wrapper that I’ve been talking about in the last few posts. Now it’s there. Once you have created your API context object (which handles API Key, Shared Secret and your obtained Authentication Token), pass it to your caller object, and then it’s done. Use the callMethod:arguments: method to perform any Flickr method–it takes care of the authentication and signing for you, so just pass the needed arguments. Some Flickr methods behave differently when authenticated, if you want to do that, pass an “auth” argument with any parameter, for example:
[apiobj callMethod:@"flickr.photo.search" arguments: [NSArray arrayWithObjects:@"tags", @"mac", @"auth", @"yes", nil]];
Which behaves slightly different from:
[apiobj callMethod:@"flickr.photo.search" arguments:[NSArray arrayWithObjects:@"tags", @"mac", nil]];
Secondly, OFFlickrAPICaller accepts two flavors of callbacks. One is to use the plain-vanilla set of delegate methods:
- (void)flickrAPICaller:(OFFlickrAPICaller*)caller didFetchData:(NSXMLDocument*)xmldoc;
- (void)flickrAPICaller:(OFFlickrAPICaller*)caller error:(int)errcode errorInfo:(id)errInfo;
- (void)flickrAPICaller:(OFFlickrAPICaller*)caller progress:(size_t)receivedBytes expectedTotal:(size_t)total;
When you receive the message, you can use the userinfo (by calling [caller userInfo]) to retrieve the state information you’ve given prior to the calling.
But, it’s always nice to have more than one way to do it. We can use a designated method for a given call, so long as the handler method matches the signature “- (void)foo:(OFFlickrAPICaller*)caller bar:(int)errcode blah:(id)data”:
[apicall setSelector:@selector(handleFrob:errorCode:data:)]
[apicall callMethod:@"flickr.auth.getFrob" arguments:[NSArray arrayWithObjects:@"frob", aFrob, nil]];
So for different Flickr API calls you can have different handlers respectively, instead of cramming everything into a single flickrAPICaller:didFetchData:.
Thirdly, since we are using Objective-C and Objective-C has this nifty thing called categories, we can use it to convert an XML document into a dictionary:
- (void)handleGetContacts:(OFFlickrAPICaller*)caller errCode:(int)errcode data:(id)data
{
// error handler…
NSDictionary *d = [data flickrDictionaryFromDocument];
}
The conversion follows the convention set by BadgerFish. I didn’t handle namespaces though.
Finally–and I’ll call it a day after this–you don’t really have to use the callMethod:arguments: to perform a Flickr API call. Instead, you can do this:
[apicall setSelector:@selector(handleFrob:errorCode:data:)]
[apicall flickr_auth_getFrob:@"foobar" frob:aFrob];
But I didn’t implement all of Flickr’s API calls (there are 95 of them!), but instead used Objective-C’s method dispatching mechanism to do the magic for me. Pass any unknown method to any OFFlickrAPICaller object, and it translates the method into a proper Flickr API call. Pass anything as the first argument, and it will become your userinfo. So the above snippet is the equivalent of:
[apicall setSelector:@selector(handleFrob:errorCode:data:)]
[apicall setUserInfo:@"foobar"];
[apicall callMethod:@"flickr.auth.getFrob" arguments:[NSArray arrayWithObjects:@"frob", aFrob, nil]];
The compiler will complain the receiver may not handle flickr_auth_getFrob. I’m still looking for ways to turn it off.
But, so much for today. There are still other works to be done, esp. more documentation, code comment, and more example. I’d be eager to hear if this framework is helpful in building real apps. As always, comments and feedbacks are always welcome!
lukhnos :: Sep.27.2006 ::
tekhnologia ::
3 Comments »