There are so many ways to encode and decode data structures just to send them over a network. Some favor XML, some JSON, some Hessian, some ProtocolBuffers.
But as I pretty much use macs for most private development I started to wonder if I just could use
NSKeyedUnarchiver for iPhone to Mac communication. My private development projects are mostly aimed at prototyping and not actually implement production level things. (wish more hosting companies would offer macs though)
So, how would I do a simple
NSKeyedUnarchiver wrapper for some iPhone to Mac communication? I’d like to write as little socket communication as possible. On the iPhone there is a great HTTP framework called ASIHTTPRequest which makes it very easy to bundle a bunch of data that can be sent over HTTP. If you haven’t tried it yet, you really should. You can find it here: ASIHTTPRequest
How about the server side then? Now days all new macs come with apache2 and php installed. None of these can decode and encode plist files (which is the fileformat used by
NSKeyed...), but hey, that shouldn’t stop me. It’s pretty easy to let php call a native command line program which could be the actual “server”. Said and done. Today I put these pieces together. It came down to three parts, an iPhone app using ASIHTTPRequest, a small php script, and a small command line program.
You can grab the project files at github
Place the keyed.php file in your
~/Sites folder. If you open Safari to that location
http://localhost/~username/keyed.php you should get a Intentionally left blank message. Compile the
KeyedServer command line program and place it also in this folder. Compile the iPhone app, you should get an error where the server address should be entered. Remove the error and enter an address for your setup. Compile again and run. Enter a name and press
So, what are happening? On the iPhone a
NSKeyedArchiver is used to build the message that will be sent. Source
NSMutableData *data = [NSMutableData data]; NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [arch encodeObject:nameField.text forKey:@"name"]; [arch encodeFloat:value1Slider.value forKey:@"v1"]; [arch encodeInt:value2Slider.value forKey:@"v2"]; [arch finishEncoding];
keyed.php script receives the plist data and a md5 checksum. If a plist file is present and the checksum is correct the
KeyedServer program is run and feed with the path to the plist file. The message is decomposed as below. Source
NSData *rdata = [NSData dataWithContentsOfFile: [NSString stringWithCString:argv encoding:NSUTF8StringEncoding]]; NSKeyedUnarchiver *unarch = [[NSKeyedUnarchiver alloc] initForReadingWithData:rdata]; NSString *name = [unarch decodeObjectForKey:@"name"]; float v1 = [unarch decodeFloatForKey:@"v1"]; int v2 = [unarch decodeIntForKey:@"v2"]; [unarch finishDecoding];
The server also returns a plist created in the same way. Here it just creates a greeting and a sum from the received items.
This worked quite well I think. Now I’ll try to implement the iPhone app that actually spur this idea.
KISS means Keep It Simple and Stupid