Category Archives: Xcode

iOS NSStreamDelegates, Grand Central Dispatch, & NSNotificationCenter

One of the more difficult design patterns I’ve managed to get working in Objective-C while developing an iOS app is one that requires NSStreamDelegates, Grand Central Dispatch (GCD) and NSNotificationCenter.  This design pattern comes into play in the following situation:

  • Application launches
  • Application does some communication with a server in the background
  • When the server communication in the background is complete, the View Controller is updated to display information from the server.

Its a pretty common scenario and I’m sure one that has many answers.  In my case, I needed to use CFReadStreams and CFWriteStreams due to the way the client server communication works.  So if there was a simpler way to do it, I’d love to know.

The design pattern that I used at a high level to accomplish this is as follows:

 

  • Application launches,  displays its first View Controller
  • This first View Controller in viewDidLoad registers an observer with NSNotificationCenter and then kicks off a background request via GCD to do all the client/server communication
  • The background request that launches is an NSStreamDelegate object.  It sends info to the server.
  • Once the background request receives information from the server, it sends a notification to NSNotificationCenter that the client/server communication is complete
  • Finally, the first View Controller gets this notification, and then updates its View with that info.

That’s the high level.  So now lets go through and flesh out the details.

Application Launch and First View Controller

This is a simple example, but its just to get you the basic idea.  This part is standard in most iOS apps.  The thing to note about this is that my FirstViewController is not an NSStreamDelegate.  It does however contain an object that is an NSStreamDelegate.  This is called my Communicator class.

First View Controller viewDidLoad

Here’s where we start to get cool.  viewDidLoad looks something like this:

A few things to note here:

1.  We add an observerer to NSNotificationCenter.  This basically says:  If someone sends the updateView message, then I’ll respond to it with my updateView method.  (We’ll show this later)

2.  We dispatch an asynchronous task to GCD.  That’s what this whole dispatch_async business is all about.  This way, the view controller will just display while this task runs in the background.

3.  We instantiate myComm and initiate it with some connection info.  This info might be something you got from the app delegate, some other view controller, or a plist.  That part is left to you to decide.

NSStreamDelegate actions

Our class Communicator is a NSStreamDelegate.  Here’s some of the relevant header info:

Nothing big here, just the NSInputStream (the stream we get info from the server) and the NSOutputStream (The stream we write to the server)

As part of the initialization of the Communicator, we have a function called startConnection. This can be called in the init methods. (provided you have all the server communication info: (e.g: user, password, server, port, etc).

Our’s has this:

The important part here is what you do before you schedule your input and output streams on the RunLoop.  The RunLoop is the preferred way to work with NSStreamDelegates.  You have to make sure that you put it running back on the main thread’s runloop.  That’s what this whole dispatch_async(dispatch_get_main_queue() bit is about.  If you leave this out, then you’ll never get any connections going on.

Once you open the connections and you do your reading and writing in the handleEvent function:

Then once you finally get the data from the input stream you send a notification.  This is done for us in the

we run:

Before we do that, however, we set our theResult NSString to the value we received.

Updating View in First View Controller

Back in the FirstViewController, we have a function updateView:

Notice here that once again we need to make sure it goes back on the main thread before we update the view. Then, since our Communicator belongs to our ViewController, we can get the result of the client/server communication through the getter and set the UILabel to that result.

Summary

As mentioned before, there are probably lots of ways to do this and some are probably better than what I’ve mentioned here.  However, this was pretty tricky to me to figure out and once I did, I thought it was worth sharing as I couldn’t find any holistic info on it via any search engines.

I’d be curious to know if this helps anybody.  Thanks for reading.

iOS app submitted to iTunes Connect

I just submitted my first app to iTunes using Xcode4 and iTunes Connect. There was a bit of a learning curve, but after hacking away at it last night I’m happy to say its sitting in Apple’s queue waiting for review.

First off, let me say that even though its a total pain there are some good things that come of it: Because of the validation process they make you go through you don’t have to wonder if there is technically something wrong with your app. The validation phase takes care of making sure you have the basic technical aspects of your app working correctly. This includes verifying certificates are correct, making sure nothing offensive is sent to the store, and making sure the code actually compiles and runs.

Perhaps the most difficult thing for me was to sit down and actually read the manual. The part I missed during the entire development process was the iOS portal:

iOS developer portal

This is where you look to upload to the portal

This is found when you log into the iOS developer center.

The first thing I missed was that I needed to create a ‘Distribution Certificate’.

This distribution certificate then needed to be downloaded into my Keychain. Basically, once this is done, you click on the file to download it, then click on the downloaded file and it will be inside your keychain. Not too hard right?

The next step is to actually create an App ID. I found this part frustrating as you are not allowed to delete an app id once it is created. In addition to this the App ID you create inside of iOS portal must be the same as the bundle ID of the app as well as the bundle ID that you give to iTunes connect. (More on iTunes connect in a bit). This is the part that took me forever because I renamed my app several times. I started with UCS Tech Ref, then UCS Tech Specs. So my bundle ID was ucstechref, then I changed to ucstechspecs. The problem is that in iTunes Connect, I had already named it ucstechref and I wasn’t allowed to change it.

Anyway, once the app ID was created, I configured them for push downloads by doing the process it describes in the configuration section of App ID. When finished my App ID had these things configured:

The last step in the portal was to create a “Distribution Provisioning Profile” for the App itself.

And that was it for the iOS portal. Now keep in mind that before I ran through the iOS portal to create my App IDs and Distribution provisioning profile, I had to actually create the app in iTunes Connect. This was pretty self explanatory.

The last step was putting it all through in Xcode. First, you need to open the Distribution Provisioning Profile and drag it into the Xcode Organizer. (Open Xcode and click shift+command+2). Once done here, you need to code sign your app:

The final part is to make sure your -info.plist has the Bundle Identifier set to the App ID that you specified in iTunes Connect and the App ID in the iOS Portal.

Whew!

Now you have to make sure that you have lots of pictures and the right sizes for all of them! That part was actually kind of enjoyable for me. I use Pixelmator to do all my art work and its pretty easy to get the hang of.

Once you have the right icons specified, go into your product Build Settings and check the ‘Validate Built Product’ and you’ll be warned of any issues you have.

Once that passes, you Archive the application, and can now validate, share, or distribute.

Words can not express the relief I felt after I finally validated the app and it passed all the inspections. The next step was to submit the app. I was stoked. App submitted. But then, I got an email from Apple immediately stating that my app was missing an image! I had forgotten an iPad screenshot. I quickly took one, submitted it in iTunes Connect and I am now back to hurry up and wait mode.

All in all a pretty rigorous process. However, I think its good because it filters a lot of junk from getting on to iTunes. Even though some apps are pretty weak in the iTunes store, they still pass enough hoops to make sure that they’re not complete garbage. I’m hoping my users will at least think that about my app… but if they don’t, hey, what do you expect for free?