Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Tag: ipad (page 1 of 2)

Sending Protocol Buffer Messages from iOS to a Socket Server

In a previous blog post, I took a look at how to create an Akka socket server using Akka IO that would read incoming messages in the form of Google Protocol Buffers. The information on the wire was framed so that it contained the length of the protobuf message as well as a numeric identifier telling my server which protobuf message.

Using a Scala client was a decent way of debugging things to figure out if my server code worked properly, but my real goal was to be able to send messages from an iPhone or iPad application to the Akka socket server. I continued to use the zombie sighting message that I created for the Akka server and for my “ProtoPhone” sample from this blog post here.

Now what I need to do is write some code in Objective-C that will send the protobuf messages over TCP via socket streams to the Akka server. The following code is not production ready, it’s just a brute force way of making sure that it works. In a real-world scenario there would be much more error handling, I wouldn’t send bytes on the NSStream until I got the “space available” message, etc.

NSInputStream *inputStream;
    NSOutputStream *outputStream;

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 9999, &readStream, &writeStream);
    inputStream = (__bridge_transfer NSInputStream *)readStream;
    outputStream = (__bridge_transfer NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

   // [inputStream open];
    [outputStream open];

    // Flip bytes for network order prior to transmission
    uint32_t length = (uint32_t)htonl([_rawZombie length]);
    uint32_t messageType = (uint32_t)htonl(1);

    // Keeping track of bytes written for debug purposes...
    int bytesWritten;
    bytesWritten = [outputStream write:(uint8_t *)&length maxLength:4];
    NSLog(@"Wrote %d bytes to the stream", bytesWritten);
    bytesWritten = [outputStream write:(uint8_t *)&messageType maxLength:4];
    NSLog(@"Wrote %d bytes to the stream", bytesWritten);

    // Write contents of protobuf object serialized as string, loaded into NSData pointer
    bytesWritten = [outputStream write:(uint8_t *)[_rawZombie bytes] maxLength:[_rawZombie length]];
    NSLog(@"Wrote %d bytes to the stream", bytesWritten);

    [outputStream close];

This is pretty much all there is to it. As I mentioned, there’s some refactoring that needs to happen in order to deal with things like error handling and to better handle situations when I have to use multiple writes to send a single object (e.g. not enough space available on the stream), but you get the general idea.

I will be posting more on this as I go along, but for now, I am plenty happy with my shiny new toys of being able to communicate between an iOS client and an Akka server.

Why Apple GameCenter is Still Annoying for Developers

Ever since GameCenter and GameKit (the SDK for GameCenter) were made available for iOS and subsequently made available for OS X developers, there has been an explosion of new games on the market. Some of this is due to GameCenter, but most of this is due to the simple fact that the App Store is the single largest and cheapest supply channel to get games from developers to consumers.

One thing has always bothered me when developing with GameKit – your application must be configured in iTunes Connect before any of the GameCenter functionality is available. For those not all that familiar with the process of developing applications for iOS there are two stages of the development process. The first stage is where your application is registered on the iOS Developer Portal. This means creating an AppID, a provisioning profile, certificates, and the other information necessary to develop and test your application on a real device. Since Xcode 4, this process has been streamlined considerably and isn’t quite the nail-biting, hair-pulling source of agony it used to be. (Don’t get me wrong, though, it’s not all roses and perfume either).

The second stage, if you are to believe Apple’s documentation, tutorials, rhetoric, and propaganda, is the publication stage. It is during this stage that you go over to the iTunes Connect website and configure your application for publication. Here, you create a new app, which consists of picking an existing AppID, and then supplying multiple pages of information in a very intimidating, “this will go on your permanent record” kind of experience.

So, what’s wrong with these two stages and GameCenter? I’ll tell you – you can’t develop with GameKit until your application is in iTunes Connect. Developers, especially agile developers, like to fire up Xcode, get in there and start coding stuff up, poking around, molding the clay, as it were. They do not want things slowing them down, and ITC slows them down and, for many indie developers, has actually scared them off to the point where the developers skip GameCenter entirely and roll their own (not that rolling your own isn’t an idea without merit, but that’s a topic for another blog post).

What this boils down to is that if you’re going to create a GameCenter-enabled game for the iPhone, immediately after you create your empty scaffolding “hello world” application from a bare bones template, you have to perform the following steps:

  • Go to the iOS Developer Portal and create an AppID for your application (e.g. com.kotancode.AwesomeGameThatNobodyWillEverPlay)
  • If you want to test this on a device, you need to create and download a provisioning profile for that AppID. This isn’t all that big a deal, and is necessary with or without game kit programming.
  • Now the fun part: go to iTunes connect and supply bogus values for all of the following:
    • Name, AppID
    • Availability date – you probably want to set this for 1 year from now
    • Pricing tier
    • Version
    • Copyright
    • Primary and Secondary Categories
    • Answer 10 multiple choice questions on content used to determine the rating for the game.
    • Description
    • Keywords
    • Support, Marketing, Privacy Policy URLs
    • Your contact information
    • Review notes – this is where I typically put the phrase – “going through the motions of creating an ITC profile for my app just so I can get GameCenter to work. Don’t accept or review this application. If you get tired of seeing messages like this, maybe you should let GameKit devs develop their test versions without an ITC app.”
    • Supply a large app icon (no, I’m not kidding, and all these screenshots need to be in a specific PPI density and resolution)
    • Supply at least one 3.5-inch Retina screenshot
    • Supply at least one 4-inch Retina screenshot
    • Supply at least one iPad screenshot

Now, and only now, after you have supplied all this information and wasted your time by creating an ITC application (thankfully you can choose to upload your application later and don’t need to upload a fully running app first.. that would be even more ludicrous than this process), can you finally do a simple task such as obtain a pointer to an authenticated GKLocalPlayer object.

So here’s the bottom line: Want your game players to be part of Apple’s ecosystem of friends, leaderboards, badges, and get limited multiplayer (turn-based or real-time locally over bluetooth) with chat capabilities? Then you’re going to have to suck it up and jump through all of Apple’s hoops. For many, many developers, this initial crapshoot is worth it for what they get in return.

For other developers, even indie developers, who are going to be providing a backing infrastructure for their application anyway, creating a private store for badges, achievements, accomplishments, friends, and multiplayer may be the way to go.

All this frustration aside, if you already have placeholder screenshots (which can be solid color blocks), then the whole process probably takes 20 minutes to do, so you can get up and running in one night. My problem isn’t that this takes too long, it’s that it’s so annoying, and even at times difficult to decipher, that it turns off newbie developers who would otherwise want to play with GameCenter.

Details Released on Surface for Windows 8 Pro

According to Microsoft, here are some of the details that we’ve been waiting to find out regarding the Windows Surface Pro (Surface running Windows 8 Pro):

  • It looks, from a hardware and form factor point of view, just like a regular surface
  • It comes with a pen (stylus)
  • It will be running Windows 8 Pro, which means Windows RT is not a limiting factor sandbox anymore.
  • BitLocker for drive/data security (does anybody actually use this on their current Windows machine?)
  • Mini DisplayPort HD connection for extra displays
  • Full size USB 3.0 port
  • Up to 128GB of storage
  • Intel Core i5 Processor
  • Price point starting at $899
  • Due out in early 2013

So that’s what I know about the “Surface Pro” and its impending release early next year. They won’t be making the holiday season for 2012, but the “regular” (aka hamstrung, limited, WinRT version) Surface is all over the commercials and seems to have basically sponsored all of the NFL up through the Super Bowl, so no doubt many, many people will be getting a Surface for Christmas.

You can’t actually play with a Surface hands-on in any regular big box electronics store like Best Buy. Instead, you have to go to an actual Microsoft store. This is unfortunate, because I feel that the more people who actually get to touch, feel, and experience the Surface the more people are going to be impressed by it. The commercials don’t really do the device justice.

Time will tell if the Surface Pro lives up to expectations. Unfortunately, I’m still not going to buy one until I get a chance to play with it. $899 might not seem like much, but it’s a big chunk of change for a tablet-sized computer and I want to make sure I’m getting my money’s worth.

Using Attributed Strings in iOS6

The title of this blog post should read something like “Hallelujah!” or “It’s about freaking time!” because this feature is long, long, long overdue. Way back in iOS 3.2, Apple allowed the NSAttributedString class to creep into the iOS SDK from the main Mac tool kit. However, none of the UI controls contained any support for rendering these attributed strings.

So, if you wanted to write your own code that read through attributed strings and manually created the various subviews and view configurations necessary for rendering, you were welcome to do so. Of course, this was a colossal pain in the ass and only those people building applications whose sole source of income relied on the use of these things ever tried it.

Now, with iOS6, the pain is gone and we have built-in support for attributed strings. What does that mean? It means that I can create a multi-color piece of text and set it on a label rather than having to create one label for each color like I would normally have done in hackish fashion on previous versions of the SDK.

NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithString:@"ThisIsAttributed"];
[mutableString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,4)];
[mutableString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor]  range:NSMakeRange(5,2)];
[mutableString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(6,10)];

So what does this do? Well, it will produce an attributed string that has the word “This” in red, “is” in blue, and “Attributed” in green.

Instead of setting label text directly the way you’re used to doing with just label.text=@”foo” , now you use a new property called attributedText.

Try it out and enjoy your new freedom. The following are a list of the attributes that come with iOS 6 and attributed strings:

  • NSFontAttributeName – UIFont
  • NSParagraphStyleAttribute – NSParagraphStyle
  • NSForegroundColorAttributeName – UIColor
  • NSBackgroundColorAttributeName – UIColor
  • NSLigatureAttributeName – NSNumber ( 0 -no ligatures, 1 – default ligatures )
  • NSKernAttributeName – NSNumber (0 kerning disabled)
  • NSStrikeThroughStyleAttributeName – NSNumber
  • NSUnderlineStyleAttributeName – NSNumber
  • NSStrokeColorAttributeName – UIColor, default nil
  • NSStrokeWidthAttributeName – NSNumber
  • NSShadowAttributeName – NSShadow, nil default
  • NSVerticalGlyphFormAttributeName – NSNumber , 0 horizontal text, 1 vertical text

Initial thoughts on the new iPad

Yesterday I received an early birthday present, a white 32GB WiFi iPad 3. To give you some proper background, I have owned at least one of all generations of the iPhone except the current 4s (the “s” being for “Siri”). I have also owned a first-generation iPad and, until yesterday, my sole tablet device was an iPad 2. I love my iPad 2. I use it for nearly everything that I can and only resort to the laptop when I plan on doing many hours of writing or if I need to do some actual coding. In other words, you can pry my iPad from my cold, dead hands.

When the “shiny new” iPad was announced my first reaction was “meh”. I really wasn’t all that impressed. Sure, it had a shiny new retina display but the difficulty Apple has to overcome isn’t convincing people that an iPad is awesome, it’s convincing owners of an iPad 2 that an iPad 3 is awesome enough to warrant forking over what I believe is a flaming truckload of cash. While these things are awesome, the only reason I can even condone purchasing one for myself is that they are tax deductions for my freelance development business and technical writing.

Case in point – I wouldn’t buy it for myself, it had to be given to me as an early birthday present. So, is the hype on the iPad 3 worth it?

The first thing I noticed when I unboxed the new iPad is that it’s heavy. Typically you have to put new devices on a scale to notice the different in weight but, even just holding one iPad in either hand, it’s very obvious that the new iPad weighs a bit more. It’s not enough so that it’s going to stop me from using it but it does have a more noticeable heft to it.

The next thing I noticed was that when setting up the new iPad, it asked me if I wanted to enable dictation. Dictation? I’d never seen this option on the iPad 2 and I didn’t remember hearing about it in the rumor mill. As a writer, the idea of getting dictation services on my iPad is pretty appealing. While dictation is there, iPad 3 has no “Siri” on it, which is fine by me. In another blog post, I will post a review of the dictation ability from an author’s point of view rather than just someone wanting to dictate an e-mail message.

Everyone raves about the new horsepower of the device – it has a better processor in it with more cores blah blah… For most applications that I tried I couldn’t tell the difference between how they ran on the iPad 2 and how they ran on the new device. The only ones that showed noticeable differences were the higher-end apps like 3d games and video streaming apps. A large portion of what I use my iPad for is watching video so this is a good thing for me. I’ve actually seen some videos of people doing speed tests where the iPad 2 comes out ahead in most situations. My experience is that the 3 has a much better display and is no slower, and visibly faster in video rendering, so that’s a plus.

All in all I’m really happy with the device and can’t wait to try out the dictation feature – of course you can’t use dictation on a train or a plane without annoying your neighbors so I wonder about where I might be able to use it. Is the new iPad 3 worth all the hype? Maybe, it’s an upgrade but a minor one. Is it worth the money? I don’t think so, but that hasn’t stopped me from owning it 🙂

iOS and Mac OS X Convergence Continues with Mountain Lion

Just the other day, Apple announced the major features coming up in their new operating system release, Mac OS X Mountain Lion. Before going into details on Mountain Lion, it’s worth remembering here that less than a year ago, Apple released Lion, which included a host of features that it borrowed from the iPad, including Popovers, the option to use “natural” scrolling the way you do on the iPad, iOS-style invisible scroll bars, iCloud support, full-screen applications, and even some great new enhancements for developers using Objective-C.

So what is Apple planning to do with Mac OS X Mountain Lion? According to the information I can find publicly, here are some of the highlights:

  • Game Center – Apple’s game service that provides everything from matchmaking to leader boards, achievements, and even in-game multiplayer voice chat is coming to the Mac. This also means that developers writing games for the Mac will be able to participate in all that amazing goodness that iOS developers have been enjoying since iOS 4.1.
  • iCloud – I don’t really know all the details here only that iCloud is even more integrated into the OS now and I’m assuming the developer experience around iCloud is getting better. I’m actually hoping that experience gets better because writing iCloud code on Lion is a pain in the ass.
  • Sharing – More iOS goodness comes to the Mac with sharing “sheets”. Every application on Mountain Lion now gets a little sharing icon that uses sharing services, allowing you to share whatever you’re looking at in the application with your buddies via e-mail or whatever other services are registered on the Mac, including Twitter. I would imagine that it wouldn’t take much work, assuming the sharing APIs are good, to add other sharing targets like Facebook, Dropbox, LinkedIn, etc to your Mac – turning it into just as much of a social hub as your phone.
  • Twitter – Twitter is a first-class citizen on the Mac just like it became first-class on iOS 5. This means that Mountain Lion users can tweet from pretty much anywhere and using the “sharing” services, they can share pretty much whatever they’re working on in any application (that supports it) via Twitter. Not only is twitter a first-class citizen, but applications can send Tweets on behalf of their users without any extra work. Twitter appears to be accessible in API form to developers without them having to figure out which of the 10 open-source Objective-C twitter libraries they want to shoehorn into their app. This is fantastic news for developers and I hope we get similar integration possibilities with Facebook, Dropbox, etc via Sharing “sheet” APIs.
  • Notifications – In what looks to be very similar to the notification center on iOS 5, Apple now has a unified display of messages that are pertinent to the user, including IMs, iMessages (also now a fully integrated part of Mountain Lion), and application-level notifications. In classic Apple style, they are aiming to push popular 3rd parties out of this market with their 1st party offering. Applications like Growl may find it hard to compete with the unified interface, but time will tell how the 1st-vs-3rd party battles are settled.
  • Gatekeeper – Again I don’t know all the details, but this feature aims to make your application more secure and, more importantly, provides developers with a secure way of distributing verified, signed applications outside the app store. For most developers, the App Store is absolutely the best way to go. But for some applications, it makes no sense to put in the app store and many people don’t need Apple’s distribution channel and so aren’t comfortable sharing 30% of their profit with the company. Gatekeeper and Developer IDs and signing give developers a way of distributing applications that users can feel comfortable downloading, installing, and using.
  • 64-Bit – You simply cannot run Mountain Lion on a 32-bit machine. The kernel is 64-bit and an entire host of 32-bit “wrappers” are missing in Mountain Lion, further drawing a line in the sand against 32-bit apps. If only some other software giant whose name starts with M that makes an operating system would also draw a similar line. In words from one of my favorite movies of all time (Zombieland), “It’s time to nut up or shut up.”
  • SSO – In order to support seamless sharing and such, there appears to be some kind of single sign-on facility in OS X much like Windows has been allowing you to link your “LiveID” to your user account for quite some time … only with the Twitter integration I would imagine Apple’s SSO allows for more than just Apple ID storage.

All in all Mountain Lion is looking pretty promising. Again, there’s absolutely nothing groundbreaking in here, but starting with Lion and continuing with Mountain Lion, it appears that Mac developers are finally getting access to the same amount of lovin’ that the iOS developers have been enjoying since iOS 4.

Struggling with SSL and Cloud-Backed Mobile Applications

While it is still certainly very common for mobile developers to build applications that stand on their own and do not communicate with the Internet, every day more and more mobile applications are released that are what we used to call “Smart Clients”. These apps sit on your mobile device (and are not browser apps or browser-shell apps). They might store data locally as a cache or back-up mechanism but the bulk of the application’s information comes from the Internet or, if you’re really upping the buzzword quota, the Cloud.

Let’s say you’re building a recipe application for mobile devices. This app is designed to let people access their recipes from any location so long as they have network data access. When you start the app, it queries a cloud-hosted server for your recipes and probably does so using some kind of secure authentication mechanism. Based on how a lot of cloud service providers are working lately, it’s very realistic to assume we’re doing Basic HTTP authentication over SSL.

Now we get into the real benefit of putting the data in the cloud – cross-platform access. I decide to write a Windows Phone 7 app and an iOS app. They both talk to the same recipe database and I should be able to share data among them seamlessly. Why would I do this? Because many people own a non-Apple phone and an iPad. Additionally, families often share service accounts where different family members have different mobile devices. Think Evernote here – they have apps for Mac, Windows, iPhone, iPad, Android – all access your shared, cloud-hosted store of notes.

Here’s the rub, the sticky bits, the source of the last 3 nights of frustration for me: not all services provided in the cloud surface clean, valid SSL certificates.

What does that mean? It means that when you make HTTP requests over SSL from an SDK, you are at the mercy of the limitations of that SDK. For example, if I am writing a desktop or server application in .NET and I know that a cloud database I’m talking to has SSL certs that don’t match their host names, I just write code that looks like this to manually override the cert validation:

ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

I can put conditional logic in there to only let certain certificates from certain hosts go through, but you get the idea. Bottom line is I have some back-up plan where I can write code to counteract what most people consider “bad net citizenship” (SSL certs that trigger warnings or worse, fail outright).

What about with iOS? What happens if my iPhone application runs into a bad SSL certificate. Again, I should not have to write this kind of code, but it is possible. When you are picking your cloud service providers, I would add a lot of extra weight to providers whose data comes through on clean SSL certs.

Here’s the juicy part of the iOS code (part of an NSURLConnection delegate class) that manually overrides the SSL cert by responding to an authorization challenge:

- (BOOL)connection:(NSURLConnection *)connection
   canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    NSString *challenge = [protectionSpace challenge];
    if ([challenge isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        return YES;
    }
}

- (void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSURLCredential *credential = nil;
    NSURLProtectionSpace *protectionSpace;
    SecTrustRef trust;

    protectionSpace = [challenge protectionSpace];
    trust = [protectionSpace serverTrust];
    credential = [NSURLCredential credentialForTrust:trust];

    // say "yes" to everybody... Note, this is BAD
    [[challenge sender] useCredential:credential
          forAuthenticationChallenge:challenge];
}

Why do I say this is bad? Well, the whole point of an SSL certificate is to establish a secure connection between you and the remote server. If someone gets between you and the remote server (called a man-in-the-middle attack) they can do all kinds of nasty crap to your data and, because you’ve written the above code, they might be able to get away with it.

But let’s say that you’re willing to accept that risk and you plow on. So now you decide to write a Windows Phone 7 app that reads from the same cloud database. Your code fails because the SSL cert doesn’t match the host name (again, this is a really common problem when cloud hosts do things to support massive numbers of clients). Well, you just use the ServicePointManager class like you did with the desktop .NET app, right? Ooops. No, actually, you’re utterly screwed. No such class exists in the WP7 SDK. In fact, there is absolutely no way in WP7 to override the validation of SSL certificates. In short, if an SSL cert chain fails and your WP7 app is on the client side of it, your app will not be able to talk to the remote server.

Case in point: I’ve been doing some experimenting with hosting an instance of CouchDB on Cloudant as an add-on to an application hosted in AppHarbor. This is great and they give you a nice SSL URL with a username and password embedded so that you can do awesome JSON goodness with CouchDB’s HTTP API. However. The certs from Cloudant fail validation on both iOS and WP7. About the only place it doesn’t fail validation is when using curl from the command line. If you’re using iOS you’ll be forced to hack around the SSL cert validation. If you’re using WP7, you’ll be totally boned.

So, what are the key points I want you to take away from this blog?

  1. If you’re using WP7, complain and never stop complaining until the folks at Microsoft catch up to all the other mobile operating systems and actually give us the ability to intercept auth challenges in the cert chain. Not having the ability to override SSL validation in a WP7 app is assinine. I realize that MS wants us all to be secure, but for the love of all that is good, even Apple allowed us to have this ability, and they are notoriously paranoid about mobile security.
  2. E-mail, phone, or smoke-signal the provider of your cloud service and complain that their SSL certs aren’t good enough. Many of them will have a facility that will let you use your own certificate purchased from one of the authorities on both Microsoft and Apple’s root authority whitelist, but that won’t fix the host name problem. If you are comparing two providers (e.g. two hosts of CouchDB) and one has certs that fail and the other doesn’t, definitely give more weight to the one with good certs.

Again, this is not a pandemic or a problem that affects the entire universe. This problem only occurs when you’re trying to access resources over SSL from mobile devices and the SSL certificate fails validation. This validation failure happens a lot when hosts do creative things with their certificates and their host names. If this applies to your host, give them a call or an e-mail and see if they have workarounds available. The last thing you want to do is write your own proxy to compensate for bad certs, because that’s just going to make the gap between your proxy and the cloud host as vulnerable to MITM attacks as your mobile device would be without the proxy.

So, go forth and consume cloud resources over SSL – just make sure your mobile SDK can override bad certs or your cloud provider has ways of making the certs look valid.

Praise the Lord and Pass the Ketchup: Automatic Reference Counting in Objective-C

Before I get to the post, let me drop this disclaimer: There is nothing in this post that violates NDA. I took all of the information for this post from the following documentation found online on the LLVM compiler’s website: Objective-C Automatic Reference Counting.

With the legal hoo-ha out of the way, let’s get down to the good stuff: ARC. If you’ve been developing for iOS or you’re even just vaguely familiar with it, then you know what reference counting is. I spend some time talking about the difference between Reference Counting and Garbage Collection in my Windows Phone 7 for iPhone Developers book and also talk about Reference Counting and ARC in my other (semi-top secret) upcoming book.

What it boils down to is that in an Object-Oriented application, especially one with multiple modules, lots of classes, and lots of exchanging of pointers to objects – you have a memory issue. The issue is – when a given class is done with a given object, how can it decide whether or not its OK to free the memory for that object? In short, it can’t. If you’ve designed your classes properly, they should have absolutely no way of knowing how many other objects in your application have a reference to the object in question. The classic Objective-C solution to this problem, and the one currently employed both on the Mac and in iOS, is Reference Counting. When an object declares its intent to hold onto another object for a period of time, it retains that object. When it says to the other object, “So long, and thanks for all the fish!”, it can then release the object when it’s done using it.

This is great and very efficient. The problem is, it’s also really easy to screw up. If you set an object to nil that has references to it, you’ve just created a memory leak. If you forget to release an object that goes out of scope, you’ve  just created a memory leak. It’s scary easy to create memory leaks and sometimes can be scary hard to track them down, even with Instruments tools like Leaks.

Unfortunately, this is where many .NET developers start pointing fingers. They yell and scream and claim that reference counting is old-school. If these same .NET developers used to be COM developers, then they have plenty of reason to both fear and hate reference counting (on Windows). Many .NET developers (and Java developers, including Android devs) are so used to the idea of a garbage collector they can’t fathom the idea of having to manually manage their own reference counts. To them, it’s barbaric – we might as well be asking them to call malloc and dealloc manually! The horror!

Garbage Collection is a sort of omnipresent Big Brother figure. It hovers over your object graphs and when it thinks you’re not looking (e.g. the application’s CPU utilization might be low, or completely idle) it will sift through your memory and free up the memory for orphaned (these would be leaking in a ref-counted environment) objects. Some garbage collectors will tidy up the place while they’re at it and defrag the managed heap. This, of course, implies that there is a managed heap to begin with. There is no such managed heap in Objective-C and, at least on iOS, there is no garbage collector. Objective-C 2.0 (for the Mac) has the option of being garbage collected but there are performance implications to running under a GC.

Finally, now that we know what reference counting and garbage collection are.. what the heck is Automatic Reference Counting? In my humble opinion, ARC is the best of both worlds. The reason people love GC is because it frees the developer from spending so much time coding pomp and circumstance (retain, release, autorelease, *panic*, etc) so they can spend more time worrying about actual functionality. ARC also provides this benefit but it doesn’t require the overhead of a garbage collector!

So now, instead of manually retaining and releasing objects, you simply declare them. When you declare an object, you tell the compiler (and therefore, ARC) how you want the lifetime of that object managed. There are 4 ownership qualifications that you can specify when declaring an object (or defining a property):

  • Autoreleasing – When an object is assigned, it is retained and autoreleased.
  • Strong – The new object is retained and the old one is released. This is the standard “retain” behavior for properties in ObjC 2.0
  • Unsafe retained – The object is simply stored in the variable.
  • Weak – Weak references are non-retained but they also have an added benefit – if an object to which a weak reference refers has been de-allocated, the weak value is automatically set to nil, preventing an awful lot of crashes.

So now we can declare properties like this:

@property(strong) KCDemo *kotanCodeDemo;

And we can declare variables like this:

__weak KCDemo *kotanCodeDemo;

Since strong is the default, we automatically take care of reference counting for pointer objects just by declaring them:

KCDemo *kotanCodeDemo;

There is a truckload more to Automatic Reference Counting than what I mentioned here. I just wanted to point it out so that .NET and Java developers who have spent so much time and effort lambasting the fact that iOS has no garbage collection see that there is a new option on the horizon and, in my opinion, that option is even better than garbage collection.

What I’ve Been Up To Lately

I was originally thinking of framing this post in the form of an apology. For example, “I’m so terribly sorry that I haven’t been posting to this blog lately.” I’m not going to do that, however. While I freely admit that the blog has been barren for the last couple of months, it hasn’t been without reason.

Firstly, I have been wrapping up my work on the Windows Phone 7 for iPhone Developers book. I’m really proud of this book and I really like the way it came out. If I had it to do over again and was able to add a few hours to every day I spent working on it, I would’ve spent more time building parallel samples so that the code downloads for the book included nearly as much iOS code as it did WP7 to allow iOS developers to compare real-world, full-functioning scenarios. Oh well, perhaps I’ll include that kind of depth in a future “Mango” edition of the book (if there is such a thing).

Second, I’ve been in the process of moving. I’m packing up stuff, throwing stuff out, and staging my old house for sale. This is time consuming when you’re still working on copy edits, tech edit reviews, oh and trying to squeeze in a little family time in there here and there.

Thirdly, I’ve started working on a new book. I can’t yet tell you the title, but here is a hint: all of the code is written in Objective-C 🙂

Fourth, I’ve been working on a series of articles for the SilverlightShow.net website, all about WP7 for iPhone and Android developers. Check out that series here.

Backing Your iOS App With WCF JSON Web Services

There is very little doubt that iOS is one of the most compelling targets for developers who want to build free or paid applications for mobile devices. The iOS SDK is, in my opinion, one of the best designed SDKs available. It is better, in fact, than many desktop and server SDKs that I’ve used. Unfortunately, Apple doesn’t have a server-side SDK so when it comes to building web services that support our connected mobile applications we’re left to look elsewhere.

Say what you want about Microsoft and their Windows Phone 7 SDK, but few people doubt that the .NET Framework is on the short list of go-to technologies for enterprise and server-side code. Unfortunately, not enough people know that it is possible to quickly and easily build cross-platform, mobile-friendly web services using Microsoft technologies. Partially their own fault for some of their early work with Web Services, Microsoft has a stigma of being proprietary and that none of their stuff server stuff is easy to consume from non-.NET clients.

This blog post will show you otherwise. For demo purposes I will use a subject that is near and dear to my heart, Zombies. This application is a zombie catalog that pulls a list of known zombie types from a catalog server and displays them in a table view (via a UITableViewController).

First, let’s build the service. To start, we’re going to build a simple C# object that represents the summary information we’re going to pull down to populate our table view:


[DataContract]
public class ZombieInfo
{
 [DataMember]
 public string Name { get; set; }

 [DataMember]
 public string Description { get; set; }

 [DataMember]
 public int TotalSightings { get; set; }
}

Now that we’ve got the data contract for the ZombieInfo class, let’s create a WCF service contract for the service:


[ServiceContract(Namespace="http://my.app.com/services")]
public interface IZombieInfoService
{
 [OperationContract]
 [WebGet(BodyStyle = WebMessageBodyStyle.Bare,
 RequestFormat=WebMessageFormat.Json,
 ResponseFormat=WebMessageFormat.Json,
 UriTemplate="/KnownZombies.json")]
 ZombieInfo[] GetKnownZombies();
}

I won’t bore you with the implementation of the service itself … for the purposes of this demo I just created a few instances of some zombies and returned them. You can choose to host the implementation of this service in IIS or you can self-host it using code like this:


Uri jsonbaseAddress = new Uri("http://" + Environment.MachineName + ":1111/ZombieService");
jsonServiceHost = new ServiceHost(singleton, jsonbaseAddress);
ServiceEndpoint jsonEndpoint = jsonServiceHost.AddServiceEndpoint(typeof(IZombieService), new WebHttpBinding(), jsonbaseAddress);
jsonEndpoint.Behaviors.Add(new WebHttpBehavior());
(jsonEndpoint.Binding as WebHttpBinding).Security.Mode = WebHttpSecurityMode.None;
jsonServiceHost.Open();

In the preceding code, the singleton variable is just an instance of my ZombieInfoServiceImpl class (a class that implements IZombieService).

Now that you’ve got this service running and self-hosted (or running in IIS – however you want to host your WCF services is up to you, but you’ll probably need IIS if you’re hosting them on the Internet somewhere) you can consume it. If you hit the /KnownZombies.json URL and you’ve provided some bogus data, then you should get a blob of information in typical JSON format. In our case, it’s a JSON array (this fact will be important when we get to the iOS code).

Now we can get started with our iPad/iPhone app. I’m not going to cover how to make this a Universal app because I did that in my previous blog post. The first thing you’re going to need is a UITableViewController. It doesn’t make any difference if you rig it through the designer (you are using Xcode 4 right??) or if you do it all programmatically. The key is that we’re going to hit our web service in the viewDidLoad: method.


- (void)viewDidLoad
{
 [super viewDidLoad];

 NSString *urlString = @"http://my.app.com/services/KnownZombies.json";
 NSURL *url = [NSURL URLWirthString:urlString];
 NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
 NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
 [connection release];
 [request release];
}

Now we need to grab the data from the web service, which is going to come to us in the form of an NSData pointer. We’ll need to convert that to a string and then from that string, we need to parse the JSON and turn it into an Objective-C object. To do that, we’re going to use this JSON framework for iOS. I didn’t mess with trying to link the library, I just copied the code into a JSON folder and at the top of my view controller’s implementation file I added an import for “JSON.h”

Assuming we don’t get any errors, then our NSURLConnection delegate method is going to be called. This is where we use the JSONValue category extension provided by the JSON framework to give us an NSArray* object from the string:


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSDAta *)data
{
 NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 self.knownZombies = [jsonString JSONValue];

 NSLog(@"got zombies! : %@", self.knownZombies);

 [self.tableView reloadData];
}

In this little bit of code, my table view controller has a property on it called knownZombies. In a bigger application I might have gone with a repository pattern to separate the view controller from the actual web service calls and the data storage and so in my viewDidLoad: method I might have just done something like this instead:


[repository fetchZombies];

And then the rest of my table view controller pulls things like rowcount and data from the repository. The last thing we need to do is supply row counts and cells for the table view:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
 return [self.knownZombies count];
}

- (UITableViewCell *)tableview:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *CellIdentifier = @"ZombieCell";

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil)
 {
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleDefault reuseIdentifier:CellIdentifier] autorelease];
 }

 NSDictionary *zombie = [self.knownZombies objectAtIndex:indexPath.row];

 cell.textLabel.text = [zombie objectForKey:@"name"];

 return cell;
}

That’s pretty much all there is to it. When you expose your WCF services as RESTful, JSON-serialized services then they become an absolute piece of cake to consume from your iOS application. One main reason for this is due to the availability of frameworks like the JSON framework. The other reason is that the XML parsing capabilities you get out of the box with the iOS SDK suck. Also, you might think the difference is small but when you get into large numbers of rows, the difference in payload size between XML and JSON can actually make a big impact on your application’s performance. The other (final) also is that if you are hosted on a site that charges by bandwidth, every dime saved by using JSON over XML counts.