iOS 5 Twitter Integration with soft fallback

After the introduction of Twitter support to iOS 5, it has become really difficult to find reasons not to add it to your app. Indeed, Apple made adding Twitter to your app really a snap. As you can find out from several sources on the web, all that is needed is:

1. Importing the relevant header files into your .m file

[sourcecode]
#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
#endif
[/sourcecode]

Notice how the import is guarded, so that it only occurs when you are compiling in an Xcode version that supports SDK 5. Once you have done that, the next step is:

2. Adding the code to tweet

[sourcecode]
– (IBAction)tweet:(id)sender {

Class tweeterClass = NSClassFromString(@"TWTweetComposeViewController");
if (tweeterClass != nil && [tweeterClass respondsToSelector:@selector(canSendTweet)]) {
UIViewController *twitterViewController = [[tweeterClass alloc] init];

[twitterViewController performSelector:@selector(setInitialText:) withObject:@"Check This Wonderful APP"];
[self presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}
[/sourcecode]

Notice how the tweet has the form of an event handler that you can associate to tapping on a button. Also, notice how the use of NSClassFromString and performSelector allows to avoid having to guard this code against compilation or execution when iOS 5/SDK 5 is not there. This code will simply work.
The example above shows a very basic use of the Twitter framework. You could as easily add more juice by providing an image and a URL for your tweet, like in the following:

[sourcecode]
– (IBAction)tweet:(id)sender {

Class tweeterClass = NSClassFromString(@"TWTweetComposeViewController");
if (tweeterClass != nil && [tweeterClass respondsToSelector:@selector(canSendTweet)]) {
UIViewController *twitterViewController = [[tweeterClass alloc] init];

[twitterViewController performSelector:@selector(setInitialText:) withObject:@"Check This Wonderful APP"];
[twitterViewController performSelector:@selector(addURL:) withObject:[NSURL URLWithString:url]];
[twitterViewController performSelector:@selector(addImage:) withObject:urImage];
[self presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
}
[/sourcecode]

Once you have your twitter code in place, do not forget the last step:

3. Adding Twitter and Accounts Frameworks to your project

This goes without special need for explanations.

The only point worth noting is that you need making those frameworks optional, like in the picture here, if you want your app run also on iOS version previous to iOS 5.

At this point, you have Twitter integrated. Really easy.
The only problem left is: what to do with previous versions of the iOS SDK, which did not offer Twitter integration?

There are several options. One is supporting Twitter through MGTwitterEngine by Matt Gemmell, or ShareKit. Actually, ShareKit offers many more possibilities of integration with sharing and social services out there, so you might have a look at it beyond the need for Twitter integration.

Anyway, integrating MGTwitterEngine or ShareKit, though not difficult, is slightly more complex than what you need to do to natively support Twitter in iOS 5. Mostly, the complexity comes from having to handle the oAuth protocol, obtaining a Key from Twitter for your app and so on.

So, what I am suggesting in this post is defining a soft fallback strategy for your app:

  1. full Twitter support under iOS 5;
  2. soft fallback in previous iOS versions.
What a “soft fallback” strategy is may be the following:
  1. check if any Twitter client is available ;
  2. if so, launch it;
  3. if no Twitter client is available, open Safari pointing to Twitter.
This is definitely not the same as using MGTwitterEngine or ShareKit to support Twitter in your app, but it might be the best way for you to go if you do not want to spend any effort on Twitter for iOS 4 or iOS 3.
Indeed, soft fallback is very easy to support. Simply add the following lines to the above code:[sourcecode]
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"twitter://"]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://"]];
} else if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"twitterrific://"]]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitterrific://"]];
} else {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://twitter.com/"]];
}
[/sourcecode]

This code snippet just shows support for two Twitter clients, the official one by Twitter and Twitterrific, but you get the idea about adding any Twitter client you decide to support. In case, you can find out URL schemes for most apps on this very useful page: iPhone URL Scheme.

As said, Twitter integration the easy way. It may work for your app, or it may not, but this is the solution I prefer using right now.

convert RGB image to grayscale

convert is a very powerful tool from the ImageMagick toolbox.

Swiping and pinching with UIWebView

One of the most versatile classes that the iOS SDK offers is UIWebView. Indeed, it can be used as a very flexible tool to display a vast range of content types: rich text, graphics in SVG format, PDF files, and so on. It is also, IMO, the cornerstone of any sane approach to supporting multiple mobile platforms, e.g. iOS and Android. Inevitably, when you integrate UIWebView into your app, you come to face a problem: how you handle pinching and swiping correctly. As flexible as it is, in fact, UIWebView has got a major shortcoming in its “greediness” to touches: it wants them all and it handles it its own way, i.e., like a web browser would do. This is not what you want in most cases and this post will outline an approach to make UIWebView behave like any other views under iOS.

Google's Cookies and pundits everywhere...

Reading “Cookies and Privacy” by John Gruber, Daring Fireball, I was astound by the following line of reasoning that Gruber pointedly arguments against:

More animation transitions for iOS

I think that one of the most common deceptions for iOS developers is to discover how small is the set of default transitions that the iOS SDK support out of the box. There are just four of them: flip from left or right, and curl up or down. Well, I also think that all iOS developers also think that those four are simply the only <i>public</i> transitions in the SDK, but that there have to be more. But, you know, non public means rejection, a word that  no one likes.