Sunday, July 13, 2014

Modernizing a 2009 iOS App with 2014 Swift

I wanted to learn a bit more about how Swift works and the best way to learn a new language is to start to code in it. The videos and book are great but I need to get the code under my fingertips to start to understand it better.

So, to get some experience with Swift I decided to port my first iOS app, HockeyTweet, from 2009 to a modern HockeyTweet built with Swift in 2014.

First what was HockeyTweet? It was a Twitter app optimized for Tweeting about Hockey games in a time before custom keyboards, auto correction, or enhanced predictive text inputs. So the scroll views were there to help you spell player names, put in arena names, post your favourite comments on the play, etc. It sold like...well, the opposite of hotcakes.

What it did do though, was help me to teach myself iOS programming which meant a leap into front end UI design, a new language (Objective-C), and new development tools. Now after 5 years of programming with Xcode daily, I am a little more experienced. How will that impact learning a new language and porting the app? Let's see.

Here are my notes as I worked on the app over the last 5 days:
  • Started on Xcode 6 Beta 2.
  • Moving to Beta 3 my storyboard elements all greyed out in the storyboard and were not viewable in the preview pane. Had to delete and recreate.
  • Learning the Swift syntax has been the normal new language growing pains. At least the code completion, warnings, and errors help to understand.
  • My app would crash in the Simulator when I tried to test it. Learned there are some missing init for a ViewController classes in Swift, you need these classes implemented for each ViewController you create:
    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        // Perform custom init here
        super.init(nibName: nil, bundle: nil)
    init(coder aDecoder: NSCoder!) {
   // Perform custom init here
        super.init(coder: aDecoder)

  • Getting my head to wrap around ? and ! for variable unwrapping. ? Is optional and ! Is used to unwrap a value if it is not nil.
  • I forgot how easy it is to get a container view from the parent view; access it via the embed segue.
  • Conversion from Cocoa to Swift sucks in the places that Swift methods for Cocoa methods are not provided. Like the missing loading from file methods for containers like NSArray and NSDictionary.
  • I lost storyboard elements again with some getting greyed out. Had to add a textview and label 2 times now due to this.

What are my thoughts on Swift?

  1. It's young and missing some stuff we take for granted in Cocoa. That is not a problem though, I expect heavily used functions from Cocoa that are missing to come over time. In the meantime we will have to wrap some Objective-C types to Swift native types.
  2. It takes a while to mind shift into the new Optionals and variable unwrapping but in general I like the idea and what it is fixing. I think this will be a good thing and cause less bugs if people do not try to circumvent it.
  3. Wow, what a lot less code I have to write now to implement the same app. I like it.
  4. Storyboards have come a long way from what you cold achieve with NIBs in 2009. I knew this already form other apps but seeing it in a rewrite was cool.
  5. UI Layout is a bit of a pain and feels like more work doing the constraint sizes but in the long run I can see this being less work and less code to write to handle the custom view sizes. Not needing custom code paths for iPad, iPhone 5+, iPhone 4s will be a blessing. A project or two and we will look back at older projects and cringe I am guessing.
  6. I am still subconsciously typing ; in places. I search and replace (occasionally) to delete them and it is entertaining to see that I added them again without thinking.

So, after 4 days of coding a total of about 12 hours I have completed the following:

  • Compose UI Ported
    • Missing Info View
    • Missing Custom Fan Favourites Edit View
  • UI layout
    • Best for iPhone 4s (original)
    • Need to handle larger sizes as a test of constraints. I will save this for later.
  • Model
    • Partially ported so far.
    • Loading initial data is taking some time since I need to work out the conversion from NSObjects to Swift objects when loading plist files with NSDictionary(contentsOfFile: String).
    • Network calls not hooked up.
    • Currently using initial load and sample data from testing of original HockeyTweet in 2009 so the players on the teams will be messed up.
    • Dropped schedule for now.
What do I plan to add next:
  • UITextView Hookup
    • Need to be able to take user input and have scrollviews insert data into tweet.
  • CharsRemaining Label
    • Hook up when UITextView for tweet composition is complete.
  • Share
    • I get to drop all the old Twitter code and go with the new Twitter API from Apple. I want tog et this hooked up and working.
  • Networking
    • Pull updated arenas, schedules, and team rosters from my web service.
    • This might be a chance to try out a new backend. Since I am not building this app for AppStore submission I will test this local only unless I land on a backend technology that I can run for free in the cloud.
Philipe Casgrain, my friend from CocoaHeads in Ottawa, put me onto the Summer of Swift. A contest to learn by coding. The idea is to code an app in Swift and do weekly updates to the project over the summer. I am going to enter that and continue to update the app over the summer. Adding back in original features and some new stuff to experiment with Swift.

The code is available to view on Github at HockeyTweetSwift if you want to take a look, grab some ideas, or make the next great Hockey Tweeting App! Ok, that last one is a joke.

No comments: