Matt Legend Gemmell Modesty is Lying

Mac OS X Cocoa and iPhone Development Services available at Instinctive Code.
Mac OS X Cocoa and iPhone Developer for hire

Other Pages

Categories

Posted
22 February 2008 @ 12pm

Categories
Development, Source

Tags
, , , , , , ,

MGTwitterEngine - Twitter from Cocoa

Ever wanted to integrate Twitter support into your Cocoa app? I know I did. Enter MGTwitterEngine, available as always from my Cocoa Source Code page. (Oh, and I’m “mattgemmell” on Twitter, by the way).

MGTwitterEngine is an Objective-C class which lets you integrate Twitter support into your Cocoa application, by making use of the Twitter API. The entire API is covered, and appropriate data is returned as simple native Cocoa objects (NSArrays, NSDictionarys, NSStrings, NSDates and so on), for very easy integration into your own application. MGTwitterEngine is designed for Leopard, but should be just fine on Tiger too.

Update: Since I made this post, MGTwitterEngine has been updated several times, so be sure to read on for more details. There’s now an iPhone version too, and an article by Tim Burks on using MGTwitterEngine via Nu.

Creating a TwitterEngine is as easy as instantiating it, setting your Twitter username and password, and you’re done:

MGTwitterEngine *twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
[twitterEngine setUsername:@"username" password:@"password"];

// Get updates from people the authenticated user follows.
NSString *connectionID = [twitterEngine getFollowedTimelineFor:nil since:nil startingAtPage:0];

You just implement a few delegate methods (for returned Twitter statuses, user information, and direct messages), and MGTwitterEngine does all the rest. It supports regular or secure connections, custom Twitter client information (so updates sent from your app can show as “from MyCoolApp” on the Twitter website), and handles all the boring stuff like network connections and XML parsing.

Give it a shot and see what you think - you can grab the code from my public subversion repository at svn.cocoasourcecode.com (please do use the code in the repository since it’s always up to date, but if you really want to just download a zip file then you can get one here). Maybe you could make the next Twitterrific?

(Note: XMPP and OAuth support coming later, when Twitter’s implementation stabilises!)

Update 1: Now includes a Read Me giving some information on how to use the class and what types of data it returns.

Update 2: There’s now an iPhone version of MGTwitterEngine, courtesy of Pedro Cuenca (pcuenca on Twitter). You can download the iPhone version here. Here are Pedro’s notes:

The attached archive contains all the modifications plus a Makefile intended for the iPhone.

The main differences are:

- Protocols are not well supported by current iPhone toolchains, and apps that use them tend to crash. I’ve had to include a conditional compilation flag that removes protocol declarations when compiling for the iPhone. This means that delegate instances are simply of type “id”. Instead of calling the delegate methods directly, I’m using respondsToSelector / performSelector pairs to invoke them dynamically. Delegate invocations in MGTwitterXMLParser should be handled using NSInvocation, but I did not write that code yet. Therefore, compilation for the iPhone will yield a couple of warnings.

- The NXSMLParser class has to be loaded dynamically, using NSClassFromString. The same happens for NSDateFormatter.

- Class init methods have been slightly modified to suppress strict compiler warnings.

- New main_iphone.m file, and implementation of applicationDidFinishLaunching: method in AppController.m

Awesome. Many thanks to Pedro for that!

Update 3: Source code has been updated, thanks to feedback from Craig Hockenberry (of Twitterrific fame).

  • We now specify login credentials encoded in the URL instead of in the request headers. This removes the requirement for linking the libcrypto framework or including the NSData+Base64Extensions category files.
  • Secure (HTTPS) connections are now on by default.
  • We now remove cookies after setting a new username/password, to ensure that the next request uses the correct credentials.
  • Added method for sending an update in reply to a specific other update. Support for this on Twitter’s side hasn’t gone live yet, but when it does this should just work transparently.
  • Fixed a small memory leak.

Thanks to Craig for the benefit of his experience working on Twitterrific.

Update 4: Code updated once again; get it from the svn repository mentioned previously. Each tweet or direct message returned by MGTwitterEngine now has an extra value in the NSDictionary, specifying what type of request was sent to Twitter and produced that tweet/message. This is very handy if you need to quickly know that, say, a tweet came from the list of replies instead of from the main tweets timeline, so that you can colour replies differently from regular tweets (as Twitterrific does).

This useful feature was implemented due to a request from Craig Hockenberry; thanks to Craig for the suggestion.


11 Comments

Mathieu Tozer
22 February 2008 @ 4pm

Thank you! I already have an app idea :)


Peter Hosey
22 February 2008 @ 7pm

> custom Twitter client information

Perhaps it could auto-detect this from [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey]?


Mathieu
22 February 2008 @ 7pm

Congrats Matt! It’s going to be very useful for a lot of us!


robby valles
22 February 2008 @ 8pm

nice!! good job :)


Jon Crosby
22 February 2008 @ 9pm

Possibly of interest if you go the OAuth route: http://code.google.com/p/oauthconsumer/wiki/UsingOAuthConsumer


Matt Legend Gemmell
24 February 2008 @ 4pm

HI all,
Cheers for the positive feedback - hope you’ll find the code useful. :)

Peter, my feeling was that that kind of thing was better implemented in the client which uses MGTwitterEngine, rather than in the class itself - I deliberately tried to keep the API as implementation-agnostic as possible.

Jon, thanks for that. I actually already had your code bookmarked for future use in that regard. ;)


Raphael Bartolomé
5 March 2008 @ 10am

Hi Matt,
great API!! I have implement it in my Teatimer.
It works like magic, awesome …

Thank you!


Tim Burks
5 March 2008 @ 2pm

Hi Matt,

You might enjoy scripting MGTwitterEngine with Nu:
http://blog.neontology.com/posts/2008/03/04/twitter-and-nu


Lachie Cox
10 April 2008 @ 11pm

Hey this is awesome!

I’m having trouble getting the User timeline, using:
[twitterEngine getUserTimelineFor:nil since:nil count:0];
creates the url:
https://lachie:XXXX@twitter.com/statuses/user_timeline.xml

This works when I plug it into curl, but using Twitter Engine I get a 401 Unauthorized

any ideas? I’m about to get wireshark onto it…
thanks again for the code
Lachie


Lachie Cox
10 April 2008 @ 11pm

Examining the http dialogue in wireshark shows that the credentials are being dropped from the url
http://lachie:XXXX@twitter.com/statuses/user_timeline.xml
User-Agent is CFNetwork/221.5
I’ll try to patch it if I can :)

I’m on 10.5.2 with the xcode etc from the first iphone beta (though not compiling for the iphone).


Matt Legend Gemmell
11 April 2008 @ 8am

Hi Lachie,

Looks like it’s an issue on Twitter’s side. MGTwitterEngine does send the auth details as normal, but there’s something weird going on with that particular URL. You can easily work around it by doing this instead:

[twitterEngine getUserTimelineFor:username since:nil count:0];

(i.e. just pass the authenticated user’s username as the first parameter.)


Leave a Comment

Irate about User Interface Skinnable Cocoa UI with WebKit and CSS