iOS Development: Things to Like; Things to Hate

Things I like about iOS Development

  • I like writing code in the Objective-C language.
  • I like Apple’s provided frameworks and tools. They are, on the whole, very good.
  • I like the iOS community’s enthusiasm for great products. It is very inspiring.
  • I like that people will pay you good money to build apps for them in iOS. Though this is has good and bad implications.
  • I love attending, and over the last few years running, CocoaHeads in Philadelphia.
  • I like that the community on a whole is not very secretive. There is a sense we are in this together and people constantly help each other out sharing tips, code and war stories.

Things I hate about iOS Development

  • I hate the exclusivity of the AppStore distribution.
  • I hate that I can’t side load apps that people build that Apple doesn’t approve of.
  • I hate that I have to sign my apps.
  • I hate the learning curve and the bugs of the signing process for all but especially for people new to iOS.
  • I hate that Apple has a shitty code validator during app signing that will complain when I have methods on my objects that look like private methods on their objects.
  • I hate how shitty AppStore search and discovery is.
  • I hate the corporate politics that let apps get featured in the store because of “connections”.
  • I hate how people continue to manipulate the AppStore ranking system and I hate how little Apple seems improve the situation when many small developers livelihoods are at stake.
  • I hate how the Radar bug system doesn’t have tools in place to involve and update the original bug reporter on progress being made. From a third-party perspective most bug reports might as well go into a black hole.
  • I hate how in the pit of my stomach I believe that, on the whole, the iPhone and its brethren have not improved society. I think the majority of mobile software has only helped to empower “generation ‘me'”, a generation that is “friends” with everyone, but no one. This deserves a post on to itself someday.
  • I hate the iOS / Mobile bubble. The fact that people are spending way too much building apps and are not getting a proper return of value on the investment.
  • I hate that building products is way riskier than consulting (bubble related).
  • I hate that Apple hasn’t shown more interest in providing a library management system. Thankfully we have CocoaPods but since it’s on the outside there is a fear it might not be able to keep up as the tool chain evolves.
  • I hate that back when Apple first started to integrate OCUnit into Xcode it enviably killed like 3 or 4 other very promising testing systems because the thought at the time was “well Apple made their choice and will build on it” when in fact Apple never did. Only recently did we see XCTest and it is, right now from a functional perspective, a method renamed version of OCUnit with no new features.
  • I hate how Xcode Bots doesn’t have pre and post scripts.
  • I hate (hate is a strong word — let’s say disappointed by) the growing community of “Apple Celebrity”. The once full time developers who can build great things but now choose to spend the majority of their time blogging, podcasting and tweeting all day. They partake in a low impact ping pong match of opinions on weekly events and news that frankly doesn’t mean all that much in the grand scheme of things.

MegaManEffect now on GitHub

A few days ago I started to archive a lot of the Clickable Bliss website, replacing it with a smaller “hiatus” version. In the process I moved the MegaManEffect which lived primarily via a blog post and a GoogleCode subversion repo to GitHub.

https://github.com/zorn/MegaManEffect

The MegaManEffect is an application that emulates an effect seen in the classic NES game Mega Man 2. When you launch a Mac OS X application, the screen goes dark, stars sweep the night sky and your application’s icon is presented in a blue letter box bar with a cheesy 8-bit music introduction.

MegaManEffect was written while I attended the ADHOC/MacHack conference in 2004 and took second place in the ADHOC Labs Showcase! In the summer of 2005 the application hit a nerve in the community generating tons of interest and downloads. It is to this day one of the most distributed pieces of code I’ve even written.

Funny enough after tweeting the move I ended up getting an email and later a pull request to update the code base to compile on 10.9. I approved the pull request today (thanks @smithrobs!) with a few other fixes.

The MegaManEffect will be 10 years old this summer.

Enums and Switches

If you are one to use enum to define modes or types in your models or controllers, consider using switch statements to help branch the different behaviors. If you do so, the complier will help you when you have forgotten to implement behavior for a enum value.

Take for example a view controller that might have different behavior if we are in an editing mode, and even more so the editing is handled differently depending on the target device. For this, let’s create an enum like:

typedef enum ViewControllerMode : NSUInteger {
    ViewControllerModeDefault = 0,
    ViewControllerModeEditingiPhone,
    ViewControllerModeEditingiPad,
} ViewControllerMode;

Now if the tableView:didSelectRowAtIndexPath: method let’s use a switch statement to branch behavior depending on the behaviorMode.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (self.behaviorMode) {
        case ViewControllerModeDefault:
            [self showRecordAtIndexPath:indexPath];
            break;
        case ViewControllerModeEditingiPhone:
            [self editRecordAtIndexPath:indexPath];
            break;
        case ViewControllerModeEditingiPad:
            [self replaceRecordAtIndexPath:indexPath];
            break;
    }
}

Notice we are not using a switch default behavior here. Now let’s add a new enum type called ViewControllerModeEditingiWatch and compile. Tada! The complier has a warning for us.

Enumeration value 'ViewControllerModeEditingiWatch' not handled in switch

This pattern can be extremely helpful to make sure you are accounting for all needed behaviors. Please consider it next time you are working with enum. Thanks!

Setup Bots Status as a Screensaver

It’s time to turn off that family photo screensaver and switch to something that’s important, CI status screens!

Bots Big Screen

First up you’ll need this screensaver (or something similar), which can be configured to load a single or multiple websites up as a screensaver.

https://github.com/liquidx/webviewscreensaver

Sadly the screensaver bundle is not developer signed so if you are bit paranoid consider downloading, inspecting and building the thing from source. Or you could be like me and hit run inside of Security after the initial “can’t run, not signed” dialogue.

Next you’ll need some URLs. I run both Xcode Bots and Jenkins off my Mac mini named GLaDOS and for those you’ll want URLs like:

http://glados.local/xcode/bigscreen

http://glados.local:8080/view/Monitor/

For Jenkins I’m currently using the Build Monitor Plugin which is pretty basic but a nice start.

Here’s to hoping all your returns from coffee breaks are bathed in green and passing tests.

Xcode Bots and Branches

Just a little quick tip tonight. If you create a Bot from within Xcode 5 it will assume that the branch you want this Bot to run on is the branch you are currently on. To change this, use the Xcode Bot Web interface. Select your Bot and look for the settings gear in the upper right and then edit the Bot, defining which branch you want to bot to run on.

Xcode Bot Setting Gear

Xcode Bot Setting Details

I’m starting to revive an old side project of mine and it’s feeling good so far. I have Xcode Bots running tests and the static analyzer (all green baby!). I also have Jenkins deploying to HockeyApp when I merge development into my qa branch. Hope to share more details soon.

IBOutletCollection

Did a short show and tell at the last CocoaHeads meeting demoing something I learned at work and hadn’t known about before, that being IBOutletCollections.

For seasoned Cocoa developers we all know that an IBAction is typically how a button sends a message to the controller that something should happen. On the flip side there is IBOutlet which is a pointer to a view in the UI that let’s the controller have access, typically to update the view’s contents or attributes.

Well an IBOutletCollection lets you have access to a whole collection of views via a single connection. In code declaring an IBOutletCollection is going to look something like this:

@property (strong, nonatomic) IBOutletCollection(UITextField) NSSet *textFields;

When you declare the type of the outlet you can be specific such as UITextField or use higher level classes like UIView and connect to many different kinds of views. Technically you can use NSArray but since the order isn’t something I think is guaranteed best to stick to NSSet. Finally, while most outlets should be using weak references, these use strong since the view controller needs to own the array that contains the connections.

When you want to iterate over the collection just use fast enumeration like you normally would with an NSSet.

- (void)updateUI
{
    for (UITextField *textField in self.textFields) {
        textField.text = self.mainTextField.text;
        if (self.isBlue) {
            textField.textColor = self.view.window.tintColor;
        } else {
            textField.textColor = [UIColor redColor];
        }
    }
}

For a simple project demo see my OutletDemo project on GitHub.

Some real world use cases for IBOutletCollection might include theming (outlet collections for various styles, then making connections to view that should be styled) as well as form access and validation. IBOutletCollection was introduced in iOS 4 so theres no reason not to check it out. Enjoy.

Updating Homebrew’s “httpListenAddress” Default for Jenkins

I’ve setup some Jenkins servers in the past for Ruby on Rails apps but these days we are trying to get things running for iOS deployment and testing at work.

To experiment with some plugins and such I have my own Mac mini and installed Jenkins via Homebrew. Overall it’s working great though I was a bit stumped as to why I couldn’t load the Jenkins webpages outside of using localhost:8080 on the Mac mini itself. Worked fine last I did a clean install.

Turns out the Launch Agent settings Homebrew gives you (located at ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist for me) will launch with the following command line parameter --httpListenAddress=127.0.0.1. Edit this to 0.0.0.0 (the default) to allow all addresses.

I know this isn’t the most enjoyable blog post but wanted to post it as Google Food for others who might run into the issue.

Other related posts:

Week in Review: WWDC, E3 and CocoaHeads

It’s been a crazy week. Some random notes and observations…

WWDC

Apple did a tremendous job streaming the Keynote. I watched it live on my Apple TV in the living room while chatting with friends on IRC and Twitter. It was awesome. As for the content, let’s review:

Mac OS X 10.9, Mavericks — Not a huge fan of the name. I liked Sea Lion! As for the user facing features, most are pretty meh for me, I will enjoy better dual monitor support. I also like the idea they are pushing iCloud Keychain and that it will suggest higher quality passwords for people. I myself will stick with 1Password but this is a great feature for users at large. The advanced tech of 10.9 looks great. Love the focus on battery life.

iOS 7 — I have very mixed feelings for the new UI. Some of it I like, some of it I don’t. Between the historic adoption rate of new versions of iOS and the complexity of delivering a consistent experience across iOS 6 and iOS 7, I can see many apps moving to iOS 7 only in the coming months, particularly ones that aren’t released yet.

While not reviewed in detail during the keynote, the real gems for me are in the developer tools and APIs released this week. Xcode 5 looks awesome. The new continuos integration services of OS X Server looks great (though time will tell if it can be a full on replacement for current solutions). Tons of brand new tech including: Text Kit, Sprite Kit, Game Controllers, UIKit Dynamics and better multitasking have been introduced along with some great improvements to current APIs. It’s going to be months until I have time to play with everything.

New Mac Pro — I’ve been a long time customer of the Mac Pro and was in the market for one in 2011 when I sadly, after continued uninspiring updates to the product line, had to settle for a loaded (max RAM / max Graphics Card / 256 SSD) iMac instead. Not to sound like a total dick, the iMac has been great and really fast but I still longed for the multi-drive, graphics card replaceable, mega ram slot tower that I was accustom to. So this new Mac Pro is actually in my eyes more of a loaded Mac mini style device. There is little chance you’ll be replacing these graphic cards (yes cards, it has two of them; probably to support the unannounced retina display this Mac Pro will probably ship along side with) and there doesn’t seem to be much room for extra internal hard disk space. That said, this machine’s stats looks awesome and I have been antsy for a retina display on the desktop. I’ll have to see a price tag before I commit myself but am happy I have options when it comes time to upgrade my current iMac.

There were also new Macbook Airs released at the show. I have and really enjoy my 13-inch Air and while the new extra battery life of these new models are probably very important for some people I am lucky enough to be able to plug-in when needed so will probably skip this generation. If it was a retina screen, maybe I’d change my tune.

Sessions — After the keynote, Apple, like they had promised, started publishing the session videos, usually less than 24 hours after they had been presented. By the end of the week we also had choices for HD or SD variants as well as the PDF slides. This helps take the sting out of not being able to acquire a ticket a lot and I thank Apple for putting forth the extra effort to do so.

E3

I haven’t been keeping up with E3 nearly as much as I have been Apple news, but seems like everyone had a great time out in LA. Playstation 4 announced it will not be following Microsoft’s lead and is promising very little DRM on the PS4 that will inhibit things like game sharing and used game sales. This, plus a cheaper price tag and arguably better under-the-hood tech has pushed itself to the top the console food chain. Time and games will tell how things end. For me, I’m not planning on a day one purchase. I’d like to see how things pan out and find a must have game to push me over the edge.

As for my Nintendo, for which I always have a love/hate relationship with, we saw a new Smash Bros, a new Super Mario 3D World, as well as lots of new info on the new 3DS Pokemon and Zelda titles.

Moving from back to front, I’m getting pretty jazzed for the new Pokemon. Even outside my previous fandom for the series, this new release has a lot of new elements to check out. Being a huge Link to the Past fan has me interested in this new sequel game though I’m still mixed on feelings of curiosity mixed with disappointment that they aren’t doing something more unique. I own Super Mario 3D Land for the 3DS and it was not something I really enjoyed. The gameplay was very slow and continued use of the same old Mario platforming was exhausting. Considering the lack of interest New Super Mario Bros got as a Wii U title, you’d think they’d start to catch on that we need real NEW things but alas this seems lost on Nintendo. Finally, Smash Bros fans will inevitably enjoy a new release of Smash Bros. Even I get a little giddy seeing MegaMan added as playable character. Unfortunately I’m not a fighter fan. I no longer share a house with people to regularly play with and even when I do play these games at a party it becomes a button mash as no one knows all the moves. I think I’ve grown out of it. :(

CocoaHeads and our iOS 7 Hackday

On Thursday we had our usual monthly meeting for CocoaHeads. With the Apple event still in-progress there was lots of chatter about all the new stuff. When the meeting finally started we actually ended up with so many talks and demos we went over time. Reactive Cocoa in particular kept many a CocoaHead asking questions and thinking out of the box.

Saturday we held a hackday, our first CocoaHead event in some time. The hackday was focused on iOS 7 and had people work solo or team up to experiment with the latest API toys. Throughout the day we provided breakfast, snacks and a home made lunch from IndyHall’s own Kara LaFleur (@KaraLaFleur). At the end of the day we presented our results to the group and awarded book prizes from the Pragmatic Programmers and Big Nerd Ranch. All in all things went great and it was good to see some people attend who normally can’t make our nightly meetings.

Sunday Rest

It’s now Sunday and after an extremely busy week I’m relaxing. I do have plans to head out for some dinner later to wish my Mom to wish her a happy Father’s Day but otherwise am enjoying a lazy day around the apartment.

For all my Apple and gaming friends, I hope you enjoyed this week as well and enjoy the upcoming releases. Have fun!

Video: Introduction to Objective-C Categories

I’m hoping to do some formal screencasting, educational videos for iOS and Rails, in the future so for practice I hacked together this little Introduction to Objective-C Categories to try some stuff out. It’s not the worst thing ever so I thought I’d share it and my notes.

Objective-C Categories from Mike Zornek on Vimeo.

A short introduction to Objective-C categories for iOS and Mac developers.

As far as what I was trying to learn through the process of making this…

What is a good resolution to shoot at?

Ended up trying 1920x1080 which in TV speak is 1080p. This I think worked well. There is enough screen real estate to show Xcode with all “widgets” open, plus enough room for a side app like the iPhone Simulator. Speaking of which, 1080p barely squeezes both portrait iPhone retina and portrait iPad non-retina. Finally, should this ever be pipped out to a TV it should be full screen with no scaling.

What I don’t like is how tiny the file browser and non-source text can be. I envision zooming in on occasion to have those read well when needed.

How is Vimeo these days?

I’ve put up a few videos in the past on Vimeo but for this new project I’m considering using their Pro service so I saw this as an opportunity to play around with their stuff.

Overall things seem good. They are really good about suggesting codec and bit-rate changes to get the most from their platform. They also provide a nice HTML 5 version of their player.

Why not YouTube? Long term I could see some of this content becoming pay-for or subscriber/membership-based and YouTube isn’t really good for that.

To record audio before video or with video?

For the majority of my previous screencast work my typical process included recording the audio on its own and then recording the video, matching everything up in editing. The result is a nice, tight video without any real hesitations or pauses.

For this video I did things more casual. I had a list of things I wanted to demonstrate and recorded my voice right with along the video. There are pros and cons to this.

Pros:

  • I do enjoy the personality that comes from this style. To hear the typing and a few ums makes a human connection.
  • If done well, it can shorten overall capture time.
  • It lends itself to camera shots of the speaker, which again can help create a human connection.

Cons:

  • Doing the video live with the audio is much, much harder to perform. It’s easy to miss things you intended to showoff (I did so in this video.)
  • I myself have bad allergies and tend to breath into the mic. If recording the audio on its own it’s easier to isolate this.
  • Some people will not like hearing the typing.
  • If the screencast is based off a fixed script I’ll be able to post a text version easier, which is extremely valuable (for Google-food as well as people who pref text over videos).

In the end I think I’ll be going back to audio only first, then screen recording but welcome your feedback.

Other random observations:

  • Probably want to hide the dock for more “Xcode space”.
  • Those early “title slides” were done in Keynote. Works great for this kind of stuff, especially animations to explain abstract concepts.
  • In the future I won’t be typing everything. Longer code will be uncommented in place or dragged in from snippets.
  • Could have done some some zooming to help visualize things like the new file Xcode sheet, schema editor.
  • Need to overlay URLs in large type when promoting a website.

Not sure how fast we’ll see real production start on these videos as I do have a few things already cooking but I don’t mind too much as it’s good to be busy. :)

Xcode Documentation Downloads

Rather that use the Mac App Store and re-download Xcode each time I need to install it on a new Mac, I take advantage of developer downloads directory and grab the Xcode DMG file so I can put on my USB disk and move around from Mac to Mac and avoid the duplicate downloads.

Xcode however no longer includes the documentation, so the first thing that happens after you launch is a 1.3 GB download for the docs.

Xcode Documentation Downloader

Apple, please consider adding a download with a snapshot of the documentation in place. Maybe even a LAN sync option so it could grab the docs from my desktop (or my co-workers) instead of saturating my internet connection all the time.