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.
Give it a shot and see what you think – you can grab the code from my public subversion repository at svn.cocoasourcecode.com. Maybe you could make the next Twitterrific?
Update: Since I made this post, MGTwitterEngine has been updated several times, so be sure to read on for more details. It will now build for iPhone too (using the official SDK), and there’s also 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.
(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: MGTwitterEngine can now be built for iPhone, using the official SDK from Apple.
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.


[...] MGTwitterEngine: an awesome objective-c wrapper for twitter api which we based our api on. [...]
[...] MGTwitterEngine: an awesome objective-c wrapper for twitter api which we based our api on. [...]
Hi Matt and first of all thank you for the wonderful framework. I’m using it for an iPhone project and I just found out that while using the search API in: MGTwitterEngine.m:1563 there’s the following line:
return [self getSearchResultsForQuery:query sinceID:sinceID startingAtPage:0 count:0 geocode:nil]; // zero means default
I just changed it to:
return [self getSearchResultsForQuery:query sinceID:sinceID startingAtPage:page count:count geocode:nil]; // zero means default
so that it actually uses the page and count arguments passed to it. I’m not sure wether it was wanted or just a copy/paste error!
Regards,
~C
How can I place a link in an app so that people can retweet it? e.g. RT “Check out this app” they click thru in safari and submit the status update from their twitter account.
Hello,
First of all thank you so much for this engine it does work great. However the Leaks instruments shows a lot of leaks once a request is send to Twitter. The problem appears to be with the NSURLConnection and the Libxmlparser. The leaks are consistent and happen every time a request is send. Am I downloading the wrong code?. I see in update 3 that you fixed a small memory leak was this it?.
Which code is the latest code in the svn repository?
MGTwitterEngine or MGTwitternEngine1.0.8?
Thank you in advance.
-oscar
I forgot to add I am using MGTwitterEngine1.0.8
Hi,
Oscar did you solve memory leak problem, i am facing same problem,
-Flyer
Is it possible to give a .zip file for download?
Do you need a framework for this?
NOTE: Twitter ids are bigger than what an NSInteger can represent. :markUpdate should be changed as follows
markUpdate:(NSString*)updateID asFavorite:(BOOL)flag
Follow on: pretty much all methods in MGTwitter using “updateID” should switch to NSString.
Hope this helps other developers, I just spent 1/2 hour thinking that [NSString integerValue] did not work! In reality the problem is that the ID numbers are bigger than what NSInteger can hold so you always get max_int…
Does someone know how to use the sinceID option? I’m having a lot of trouble with the int, unsigned long long and I can’t get it to work. Thanks
Flyer: I haven’t been able to solve it, have you?
2Stefano:
That’s generally a bad idea. Integer numerical values are not supposed to be stored as strings.
You can (and probably should) use (unsigned) long long type.
I have updated Matt’s code to use unsigned long long as the type for status IDs, see http://github.com/freeatnet/MGTwitterEngine. Unsigned long long maximum value is about 19 billion, so, I hope, this fix will last for some time.
Are there any plans to reintegrate the github unsigned long long fix with Matt’s svn repo? Seems less than ideal to fork the project for any longer than necessary.
[...] MGTwitterEngine: an awesome objective-c wrapper for twitter api which we based our api on. [...]
Thanks for you work, but i met some problems to use it.
I met some problems during the compilation:
libxml/xmlreader.h no such file
Follow this steps to correct it:
http://www.ashlux.com/wordpress/2009/10/04/compiling-mgtwitterengine-for-the-iphone-using-xcode/
then another error occured…
yajl/yajl_parse.h no such file
Follow this steps too:
http://damienh.org/2009/06/20/setting-up-mgtwitterengine-with-yajl-106-for-iphone-development/
The i wanted to use the location support of twitter, but the method was noted has “TODO” :-)
So i have create it (works fine). Can you tell me how can i upload it to your website? i’ve create it has a Category.
Thanks for the engine. When I bring up the login page and click Sign Up, I’m redirected to another login page and don’t have an account creation option. Anyone else experiencing this?
[...] I've also found someone who has done a lot of the work I would need to do and more in the sourcecode from http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa. [...]
[...] Twitter support using MGTwitterEngin… Add Twitter support using MGTwitterEngine http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa [...]
Thank you for posting this. Was scratching my head for hours trying to figure this out.
Is the shouldn’t-be-integer ID-number-problem resolved?.. and if so how?
I’ve tried doing this:
unsigned long long myULL = 7537088163;
NSLog(@”getFollowedTimelineSinceID: connectionIdentifier = %@”,
[twitterEngine getFollowedTimelineSinceID:myULL startingAtPage:0 count:0]);
But the delegation method statusesReceived is showing me an NSArray with message ids predating that ID (as seen in the Console thanks to the NSLogging).
Please note that I *HAVE* tried
modifying MGTwitterLibXMLParser.m:164
to become
return [NSNumber numberWithLongLong:[intString longLongValue]];
but no joy.
Please help! (And ’scuze the newbie-itude please!)
I forgot to mention that YES I did try Stefano’s colution from Nov 23 (switching all methods in MGTwitter using “updateID” to use NSString)…
and then,.. I tried Arseniy’s solution (from Nov 27) to use unsigned long long’s.
No dice.. the [twitterEngine getFollowedTimelineSinceID:7537088163 startingAtPage:0 count:0]);
is showing all IDS from 7534588382 to 7538912965.
;-(
One problem I can see with Arseniy’s solution is the unsigned long longs are being converted to string with the specifier “%u” — this should be “%qu”.
I’m looking at – getUserTimelineFor:sinceID:withMaximumID:startingAtPage:count:(int)count but there are probably other cases too. I’ll have a look through the rest of the source.
I’ve also made some fixes for 64-bit Cocoa. I’ll email Matt when I’ve fixed and tested the format specifiers.
I take that back – I was looking at the wrong checkout [headdesk].
Shawn, try giving the ID as 7537088163ULL. That should work.
[...] More details on: http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa [...]
[...] made a decision to add Twitter support to our iPhone application. We did choose MGTwitterEngine. It saves a lot of time, but it doesn’t support geotag for tweets. If you do need to geotag [...]
Could it be possible that the deleteUpdate-methode doesn’t work anymore? All other methodes are working, but not the deleteUpdate, also not in your sample app. When I give the methode a number, the finaleURL gets a other number. Is it right that the id, that I get with getFollowedTimeLineSinceID is the id to give the deleteUpdate-methode? So for example I get as ID 7988450547 and I know that this Tweet is a own tweet. The finalUrl looks something like that: finalURL = https://twitter.com/statuses/destroy/3693483251.xml – Also the NSLog writes this error: error = Operation could not be completed. (HTTP error 403.) ((null))
Why? Thanks for your help and sorry for my bad English, I´m a student from Germany ;)
I want to report a problem with encoding of passwords.
Inside MGTwitterEngine.m you use NSASCIIStringEncoding for converting the password string to an NSData object. That’s wrong; the twitter API expects the encoding to be UTF8.
Since the ASCII is subset of UTF8, the ASCII encoding will still work properly as long as your password does only contain pure ASCII characters (<128).
But if not (e.g. if your password was 'Mätt'), the conversion will not work, authData will be nil.
You can solve this issue by simply changing the encoding to NSUTF8StringEncoding
one more minor issue:
the MGTwitterXMLParser is using the selector dateWithNaturalLanguageString: which is marked as deprecated.
Currently you might only get a compiler warning for that, but I think in future that method should be replaced using a NSDateFormatter
… but all in all the whole thing is working pretty fine.
Nice work!
[...] MGTwitterEngine – Twitter from Cocoa » Matt Legend Gemmell 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. (tags: twitter objective-c objectivec iphone development code libraries) [...]
As an addition to Christian’s previous comment about the deprecated NSDate method, it is pretty straightforward to use an NSDateFormatter instead.
I added the date formatter as a member on the class and initialised it with the following in -initWithXML…:
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:kMGTwitterDateFormatString];
The kMGTwitterDateFormatString is defined at the top of the implementation as:
#define kMGTwitterDateFormatString @”EEE MMM dd HH:mm:ss ZZZ yyyy”
and the call to NSDate’s -dateWithNaturalLanguageString: can be replaced with a call to the dateFormatter’s -dateFromString: as so:
[dateFormatter dateFromString:[currentNode objectForKey:elementName]];
Now it should work without the compiler warning. Just don’t forget to add a [dateFormatter release] to -dealloc.
This is excellent!
I’ve been having one major problem however. I’ve gotten this running on the iPad simulator, and most of the time I’m able to log tweets with no problem, but sometimes my app crashes just after it’s launched with the following error:
2010-02-06 21:26:14.136 TwitterApp[72383:207] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil’
I’ve searched through all of the source, but have found no “NSCFArray”. Has anyone had gotten this running on the iPad simulator? All I’ve done is implement the delegate methods in my View Controller, I basically copied and pasted the code from the provided Mac app controller and just removed a few small parts that were iPhoneOS incompatible. Could this possibly be an iPad specific problem? Is NSCFArray actually used somewhere but I’m just missing it?
Thanks!
NSCFArray is just a regular NSArray (it’s NSCFArray because of toll-free bridging between Foundation and Core Foundation).
This exception is being thrown because code somewhere is trying to add a nil object to an NSMutableArray. Your best chance of finding this is running the app with breakpoints on (Build and Debug), which will cause Xcode to stop an show you a stack trace.
Ok, thanks for the explanation. I think this is only occurring when it failed to fetch new tweets. A workaround shouldn’t be hard.
[...] Matt “The Legend” Gemmell. Heard so many great things about him and even delved in the MGTwitterEngine code just to see if I would understand [...]
Hi
Your twitter cocoa code has been working flawless until right now. Now when doing the same calls (and also in my existing apps) all of the sudden Twitter gives me a pin code on screen and no way to close the screen :/
Any idea as to what is going on and how to fix it?
Thanks!
after searching all over I found the solution
seems this:
document.getElementById(‘oauth_pin’).innerHTML
needs to be changed in:
document.getElementById(‘oauth-pin’).innerHTML
(replace the underscore with a dash)
:/
[...] best twitter engine in the street right now and available to everyone is the MGTwitterEngine developed by Matt [...]
[...] trying to use Twitter framework under iPhone I managed to get rid of all errors, but only one warning remained: NSDate may not [...]
[...] in the usual suspects, as autocomplete names. Right now It’s almost finished (thanks to the MGTwitterEngine) but it’s missing things like short URLs, upload to image sites or support for [...]
When do you think OAuth support will be ready?
I found a lingering issue where the LibXML implementation truncates status IDs etc to 32-bit. The culprit is MGTwitterLibXMLParser _nodeValueAsInt.
I changed the last line to:
return [NSNumber numberWithLongLong:[intString longLongValue]];
since unfortunately NSString doesn’t have a -unsignedLongLongValue.
[...] Social network APIs for Iphone Here are the APIs used to with the main social network: * myspace : http://code.google.com/p/myspaceid-iphone-sdk/ * facebook : http://wiki.developers.facebook.com/index.php/Facebook_Connect_for_iPhone * linkedin : http://developer.linkedin.com/community/apis * twitter : http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa [...]
[...] choose to use the MGTwitterEngine (http://mattgemmell.com/2008/02/22/mgtwitterengine-twitter-from-cocoa). In order to make it work, you’ll need to install the framework libxml2 and to add yacl from [...]
[...] you have the xAuth access token, you can simply use the XAuthTwitterEngine like MGTwitterEngine (since it's basically Isaiah's oAuth-aware version of the MGTwitterEngine [...]
[...] Twitter, buah karya Matt Gemmell, lihat blog nya, di sana juga terdapat UI yang sangat menarik dan [...]
There seems to be no support for international letters such as äåö in the user password in MGTwitterEngine.
Swedish users with theses signs in their password can not log in to Twitterrific.