Swifticle - .None, nil, and why Swift is awesome.

We build professional apps for Android, iOS and mobile web.
Have a look
Objective-C developers can now switch to #swiftlang 🎉

Harking back to my earliest days as an iOS developer, I quickly learned that in the event of something possibly holding a nil reference, you had to do the inevitable and check if x != nil before doing anything on an object that had the slim possibility of simply "not being there."

Of course the latest "Swifty" updates to Objective-C have given you _Nullable and _Nonnull. You can even use those almost whereever you normally use const, except they have to refer to a pointer type. However _Nullable, _Nonnull and their lowercase __nullable and __nonnull are pretty ugly. Lucky there's a nicer way of writing them like so:

- (nullable NSString *)nameForPerson:(nonnull Person *)bill; // Get Bill's name. Poor guy forgot it.
- (NSInteger)indexOfPerson:(nonnull Person *)bill; // 6 billion somethin' or other

Luckily, you can use the non-underscored (read: prettier) nullable and nonnull right after open parentheses, as long as the type is an NSObject or block pointer. You can also use those in @property declarations. And you even have audited code regions NS_ASSUME_NONNULL_BEGIN to simplify putting nullable or nonnull everywhere down to only putting nullable where it's needed. With that Macro, everything in that BEGIN and END block will be assumed to be nonnull automagically.


But that's not why I'm writing today. I'm writing today to tell you that you no longer have to put up with that blocky, (sometimes) borderline-unreadable syntax of Objective-C. You can avoid it completely by switching to Swift! #swiftlang 🎉

I know I probably lost a lot of you when I said that, but bear with me. During my first 7 months working in the industry, out of University (finally) and after 8 years as an Objective-C-only dev, I found myself using Swift for 98-99% of my working week.

My only experiences with bog-standard Objective-C came in the form of pull requests from a colleague of mine who was working on updating (read: cleaning up) a legacy project. When the time came for him to update Xcode, he was baffled by nullable and nonnull when the compiler seemed to require it, and indeed so was I. What had happened to old-faithful, the language without optionals!? 😭

That said, after using Swift for a while I came to really and truly love optionals. It beat having to check if everything was nil in Objective-C by a long shot, but it was still nice every now and then to hop back a little and try my hand at updating an old project so I didn't become too rusty.

It was doing this that made me start wishing for if x == nil checks in Swift. I rather dislike the practice of 'unwrapping' a value just to check if it's not there. Keep it simple, and use the nil check, I said. Well, the good news is you can! It's actually recommended to check if something !=.None(nil`), if you are certain there's a possibility an object may be empty. You use it like so:

if object != .None { // Do all the things }

It's that simple! For a while there when I switched to Swift, I was using the very nifty guard let and if let functions to "unwrap" my optional objects to see if they were nil like so:

guard let object = object else { fatalError() /* or return */ }

or

if let object = object { // Do the thing }

Which allowed me to bail out just as I would in Objective-C. However those examples gave me unused pointer warnings in Xcode. To silence them, you change let object to let _ where _ is a temporary variable. But it's not nice, it's not easy to read for a newbie.


Concessions...

Of course in Swift you'd still be persuaded to use guard or if let blocks to do a multi-line if x != nil { if x.y != "" { }} (and deeper) block that you'd write in Objective-C like so:

guard let objectY = object.y where objectY != "" else { return /* or fatalError() */ }

But that's a story for another time. And isn't the where keyword just awesome!?

But hey, at least in Swift you can simplify those ugly method signature examples from Objective-C into these:

func name(forBill person: Person!) -> String?
func index(ofBill person: Person!) -> Int?

Sure beats writing nullable (?) and nonnull (!), right? 😉