971-270-0003 info@singlecoilinc.com

Swift-ly venturing into an iOS future

Swift is the new Xcode language being promoted by Apple. I decided it was best to figure out how to use this language and learn its benefits first hand.

Why did Apple decide a new language was needed?  One major reason is that Objective-C (cocoa) has a bad reputation: hard to learn, ugly, convoluted and a plethora of [[[brackets]]].  Some of these complaints were true, some were just nit-picking. Is Objective-C hard to learn? Not in my experience, and it got much easier with the advent of ARC. Is it ugly? Yes, with arbitrary prefixes instead of namespaces (the NS in NSString originated with a company that hasn’t existed in nearly two decades!) and convention-breaking syntax (i.e. “YES”/”NO” instead of “true”/”false” or “becomeFirstResponder”/”resignFirstResponder” instead of “focus”/”blur” or even “self” instead of “this”), the average C/C++ developer would paraphrase C3PO, “I don’t know where your Mac learned to communicate but it has the most peculiar dialect.”

As the releases rolled on, Apple conformed more and more to accepted conventions (You could declare arrays like “@[‘a’,’b’,’c’]” instead of “[[NSArray alloc] initWithObjects: ‘a’,’b’,’c’,nil];” and if Objective-C is allowed to develop, by Xcode 9 we’d have something approaching C#.  However in doing so, the syntax would become so complex supporting new and old conventions making code much more unreadable.  A better, cleaner approach was to create a new language using modern software coding paradigms.  Enter Swift.

My very first foray into Swift was a new simple class I intended to add to an existing project.  One of the benefits of Swift is that it can be mixed in with existing projects that were built using Objective-C. However, upon creation of the swift file, the IDE informed me that I also needed a bridging class between Objective-C and Swift; additionally, I looked into how to access from Swift extern const NSStrings defined in Objective-C and saw that also wasn’t straightforward.  I the proceeded to remove my newly created Swift class, rewrite it in Objective-C and shelve my Swift learning for another day–it’s always a good idea to learn how to walk before you learn how to run.

So now I return to Swift learning with a simple project.  I want a Swift app that allows me to fill out a form and after clicking “Submit” shows the form on the next view.

Here are my steps:

1. Create the Swift Xcode Project.
I created a new Single View project called “Swift Test”.
I chose the “Swift” language for the project.
I set the device to iPhone (simpler than universal or iPad).
Lastly, I checked the “use Core Data” checkbox. Strictly speaking, this wasn’t necessary because I have no plans to store any data.  However, I wanted to see what the generated methods looked like in Swift compared to those I am used to for Objective-C Core Data.

The files created were named similarly to their Objective-C cousins: AppDelegate.swift & ViewController.swift–but there are no headers!  Looking at the methods in the classes yielded some nice surprises–gone are the ugly “#pragma mark”s and in their place are normal(-ish)comments (“// MARK: – …”) used to delineate regions in code. Also gone were the godawful “YES” and “NO” boolean values–application:didFinishLaunchingWithOptions returns “true”!! (BTW, I know that “true” and “false” are legal in Objective-C, but they’re not the convention and the last thing I want is some Mac fanboy to think I’m a noob after looking at my code.).

The next thing I notice is the total lack of semicolons. I’m apprehensive towards this mostly because of memories of time wasted tracking down missing whitespace while debugging TCL/TK back in college.  Semicolons clearly delineate one statement from the next, but mostly I think out of habit I’m going to type them anyways–that is until I break that habit–then forget them all over the place when I return to Obj-C, C#, JavaScript, Java, PHP, and every other freaking language that uses them.

Continuing on, the next I see are “lazy var”s.  The method signature for the Managed Object Context is “lazy var managedObjectModel: NSManagedObjectContext”.  What’s a lazy var?  It is actually a very nice shorthand way to not initialize a value until it is actually used.  In Objective-C, gettermethods would often have a bit of boilerplate such as:


-(NSPropA) PropA{
if (propA == nil){
propA = [[NSPropA alloc] init];
}
return propA;
}

The above code will initialize the iVar propA the first time the property is accessed and then pass propA back for each subsequent call.

I imagine the Swift equivalent is closer to:


lazy var PropA: (NSPropA) = {
propA = NSPropA()
return propA
}()

A method body with half the internal line count!

Also, in the ViewController.swift file, I was pleased to see the keyword “override”; I always prefer to have a compiler ask me if I want to redefine some variable or method rather than just take me at my word.

2. Modify the Storyboard
After examining the code, I took to modifying the storyboard.  This was more-or-less the same as Objective-C (Although perhaps because this was my first wholly iOS 8.1 SDK project, I noticed some differences in segues and view sizes.)
I threw on a couple text fields for First and Last Name as well as a button labeled “Submit” and then segued (“present modally”) to another view where my message will be displayed.

3. Add the IBOutlets & IBActions.
Declaring IBOutlets in the Swift class file is  done like this:
@IBOutlet var firstName: UITextField!

The exclamation point (‘!’) is for required fields, but you can also use a question mark (‘?’) for optional fields–compare this to Strong and Weak Objective-C properties.

Hook the IBOutlets and IBActions up just like usual in the storyboard.

4. Write the methods (or are they functions now?)

I filled out my submit method by checking that both text fields were populated and showed a UIAlertController message if they were not.  Then I filled out the usual prepareForSegue method by getting the destinationViewController, casting to the correct view controller type and then setting the UILabel to the display message. A definite check in the “Pro” column is the native String type and concatenation with ‘+’–no more “NSString:stringWithFormat” and worrying about using %d or %@ or %ld just to build a simple string.

I then built and ran the code.  Then it crashed with the following (characteristically dismal) error message:

“unexpectedly found nil while unwrapping an optional value swift”

Unlike in Objective-C, at this point the UILabel hasn’t been initialized yet. I needed to add a property to my resultDisplayViewController class to hold the display message.  Then in ViewDidLoad (or if you want, ViewWillAppear) I assigned the message to the UILabel’s text field.  Then it worked fine.  My first Swift program is ready for the App Store! :)

Conclusion:
Swift has legs.  It’s has many advantages over Objective-C.  It will take a bit of time to get used to, but not too much and the investment in Swift will pay off.  I look forward to my next iOS application that I will start and will write it in Swift.

Submit a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>