{ by david linsin }

February 15, 2011

ShareKit Pimping

A couple of months ago, I improved Word Buzz' Twitter sharing feature significantly, by leveraging a tweaked version of an existing framework. Unfortunately, I had only heard of ShareKit at that time, that's the reason why I decided to implement my own solution!

In case you don't know about ShareKit or like me only heard about it:

SharKit adds full sharing capabilities to your App. It's a drop-in library, which supports services like Twitter, Facebook, Instapaper and many more. You can share links, text and pictures with a customizable user interface. It evens queues shared items until an internet connection is available.

SharKit is awesome and I really regret not using it to add Twitter sharing to Word Buzz. It has a well documented API and is really easy to extend, there's even a step-by-step guide on ShakreKit's website, which describes the process. I followed that guide to add TwitPic and yfrog capability to ShareKit for one of our next furryfishApps projects and that's what I'd like to write about in this post.

ShareKit comes with built-in Twitter support, which you can find in SHKTwitter and its authentication form SHKTwitterForm. It uses bit.ly to share images, which has a similar API as TwitPic and yfrog. I piggybacked on that implementation, however dropped oAuth support in favor of xAuth.

I know there are a lot of discussions on xAuth, however I found it the easiest way to provide the most benefit for iPhone App users, without compromising security in a hurtful way. In order to get your iPhone App ready to use xAuth with Twitter, you need to sign up at http://developer.twitter.com/. I described the process in a previous post.

The previously mentioned class SHKTwitter inherits from SHKOAuthSharer, which does all the heavy lifting in terms of authentication for you! All you need to do is hook into the API calls and customize your authentication screen:

return [NSArray arrayWithObjects:
[SHKFormFieldSettings label:SHKLocalizedString(@"Username") key:@"username" type:SHKFormFieldTypeText start:nil],
[SHKFormFieldSettings label:SHKLocalizedString(@"Password") key:@"password" type:SHKFormFieldTypePassword start:nil],
[SHKFormFieldSettings label:SHKLocalizedString(@"Send to Twitter") key:@"sendToTwitter" type:SHKFormFieldTypeSwitch start:SHKFormFieldSwitchOn],

So let's say the user wants to share a picture, taps on the share icon and select TwitPic. He authenticates after being prompt for his Twitter credentials. When the authentication was successful, you want to show some sort of form to your users, where they can enter a comment or in case of Twitter, their status. You can totally customize the UI, without any dependency to ShareKit. In fact SHKTwitterForm, ShareKits built-in Twitter form, is a simple UIViewController with its delegate set to SHKTwitter.

The actual sharing part of the code is as straight forward as the rest of ShareKit. It's a little verbose, but once your understood the concept, it's easy to extend:

- (void)sendImage {

NSString * oauthHeader = [self oauthHeader];

NSURL *serviceURL = [NSURL URLWithString:@"http://yfrog.com/api/xauth_upload"];
OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL

[oRequest prepare];
[oRequest setValue:nil forHTTPHeaderField:@"Authorization"];

[oRequest setHTTPMethod:@"POST"];
[oRequest setValue:@"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:@"X-Auth-Service-Provider"];
[oRequest setValue:oauthHeader forHTTPHeaderField:@"X-Verify-Credentials-Authorization"];

NSString *boundary = @"a21ff70823f9";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[oRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];

NSMutableData *body = [NSMutableData data];

[body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"key\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[self.yfrogAPIKey dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"media\"; filename=\"upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[self imageData]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[oRequest setHTTPBody:body];

[self sendDidStart];

// Start the request
OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest

[fetcher start];

[oRequest release];

As you can see most of the work goes into setting up the authentication headers for the request, as well as filling in the elements of the request body. There are APIs like ASIHTTPRequest, which handle this for you, however ShareKit doesn't use them and I didn't want to introduce a 3rd party library. If you take a look at Gurpartap's TwitPic engine, you can see how easy and simple the code would be.

Overall it's a breeze to develop with SharKit and I'm glad I digged in deeper. For our next project we'll definitely use it and you should at least take a look at it before rolling your own implementation.


  • mail(dlinsin@gmail.com)
  • jabber(dlinsin@gmail.com)
  • skype(dlinsin)