What’s cool in Swift

Swift Intro I’ve been programming Objective C since 2008 at tapwork. I always thought I need to blog about Objective C, iOS and Mac. But time is an issue. My public results were some code and little projects I share on GitHub like the super old non-ARC PunchScrollView. Now with Swift things changed a lot. It’s time to start something new and fresh. From now on I’ll try blogging continuously. The programming language will be mainly Swift. But sometimes it’s good to jump back to Objective C to compare things. I know there are already good intros to Swift here, hereFAQ & Apple itself … Check out these resources! Today I start with things in Swift I personally find really important and worth to understand what is going on.

  1. Type inference & safety
  2. Optionals
  3. generics 
  4. structs 
  5. Overriding functions
  6. Downcast / type check
  7. A lot more ….

 

1. Type inference & safety

In Objective C you need to declare the type for your variable

NSString* myString = @"John";
NSInteger age = 64;

Swift has type inference. That means that Swift is checking the type for you.

var myString = "John"
var age = 64

Swift is also type safe. Things likes this won’t compile.

age = myString

Age is an Integer type, myString is a String type. The type mismatch will not compile “…This enables you to catch and fix errors as early as possible in the development process.” Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/de/jEUH0.l

 

2. Optionals

In Objective C we send messages to nil, we can return nil, properties will be initialized with nil, we can use nil in stringFormats (which results in “null”). We can use nil almost everywhere in Objective C. Almost does not mean always. And all those exceptions in Objective C make the usage of nil unsafe and unclear: Containers can’t contain nil and  more Cocoa frameworks can’t handle nil too. Developers created categories like: [array addSafeObject:nil] which checks for nil. In Objective C the nil handling is not really consistent and it’s implicit. Now with Swift things changed. The nil handling became explicit. All variables and properties must have a value, except for optional marked variables. Only optional variables can contain nil. In Swift nil is not a pointer to nothing like in Objective C. In Swift nil tells us that there is no value. Also doubles can be nil. The developer needs to say when the variable can contain nil or the function is allowed to return nil. This is called Optional.

var myOptionalString:String?

You write a question mark after the type to mark the variable optional. Using the optional variable can’t be done directly. Also you need to unwrap the optional with the exclamation mark explicitly.

println("Result: "+myOptionalString)
println("Result: "+myOptionalString!)

The first println() will not compile, because we are not unwrapping the optional.Second println() will compile, but causes a run-time error (crash) when myString is nil. Therefore Apple enforces us to check for nil.

if myOptionalString {
    println("Result: "+ myOptionalString!)
}

But Swift provides us a better pattern: Conditional unwrapping optionals:

var myOptionalString:String?
if let myString = myOptionalString {
    println("Result: "+ myString)
}

We are checking for nil and conditionally unwrap the myOptionalString to a local constant string myString in one line: if let myString = myOptionalString This makes the usage of optionals and the unwrapping easier and safer.Sometimes you may encounter a pattern like this:

var firstname : String!
var lastname : String!

init(firstname : String, lastname : String) {
  self.firstname = firstname
  self.lastname = lastname
}

Here firstname and lastname are implicitly unwrapped optionals. You write an exclamation mark instead of the question mark after the type. To quote the Swift book: “Sometimes it is clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it is useful to remove the need to check and unwrap the optional’s value every time it is accessed, because it can be safely assumed to have a value all of the time.” It short words: You don’t need to unwrap the optional (by writing ! at the end of the variable) when you access the variable. This makes it easier, but dangerous too (can result in a run-time error if nil). You will see a lot of implicit unwrapped variables in initializers when you start working with the Cocoa classes like NSURL:

init(string URLString: String!, relativeToURL baseURL: NSURL!)

This allows you to pass nil into the initializer. The explicit use of nil makes it safer and clearer. A lot of crashes in Objective C are the results of wrong nil handling. Optionals will not only be used with variables or initializers. The return type for a function can also be optional.

func memberNameForAge(age : Int) -> String? {
    if (age >= 65) {
        return "Golden Age"
    }

    return nil
}
var memberName = memberNameForAge(67) // memberName is nil if age is below 65

Also you can use optionals to check nested properties for nil. Called Optional Chaining


if let lastname = person.name?.lastname {
   println("The lastname is: "+lastname
}

Optional chaining checks each property marked by the question mark. In this case if name is nil, the chain will stop there and doesn’t go on to lastname. Optional chaining is bit like “respondsToSelector” in Objective C. Apple says: “You use optionals in situations where a value may be absent…Optionals are an example of the fact that Swift is a type safe language.” Excerpt From: Apple Inc. “

 

3. generics

As mentioned above Swift is strict about types. How you can build functions in Swift that does not care about the type you pass as parameter and return? This is where generics will be your friend. Imagine a code that logs some stuff for arbitrary values:

func logDouble(value:Double) -> Double {

    println("log message: \(value)")

    return value
}

This is fine for a double type. But it does not work with Integer or Bool. The same code as above with generics:

func logValue(value:T) -> T {

    println("log message: \(value)")

    return value
}

The magic keyword is “T” here. “T” is not a type, it’s just a placeholder for any type. Generics take any kind of type. It checks that all of your parameters and return values are of the same type, So it ensures type safety. Generics are used widely in Swift. For example: Optionals are generic enums. The Swift array is also just a generic struct, which enables type safety for objects in the array (all objects in the array are of the same type)

struct Array : MutableCollection, Sliceable {
...
}

You can also be more specific using protocols after the “T” placeholder.

func sort(array: T[]) -> T[]

The Swift standard sort function accepts a type that conforms to a specific protocol: Comparable. Apple says: “Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner. Generics are one of the most powerful features of Swift, and much of the Swift standard library is built with generic code. ” It’s working like the instancetype. It gives you some dynamic power we all know from Objective C, but with type safety.

 

4. structs & enums

really cool..Structs & enums are more than the standard C struct or enum. They can have functions, initializer, dynamic properties. Structs can be seen as little classes with better performance (compared to classes). Swift uses a lot of structs and enums throughout their standard Swift library. Integer, Array, Dictionary, float, Bool, String are structs (Array has some special behaviors). The optional is build of an enum. Structs are value types, classes are reference types. This means that structs will be copied when you assign them or pass them around. A new “instance” will be created. Classes will still reference to the original instance.

 

5. Overriding functions

If you want to override a function like viewDidLoad (or even properties) in Swift you need add override in front of the function. This is super cool and avoids many bugs with overriden functions or properties. It catches any typos in the overriden function. Because you have to be explicit with overriding functions you can’t override functions accidentally.

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

 

6. Downcast / type check

Downcast with the keyword as. Type checking with the keyword is (replaces the old isKindOfClass) You can downcast with conditionals and optionals as follows:

for item in library {
    if let movie = item as? Movie {
        println("Movie: '\(movie.name)', dir. \(movie.director)")
    } else if let song = item as? Song {
        println("Song: '\(song.name)', by \(song.artist)")
    }
}

 

7. A lot more…

There is much more cool stuff..

  • Properties don’t have a member variable as backing store, which avoids confusing and many bugs.
  • functions are closures (just with a name)
  • Nested  (closures again) – they have access to variables in outer functions
  • Pass and return functions
  • return tuple values
  • String / Array mutability is made easy just by a +
  • ….much more (I’ll try to keep posting in separate posts)

And check out the sites I mentioned above

and WWDC 2014 Videos, Swift iBook

Besides the cool new stuff, there are things I will miss:

  • Runtime fun like swizzling, Objc_setAssociatedObject
  • The header file
  • Key – Value – Coding

Leave a Reply

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