For a little less than a year, I've been writing code built atop Twitter, specifically Matt Gemmell's MGTwitterEngine. I've got a few things running on this code, which I've not talked about publicly (other than minor hints on Twitter), but have been well-received by the few people who have seen it. Still, these projects have needed to extend both MGTwitterEngine and related libraries to add functionality or fix bugs. I'll spend this blog post documenting some of those changes across the different projects.
MGTwitterEngine
Most of these changes were made to make the engine's behavior a bit more extensible. Here's the GitHub repository.
MGTwitterEngineIDis a typedef for unsigned long long values. Everywhere a user ID or tweet ID is returned, it will return one of these. You will want to check your existing Twitter code to make sure there are no potential Twitpocalypse-related problems, updating old data types to the newMGTwitterEngineID.- Subclasses of
MGTwitterEnginecan now override a new method,-_sendRequest:withRequestType:responseType:, if they want to use custom networking code (such as with anNSURLRequestqueue class). I use this to implement both Twitter's password authentication and OAuth, and decide at runtime which to use. - Added a
-connectionStarted:method toMGTwitterEngineDelegate, which can be used to update your UI. - Fixed a few bugs in the YAJL parser which crashed or parsed incorrectly.
Things I still need to do:
In my custom subclass ofUpdate: Thanks to Uli Kusterer, the dependency onMGTwitterEngine, I use a class I wrote calledTCDownload, which I'll talk about below. There are still a few references to it in myMGTwitterEngineclass; those should be fairly straightforward to remove.TCDownloadhas been removed. The changes have been merged from his fork into mine.- Add full support for Twitter lists. I have some basic Twitter list functionality working in a private subclass, but far from all of it. There are some problems with the YAJL parser that don't appear easily fixable with the stock
MGTwitterEngine(specifically, the API key for the list description is the same as the key for the user's bio, and these are overwriting each other internally). I'm going to look into replacing the manual parsers - Add full support for new-style retweets. Haven't started this yet.
- Add support for geolocation in incoming and outgoing tweets. Haven't started this yet.
yajl
I've forked yajl to support 64-bit tweet IDs, mainly by changing the callback methods and the string parser from strtol to strtoull. Here is the GitHub repository.
SSCore
This is a repository of scattered classes which serve various purposes. There are two classes which are relevant for our discussion, TCDownload and TCOAuthDownload. You will need the TCDownload class if you use the vanilla MGTwitterEngine fork, although I'll be removing those dependencies. Here is the GitHub repository
TCDownloadis a generic wrapper that encapsulates an HTTP request to the interwebs. It wraps NSURLRequest and NSURLConnection under the hood. It automatically queues request and gets callbacks on a background thread (although you can change either of these). I use it a few places inside myMGTwitterEnginefork, but removed most of those changes and put them in a subclass.TCOAuthDownloadis a subclass ofTCDownloadwhich accepts OAuth tokens and sends out requests with the correct headers. It relies on theOAuthConsumerframework, which I'll talk about below.
OAuthConsumer
This framework deals with OAuth. Twitter has officially announced that basic auth will be dead in June 2010, so getting on the OAuth bandwagon now is a good idea. Here's my fork of the OAuthConsumer framework on GitHub.
- Changed the signature code to use Common Crypto instead of the C libraries' HMAC APIs. This seems to work more consistently on both Mac and iPhone.
- Added a
-parseHTTPKey:value:method which is used to parse extended attributes in OAuth access tokens. Twitter uses this to pass some special metadata, like the username of the logged-in user. Subclasses ofOATokencan extend this to parse those tokens.
OAuthery
This isn't strictly a tool for doing Twitter development, but it can be handy when learning how to implement the OAuth login flow. I posted about it more back in January, and you can find the code and a prebuilt app over at GitHub.
Technical details of the upcoming Flash Player for Mac, wherein the Adobe team is switching to using Core Animation to do faster rendering of non-video Flash files. It's worth noting that the performance will only initially be seen in Safari on Mac OS X 10.6, as the plugin is fully Cocoa-ized now.
Also interesting to note is that Flash is still using the ancient QuickDraw APIs which have been deprecated for years.
I wish I had found this article months ago. In it, Chris Hanson demonstrates how to merge multiple model files into one contiguous model object at runtime. This can be useful in many situations, such as large models with lots of entities, and scattered models in separate plugins. Extremely informative.
The templates that ship with Xcode are not the greatest. Some of them are inconsistent and don't enforce good coding standards (e.g. missing a dealloc method). Other templates which would be useful just flat out don't exist (e.g. an NSOperation subclass, or a protocol header file). This project aims to supplement or replace the built-in templates for Xcode to speed up coding and improve the quality of code.
Coding Standard
All files will be processed by Xcode. The generated source files must produce consistent, readable, commented code. The code must have these characteristics:
- Each file must have a comment block at the top describing the file.
- Each class must implement its superclass' designated initializer and dealloc.
- Stub methods must be organized by their purpose, class or protocol. -- Each group must be organized by their class hierarchy, with protocol stubs following. -- Each group must be prefaced by a pragma mark naming the class or protocol the methods were implementing. -- Clusters of methods (such as relating to KVO) should be organized along the lines above, with a pragma mark.
- All method implementations should contain a method call to their super implementation if needed.
- All method implementations should contain a commented out stub line that will signify where to insert their code.
- All comments must be in the form of two slashes //, and none using the /* */ form. This will allow developers to comment out large blocks of code as needed.
Wish List
- Different people want different things in their template. For instance, someone may want to include an implementation of observeValue:... for every class. Would be nice to have a template generator application (yeah yeah, very meta) which would make templates customized to the developer.
Inactive
URL Shrink is a new OS X tool with a very simple purpose - converting URLs to shorter permalinks on various web services. As the internet has matured, and services like IM, IRC, and Twitter have forced us to write shorter messages, it was clear that a system was needed that was as ubiquitous as Quicksilver.
For now, the main service of URL Shrink is just converting a URL that is on the clipboard, although this will be expanding over time (including things like a system text service, a command line client, a Quicksilver plugin, etc.). To do this, there is a keyboard shortcut (option-shift-space) which will convert the URL in the background to a tiny URL using one of the services provided. If you've selected one as your favorite, it'll choose that one. For example, I'm personally partial to is.gd, so all the URLs that are processed by URL Shrink on my machine go through is.gd.
At a low level, URL Shrink is a system where multiple shrinking engines can be added. It was designed to be extremely easy for developers to write just a little bit of code to integrate with other web services, including private URL services. For information on that, see the project page below.
URL Shrink is licensed under the BSD license. I encourage its adoption within other applications; I'll be adding .framework and .a targets for building this into Mac and iPhone apps respectively. Indeed, the project was born out of the URL shrinking capacity of another app I'm working on.
Inactive