Swift Optionals

As an Objective-C developer, the biggest point of confusion for me was with optionals. There are of course other tricky idiosyncrasies, but the hardest thing to wrap my head around was the use of optionals and what the hell “?”,”!”, and “??” means.

Why We Needed Optionals

If you are at all familiar with objective-C , then your well aware that every object had the option of returning nil. To make code safe, we had to typically check for nil all of the time. Often we would set a return nil when something went wrong as well. So we would end up with a bunch of ugly code that looked something like this:


- (NSString *)getStringItemFromResponse:(id)responseObject {
    if([responseObject] != nil && [responseObject isKindOfClass:[NSDictionary class]]){                        
        return responseObject[@"someItem"];

    }

    return nil;
}

Notice that we return nil here if we fail to return a string by the end. Also notice that I purposely left out a check to ensure that responseObject[@”someItem”] is not nil and it is actually an NSString. Although we try to be perfect, most of us forget to do this sort of check from time to time. Swift can help with this.

How Can Swift Help?

When you define something as optional in swift, for instance the return would be a string optional, we’re saying this will either be a string or nil. This means, swift will force you to handle the condition where responseObject[@”someItem”] may be nil.

Now let’s consider a swift example of somewhat similar code:


func getStringFromResponse(responseObject:Any?) -> String? {

    if let tmpResponse = responseObject as? [String:String] {

        return tmpResponse["someItem"]
    }

    return nil
}

Here we’ve created a method that can take any object as an optional and it will return a string optional. Also, notice with swift you can declare a variable within the if statement. This is called optional binding. This variable will be a non-optional result inside if statement if evaluates to true. This result can then be used inside of the if statement.

First we can take the any object and make a variable within an if statement to check if the response object is a dictionary that contains only a string key and a string value. If that is true, we will return tmpResponse[“someItem”], which will return only a string value because our check. If none of that passes the if statement we’ll return nil. For this method to pass, you’ll have to make sure your dictionary type is [String:String]. This is a little more elegant and easy to read than the last response, but more importantly, all nil conditions and proper return types are guaranteed.

This example works if we expect the anyObject dictionary that comes in to have the type [String:String]. But what if the dictionary contains any object or primitive with a string key? For example [String:Any]

Well swift will let us handle that too!


func getStringFromResponse(responseObject:Any?) -> String? {

    if let tmpResponse = responseObject as? [String:Any]{

        return tmpResponse["someItem"] as? String
    }

    return nil
}

Or equivalently, and perhaps a little better:


func getStringFromResponse(responseObject:Any?) -> String? {

    if let tmpResponse = responseObject as? [String:Any],
        let tmpResult = tmpResponse["someItem"] as? String{

        return tmpResult
    }

    return nil
}

A Little More on Optional Chaining and Optional Binding

In the previous examples, you saw the use of optional binding in the if statements.

In Objective-C if you tried to operate on variable with a nil value, then you would crash. For example:


UILabel *someLabel = nil;
UILabel.text = @"Some Text"  //< -- Insta Crash :(

In Swift however, this it totally good if you define the label as an optional.


let someLabel: UILabel? = nil < -- the question mark makes it an optional.
someLabel?.text = "Some Text" < -- If nil, the text setter wont ever be attempted.

You can also keep chaining these


let someView: UIView? = nil
let cgColor = someView?.tintColor?.CGColor < -- cgcolor will be nil

So in this last example if someView is not nil, but tintColor is nil, then CGColor doesn’t get attempted. Swift is super safe (If done right :]).

From the cgColor example, if all you want is cgColor then you can use the optional chaining method we used. However, if you plan on accessing multiple elements of an optional, its better to use optional binding like so:


if let view = someView, let color = view.tintColor {

    print(view.description)
    print(color.description)

}

Here I’m not doing anything with the values, but you can see how optional binding is safe and helpful. If view evaluates to a non-nil value and color (which is derived from that previous value) is also non nil; than this if function will proceed. You can easily access each of the variables that have guaranteed values.

WTF is This “!” For?!!?

When working with optionals, you’ll probably make some mistakes and the compiler will suggest placing an exclamation point next to your optional. This is typically a bad idea. The exclamation point force unwraps the optional, and basically removes the optional protection. You’re basically saying, “It’s all good! This variable definitely is not nil”. Remember that Objective-C example with the nil label? Well this is basically the same thing. Just to be thorough though:


let someView: UIView? = nil
let color = someView!.tintColor < -- Insta Crash :(

For the most part, don’t use em. You can almost always use optional binding instead.

The main exception is when you define a class variable that is a foundation framework type (eg. UIButton, UIView, NSDate) without an initial value. These typically get defined as:


@IBOutlet var mainButton: UIButton!

This is because you are bridging over an Objective-C type. nil in swift is different from Objective-C, in Objective-C nil is a pointer to a nonexistent object. In swift, nil is not a pointer but rather the absence of a value. In other words, an Objective-C object always has a value and that value is a pointer. That value may be a pointer to a valid object, or a pointer to a nil object. So we implicitly unwrap it so we aren’t constantly having to unwrap it every time we use it. This would be super annoying. Implicitly unwrapping bridged Objetive-C elements is a compromise to make our lives easier. Take note though, you will still need to initialize these before using them.

Final Thoughts

When I first saw optionals, I didn’t care much for them. They seem to be a hassle, but once you take the time to really understand them, they actually turn out to be a time saver. Not to mention I have noticed most classes have substantially less lines without all the checking to make sure a value is not nil.

State of The Union

The presidential state of the union is a designated time where the president can openly complain about his views on the world and update us all on what is going on in his world. Since that is basically what I’ll be doing in this article, that is the title I gave it.

A Brief History

I had spend quite a bit of my free time for roughly a year or two learning Objective-C. Granted, had my day job been working on Apps, I could have learned it a bit quicker. Now that I am a gainfully employed iOS developer I have a few more years of experience under my belt. So imagine my frustration when a new programming language emerges just as I was starting to touch on Objective-C Mastery.

I started NSCookbook with a basic goal. NSCookbook was a method of teaching myself iOS Development while also providing value to the community. I have always found that the best way to learn something is to teach someone else how to do it. As a noob myself, I felt I had a unique perspective that would help out the new comers. What I liked about learning iOS development is everything was new to me and it was fun. Now that I’m more experienced, most of what I will write now is something I already have a pretty good grasp on. In other words, It’s getting a bit boring to me. This is where Swift will help me out.

The State of Swift

Swift 1.1 came out with XCode 6.0 and iOS 8. At the time I had guessed that Swift would not be quickly adopted as it was relatively new and buggy. None-the-less, folks adopted Swift in surprising numbers. As of Today, Swift 2.0 is the current version, and is quickly becoming the standard iOS language. This has become an increasingly cumbersome fact for an Objective-C developer for the following reasons:

  1. Every time I’m trying to solve problem that is new in iOS 8 or iOS 9, Most of the solutions that come up in stack overflow are now swift.
  2. New libraries on Apple’s documentations are documented in Swift
  3. Playgrounds are really sweet for experimenting, and they don’t support Objective-C
  4. Once you see Swift, you may realize how much more ugly Objective-C is.

So What Now?

I have noticed That I have been increasingly lazy with respect to my articles. This is mostly because I don’t like the idea of showing both Swift and Objective-C. It’s a lot of damn work, and half of it is largely uninteresting to me. Therefore, Moving forward I’m going to Ditch Objective-C. My primary objective right now is to learn swift. As such, I’d rather not waste too much time with Objective-C. I will however attempt to update old articles that are still applicable with Swift. I hope ya’ll are okay with that. :)

iOS Programming Recipe 36: A Fixed Width Dynamic Height ScrollView in AutoLayout

As an iOS Developer it seems I come across a common situation where I want to add a content view with the same width as the screen inside a scroll view. Since most apps need to have responsive layouts, this usually makes sense to do using Autolayout. At first when learning about scrollviews, they seemed like magic. Due to their slightly different rules they were also a bit frustrating.

[Read more…]

5 More Tips and Tricks

The last few posts have been pretty long and drawn out, so this time we’ll make a short and sweet post that helps save you some time. Building on the past tips’n’tricks article, here’s a few more.

Assumptions

[Read more…]

iOS Programming Recipe 35 – Implementing The Common Views: UIPickerView, UITableView, and UICollectionView

Over the past couple years I’ve noticed some patterns when it comes to noobs and the more useful iOS UI elements. Whether your dealing with UICollectionViews, UITableViews, or UIPickerViews, the pattern is essentially the same. And a lot of beginners, don’t quite grasp how similar these views really are. This recipe will focus a little less on the nitty gritty of doing a single one of these view types, and more on how the pattern works for them all. As a bonus, this will be the first tutorial I’ll be doing with Swift. As far as the UI elements go, it’s all the same philosophy, just a slightly different syntax.

[Read more…]

css.php
Privacy Policy