Archive for the ‘Cocoa’ Category

Efficiency Over Elegance

What do you use when you want a server to communicate with a client over TCP? Some people would tell you to use HTTP. Some people would write their own binary protocol. A friend of mine is actively developing an IM client which communicates with a server using JSON. Unfortunately, some of this data needs to be raw binary, such as buddy icons, etc. Along with that, he uses JSON-framework for encoding and decoding.

JSON (JavaScript Object Notation), is a lightweight, human-readable way of representing dictionaries, arrays, strings, and numbers. For instance, a dictionary containing a single key might look something like this: ["myKey":999999]. You may immediately notice that the data could be smaller. There are two bytes already taken for the open and close brackets. Another two taken by the quotation marks. A few wasted bytes where a four-byte binary integer could be used to represent the number 999999. To some, this is fairly irrelevant. But consider the same amount of overhead for a very large amount of data. A more efficient binary storage method would be nice, and very handy to many.

I created a project called KeyedBits, a binary archive format. First I started off by writing a very simply Objective-C encoder and decoder that I called KBKit, which used some fancy object orientation to achieve its goal. Unfortunately, benchmarking this implementation gave unpromising results. Although it appears that KeyedBits saves an average of around 13%, KBKit was almost two times slower than JSON-framework. My natural reaction was not to optimize my Objective-C implementation, but to write another one in C.

I had already sacrificed the elegance and beauty of JSON, instead using a rather ugly binary format that only looks good when viewed in a hex editor. Now, I had to sacrifice the elegance of KBKit and instead write a C framework. For lack of a better name, I decided to call this C framework KBCKit.

It turns out that encoding was neck-and-neck between JSON-framework and KBKit. The real tie breaker was decoding. After I implemented both the encoder and decoder for KBCKit, and had written an Objective-C wrapper for each, I found that I was successful. KBCKit now is able to encode and decode almost twice as fast as JSON-framework. This, on top of the fact that there’s little overhead, makes KeyedBits a great alternative to JSON in Objective-C applications.

The lesson to be learned here is that sometimes beauty is not better than efficiency. Sure, my C implementation isn’t as fancy as my Objective-C implementation, but it certainly has a better end result. There are times when it’s okay to use a high-level language, but there are also times when it’s simply not appropriate. Imagine if the Linux kernel had been written in C++ instead of C. It would probably be a lot easier on the eyes, but ultimately easy on the eyes isn’t its purpose. Things like kernels, video decoders, and KBCKit were made to be used, not drawn on paper and hung in an art museum. The user doesn’t care how elegant the code is, they just want something with raw speed and power.

Writing My Own IM Protocol

These past few months have been quite enlightening to me. I have learned much about OSCAR, and Jabber, two IM protocols used every day. After learning about these protocols, I have come to the conclusion that there needs to be a new IM protocol. This is why I decided to write the JIMP protocol, which emphasizes ease-of-use for the developer.

The name “JIMP” stands for Jitsik Instant Messaging Protocol. Before I started working on either the server or the client, I made a pretty good outline of what I want the protocol to be like, and posted it here: JIMP Protocol. Once I had the protocol outlined, I started to work on a client and a server.

Since I wanted to try something different for this project, I am creating the server entirely in Java. This will allow it to run on any platform that I please, and makes the development very smooth and easy. I am writing the first client in Objective-C for Mac OS X. This client so far allows sign-up, login, and is well on its way to displaying the buddy list. I am developing the server and the client simultaneously, which is actually good since I can make changes to either one if I need to.

Once I am finished with the basic client and the server, I am going to spiffy up the client, and release it to the Mac App Store. Since the App Store allows anybody to stumble upon your app, I hope that one or two people will try out the client, and tell their friends. After I release the Mac app, I am probably going to work on a libpurple plug-in for the protocol, and release a Pidgin plug-in for it.

Date Formatting in Objective-C

As you may know, I am making an RSS app for the mac, and have already posted the code to github. Well, one of the most important parts of any type of news is the date that it occurred. You don’t want to hear news that seems urgent, but then find out that it is a month old, do you? In making my RSS app support date/time for all RSS feeds, I had to deal with several different date formats.

Since I am making this app for Mac OS X, I am using the Cocoa framework for almost everything. This means that I am using NSDateFormatter to turn a text string into a date object. You can see the documentation for NSDateFormatter here, but it does not include information about how date format strings should be constructed. This means that I had to figure it out myself.

As it so happens, apple does not use the ISO standard for date formatting. Instead, NSDateFormatter formats dates using something called TR35. That is how I finally figured out how to format dates. I easily constructed code to turn a string (that uses the standard RSS date format) into a valid NSDate object. The following code will successfully turn a date such as Sat, 11 Dec 2010 17:16:16 EST into an object that we can work with:

NSString * dateString = [information stringValue];
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"E, dd LLL yyyy HH:mm:ss zzzz"];
self.postDate = [formatter dateFromString:dateString];

One might think that date formatting on the iPhone would be similar to that in PHP, using the date(2) function, but it is actually quite different. I wish apple had made date formatting more clear in their documentation, but I guess they didn’t bother with it since the spec is online anyway.

SQlite3 and Objective-C

This thing can save all your data quickly and efficiently, but just as fast can be hacked and injected with bogus code.  This thing is sql, and everyone who has to store information swiftly uses it.  On the iPhone apple provides you with the SQlite3 library, a small C based sql database, which uses files to store information.

My question is, why would I want to use something written for C when I am programming in Objective-C for the iPhone?  And I found that there is no simple answer.  Since some of the apps that I have been working on recently use database software, I figured that I would take a look at SQlite, and try wrapping it in some Cocoa goodness.

Since SQlite is file based, opening, executing, and closing is fairly simple to do.  No backend server is required, and all of your code is written natively in C (excluding the SQL code that you are executing).  Since this is the case, it was fairly easy to write a lightweight wrapper that supports opening, executing, and parameterized queries.  Since I do not want to ramble on about code on this post, check out the code on git, as usual.

Using Google Translator as a Proxy

Today in school my friend showed me a practical proxy that has been sitting in front of my face for quite some time. Google Translator has an option to translate any webpage, and it actually fetches the page for you to do that. So my idea was to make an app that uses Google Translator to translate base64 web pages to a different language with the same alphabet, thus causing nothing to change.

As I made a simple objective-C class library to do this, I noticed suddenly that my requests stopped going through properly. It turns out that google will block your IP for certain features if it thinks you are auto-fetching their site in some way. Even though my IP is blocked from translating websites, I will post my existing code for anyone to read (if they want to). I have no idea if it works perfectly since I cannot test it, but I am hoping for the best. The code: GoogleTranslateFetcher.zip.  Here is a screenshot of what happens to google translator after a few requests made by my program:

Remote Cocoa Objects Over the Network

Sockets are a programmer’s worst nightmare. On Windows you have to use WinSock, and on Unix you use standard Unix sockets. But is there a simpler way? After making the Remote Draw app (which uses Unix C sockets) I wondered, “is there an easier way to do this?” The answer is something that is somewhat obvious. Foundation/Cocoa has a class structure of NSProxies and NSConnections.

In only a few lines of code, it is extremely easy to create a server and client that use an NSProxy and NSConnection to use the Objective-C messaging system over the network. I wrote a little sample program to demonstrate this. Here is the main code that is required to make this work:

Server
NSSocketPort * port = [[NSSocketPort alloc] initWithTCPPort:5901];
NSConnection * connection = [[NSConnection alloc] initWithReceivePort:port
sendPort:nil];
[connection setRootObject:myObject];
CFRunLoopRun();

Client
NSSocketPort * port = [[NSSocketPort alloc] initRemoteWithTCPPort:5901
host:@"127.0.0.1"];
NSConnection * connection = [[NSConnection alloc] initWithReceivePort:nil sendPort:port];
id remoteObjectProxy = [[connection rootProxy] retain];
[remoteObjectProxy setProtocolForProxy:@protocol(MyProtocol)];
[remoteObjectProxy print:@"Hello, world!"];
[remoteObjectProxy release];

And that’s all that one needs to do to make a simple networked application using Foundation or Cocoa!

Drawing Remote Beta Preview

Two days ago I started work on a simple app requested by my friend’s sister.  This app allows you to draw on your iPhone and instantly see the changes on your mac, and then save the changes on your mac into an image file and add it to a word document.  One might think this is a hard task, but with my knowledge of Cocoa and CoreGraphics, I managed to do it the basics in about 1 hour.

Two days ago (July 31) at about 1AM while you were sleeping, I was working on Drawing Remote for iPhone.  In about one hour I threw together a mac and iPhone app pair that work together seamlessly to allow you to draw on your mac, using your iDevice’s touch screen.

When the iPhone app is opened, a list of computers on your WiFi network hosting Drawing Remote servers will appear almost instantly.  When the user clicks on one, a message will pop up on the corresponding Mac, asking the user to accept or deny the connection.  If accepted, the iPhone will slide up a new view asking the user to “Draw Here”.  When that is done the drawing appears both on the iPhone and on the Mac simultaneously.

A demonstration of this simple Mac/iPhone app pair can be found here: http://www.youtube.com/watch?v=JyT_WYuh8c0, or viewed on our blog:

Return top