Archive for the ‘Cocoa’ Category

YAJL JSON Parser (Objective-C Bindings)

Monday, June 15th, 2009

I recently was investigating using a more lightweight JSON parser for iPhone projects (other than the standard SBJSON library) and came across the YAJL C JSON library. While using it as a document style parser didn’t result in a huge performance gain, it does a support a streaming “SAX” style parser which might help memory usage in larger documents.

Hopefully, sometime soon I will do some performance comparisons. In the meantime, if you try these bindings, let me know how it goes. You can find it on github at: http://github.com/gabriel/yajl-objc.

Right now, I only have a framework (for 10.5) built, but check back and at some point will have a static iPhone library built as well.

Here are some quick usage examples:

Usage

Usage (Streaming)

Usage (Document style)

Updated (07/01/2009): Updated usage to use new API changes for better streaming support.

Invoking forward

Friday, May 22nd, 2009

Typically when you want to invoke methods on a separate thread, with a delay, back on the main thread after a long operation, etc,  you are stuck with the performSelector:onThread: methods. With performSelector you are limited to invoking with a limited number of arguments, which must be objects; it won’t auto-unbox NSValue/NSNumber/NSNull like key value coding does.

This limitation can be really frustrating, particularly when you are using NSOperation or threading in general and need your delegates to call back onto the main (UI) thread.

A possible solution is to use NSInvocation with performSelector to deal with multiple arguments and primitives, for example:

but it gets cumbersome, especially setting up the invocation instance. (BTW, the first argument is at index 2 because of the hidden arguments self and _cmd.) Also you would need to call retainArguments if your arguments were objects, that may be released by the calling thread.

Thankfully there is a better way. In a post called ‘Grab that Invocation‘ and later at Dave Dribbin’s post ‘Invoke on Main Thread‘ we can see how to get an NSInvocation instance from an NSProxy/forwardInvocation: automatically; and now we can combine the proxy with performSelector:onThread: or any of the other peformSelector methods to invoke back on the main thread, invoke on other threads, delay invocation, or other more general aspects like timing methods, debugging, logging, or security.

You can find Dave Dribbins original DDInvocationGrabber implementation in his DDFoundation library.

I’ve expanded on it a bit in GHKit, (see GHNSInvocationProxy) and plan on adding more features. If you use it with the GHNSObject+Invocation category, it gets even better:

This category also includes other performSelector helpers (supporting var args and argument lists).

What might be some other ways to use this? Maybe an NSOperationProxy that allows you to queue and prioritize invocations, or more complex debugging or analytics proxies that can keep stats of certain activities.

Unit Testing Framework & GUI for Mac OS X and iPhone (GHUnit)

Saturday, February 21st, 2009

I’ve always wondered why XCode doesn’t have a unit testing GUI like other IDEs, or why the SenTesting framework has to be such a pain to setup, with all its RunScript build phases, shell scripts, octest bundle insanity. After using the GTMTestCase for the iPhone (since SenTesting isn’t supported on the iPhone SDK) I decided to try to re-purpose some of the GTM Unit Testing code into a standalone testing framework and GUI that I could use on both my Mac OS X and iPhone projects.

GHUnit (pronounced \ˈgü-ˈnit\, I guess?), hosted at gabriel/gh-unit, is meant to be installed as a framework (or embedded in your project for iPhone apps), and run as an application in a separate Test target. The idea being that you can run and crash into the XCode debugger directly and utilize all the debugging techniques that you normally use. The test GUI should allow you to see test failures more clearly, view timings / stats and not have to go fishing for the build console window. And an automated way to view stack traces.

Details on how to use the framework are included in the README.

GHUnit Test GUI for Mac OS X App

GHUnit Test GUI for Mac OS X App

Unit Test GUI for iPhone App

Unit Test GUI for iPhone App

For the iPhone side, I included a similar GUI that runs the tests in the simulator. Though since frameworks are not supported on the iPhone SDK, you’ll have to embed it in your project, which is a little bit cumbersome. (Any ideas on how to make this easier?)

GHUnit can be used as a standalone test framework (by subclassing GHTestCase), or with your existing SenTestCase tests or GTMTestCase tests.

So far its pretty basic, but I am using it on a couple projects and its been helping my development a bunch and letting me to write tests as I go without completely destroying my workflow or sanity.

Any feedback is appreciated and let me know if you have any problems with the install/embed instructions or in general. Also thanks to the GTM peeps, on which much of this is based.

Maybe the next step is an XCode plugin?

Cocoa Utils Kit

Thursday, August 7th, 2008

I pushed my Objective-C utility kit to github: gh-kit. Its a collection of some files I’ve found, some I wrote for S3Hub. There isn’t a ton of stuff there. In fact, it probably needs to be merged into another utils framework or obsoleted completely by someone else (like google toolbox for mac). But until then, it has some useful stuff like:

And other stuff for generating uuids, mime types, etc. I blogged earlier about the date parsing and time ago in words.

Also, be sure to checkout the Google Toolbox For Mac which is way comprehensive (definately check there first). Feel free to pick and choose stuff at will. All files from other sources should have their original licenses which should all be MIT-like.

PS, sorry about the crazy feed crossing before. If you want to switch to a “cleaner” feed you can use this url: feeds.feedburner.com/gabrielh. Google reader caches the feed entries on the other one, so those will likely live forever.

Date format RFC822/850/1036/1123; asctime; ISO8601; Unicode#35(tr35-6); *#$*&!

Tuesday, July 22nd, 2008

I had to deal with handling of various date formats for S3Hub and totally munged it the first couple passes. This post lists some things to be aware of when parsing and formatting HTTP and XML style dates correctly using the Cocoa API’s.

HTTP Date

Some quick background on HTTP dates first. S3 requires sending a ‘Date’ header field as part of an authenticated request. (This and signing the request is a common countermeasure against a replay attack.) The spec says, the format of the date should be “one of the RFC 2616 formats (http://www.ietf.org/rfc/rfc2616.txt)”.

HTTP applications have historically allowed three different formats
for the representation of date/time stamps:

Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C’s asctime() format

The first format is preferred as an Internet standard and represents
a fixed-length subset of that defined by RFC 1123 [8] (an update to
RFC 822 [9]). The second format is in common use, but is based on the
obsolete RFC 850 [12] date format and lacks a four-digit year.
HTTP/1.1 clients and servers that parse the date value MUST accept
all three formats (for compatibility with HTTP/1.0), though they MUST
only generate the RFC 1123 format for representing HTTP-date values
in header fields. See section 19.3 for further information.

So these are the standard formats. When sending a formatted date you should only use RFC1123 but should be able to handle any of the formats listed. This is just a way to maintain compatibility while trying to move everything to the latest format. If you are wondering what the difference is, RFC 1123 updated 822 by changing the time zone from hour format (±0000) to GMT format (GMT).

For example, the ‘Date’ or ‘Expires’ header fields for requests have this (RFC1123) format. Replies might have an HTTP date format in a Last-Modified or Date header as well.

ISO Date

XML data which has formatted date fields might use a date format which is defined by the ISO8601 standard and looks like ‘2006-02-03T16:45:09.000Z’.

Date parsing in Cocoa

Prior to 10.4, the Cocoa API supported “strftime-style conversion specifiers”. In 10.4, they added support for the Unicode Technical Standard #35 (version tr35-6).

The pre-10.4 strftime patterns look like: “%m/%d/%y” and the Unicode standard looks like “MM/dd/yyyy”. The default behavior (for backwards compatibility) is strftime format. In order to use the Unicode standard (which you will, its way better), you need to set the formatter behavior to NSDateFormatterBehavior10_4 either by calling setFormatterBehavior or setting the classes formatter behavior globally. Do NOT use the initWithDateFormat:allowNaturalLanguage: constructor, because it will give you a pre-10.4 date formatter. Using the strftime style of pattern when configured for the 10.4 (Unicode) behavior will fail silently.

So fast forward a few weeks, an S3Hub user told me he was getting authentication errors (invalid signing) trying to connect. I couldn’t replicate the problem but I eventually got the raw HTTP request header it was sending and the Date header looked like.

Fr, 06 Jun 2008 08:49:37 GMT.

Turns out the user is in Germany and when I change my locale to something German, I can reproduce the problem. Date formatters themselves can have specific styles (and symbols) that are modified by the locale. In the German locale the weekday symbol for friday is ‘Fr’ instead of English locale which is ‘Fri’. So when you use a date formatter in this way (with day or month symbols, for example) make sure to set the locale to en_US. The final date formatter looks like:

Update: See GHNSDate+Parsing gh-kit category on github for a collection of these date formatters.

S3Hub: S3 Client for Mac OS X

Monday, June 16th, 2008

I’ve been looking for an Amazon S3 client for the Mac for awhile, that had a couple key features that seem to be missing from apps like Cyberduck or Transmit. Mostly I wanted a better way to manage permissions and make it easier to share files with my friends, and I needed something to throttle my bandwidth so I can leave beefier transfers running without nuking my Gears of War latency.

S3Hub (left)

You can download it over at: http://s3hub.com

And, also, its an excuse to do some Cocoa again now that Objective-C 2.0 is out. Garbage collection, declarative properties, and fast enumeration help remove a lot of cruft and let you focus more on making things work. Also there are alot of new and really nice API’s in Leopard like NSOperationQueue.

S3Hub (right)

A major feature I don’t have yet is sync’ing (syncing is hard); but I think that should come in the next version hopefully. I have some ideas about generating rss feeds or some way to track new files which I think could be really useful. If you have any ideas or find any bugs, leave a post on the group.

Time ago in words for Cocoa

Monday, June 9th, 2008

I ported the time_ago_in_words helper for to a category (mixin) for NSString. Its nothing profound but I couldn’t find it anywhere.

Update: Moved to github and is part of GHKit. You can find this helper: GHNSString+TimeInterval.m

Fix for XCode unit test error (exited abnormally with code 127)

Wednesday, April 23rd, 2008

If you are getting the:

Test host '/path/to/App exited abnormally with code 127 (it may have crashed).'

error in XCode 3.1 (beta) when you try to run your unit tests then you need to:

  1. Get Info for the Unit Tests target.
  2. Choose the Build tab.
  3. Set the Architectures value to Native Architecture of Build Machine.