How I Handle Optionals In Swift

Updated to add using map over optionals section - 7th January 2015

Update (26th January 2015) See Beyond `if let` for video of me presentating of much of this content.

Dealing with optionals is unavoidable in any Swift program that interfaces with the Cocoa or CocoaTouch libraries. Realistically that is all of them with a very few limited exceptions. Handling them is often annoying a although I am very glad of the rigour that they enforce on me. In fact I like the rigour so much that I never use implicitly unwrapped optionals (variable declared with !) and I use force unwrapping only in very limited circumstances.

In almost all cases I use combinations of optional chaining and nil coalescing operators with `if let` used where they don't do the job. In this post I'm going to explain how and where I use the different options and give some examples.

Note that this is very much a "How I do it" post and not a "How you should do it" post. It is also what I do this week which may evolve further in future. I take a somewhat radical approach and others may prefer approaches that fail earlier rather keep running in error conditions to the choices I take which are intended to keep running in most circumstances. Do note that there are definitely cases where it is better to stop than continue in an error condition especially where there is risk of corrupting data, losing money or even more serious consequences. Please choose a domain appropriate response. My recent domain has been a consumer app handling network data and not complicated and corruptible user documents or financial or safety critical and the choices you make about operating in unexpected state are different in each one.

theAnswer = maybeAnswer !! "Or a good alternative"

AssertingNilCoalescing Operator !!

I believe that Swift needs one more operator to deal with optionals, in this post I present my concept to make dealing with them better and safer. It isn't a beginners introduction to optionals or Swift. There are plenty of good ones out there already.

infix operator !! { associativity right precedence 110 }
public func !!<A>(lhs:A?, rhs:@autoclosure()->A)->A {
    assert(lhs != nil)
    return lhs ?? rhs()
}

How this code works will be explained near the end of this post so don't feel you need to understand it now. It adds an additional operator !! to a Swift project for dealing with optionals. It is designed to retain the benefits of strong typing proving the validity of some aspects of the code while documenting the expectation that the left hand argument will not be nil and exposing (in debug builds only) if that belief about the code is wrong.

Unlike other operators it behaves differently in a debug build than a release build. In release builds it is exactly the same as the built in ?? nil coalescing operator return the argument on the left unless it is nil in which case the right hand argument will be returned.

Swift Arrays are not Threadsafe

Swift arrays are not necessarily contiguous blocks of memory (although they may be in some cases so some code may work in some cases but not in others). Some operations may trigger them to be converted to a contiguous block of memory and I believe that is what can particularly cause issues when there is access from multiple threads.

[Update - This post is more popular than I expected (thanks Reddit). I've added some additional notes at the bottom. Also the previous post about optimisation is probably more interesting and valuable.]

Even the code as described here may not work (and I haven't tested at all) when there are multiple reads or writes that access the same elements of the array. All the code I used was either reading from a constant array (safe from multiple threads/queues) or writing into non-overlapping ranges with no reads occurring (only seems safe with the technique described here).

.withUnsafeMutableBufferPointer

Swift Optimisation Again - Slides from Swift London 21st October 2014

Update (23rd October 2014) - Now with video link HERE.

Swift optimisation presentation refined and developed further.

Please contact me if you want the source version and please let me know if you make use of it or find it useful.

Description of the demo from a previous event. Note that for Xcode 6.1 you will need to use the 0x, 1x, 2x and fullSpeedXC61 branches instead of the 0, 1, 2 and fullSpeed branches respectively. Likewise master currently has an Xcode 6.1 version although I will probably merge that to the real master shortly.


Core Location - Significant Location Updates Requires Background Permissions

If you've watched the WWDC video you will already know this but if you just look at the class references it isn't obvious that . iOS 8 introduced the possibility to request permission to access location only while the App is in the foreground which should encourage users to grant permission without fear of being tracked inappropriately however the foreground only mode only works with some of the modes. This slide from the talk (WWDC 2014 What's New In Core Location - Session 706) is the key one: