It’s that time of the year again! Xcode 7 beta has turned into a stable release, and now we have to adapt our currently developed projects to Swift 2 (I know some of you may already have done this, but personally I never work in a project in progress on beta software, not even Xcode).

So without further ado, lets go through the list of issues I have found, and (hopefully) how to solve them:

Functions that become properties

This is a classic in the evolution of Swift. Take for example the UIView’s function setTranslatesAutoResizingMaskIntoConstraints.

this long-and-ugly-named function is critical if you intend on managing the layout of some of your views programmatically. Setting it to “false” means telling the view not to create automatic constraints based on the view’s auto-resizing properties. This usually means the difference between having a nice, structured view hierarchy layout and crying desperately in front of a mess of crazy Picasso frames.

So, I kind of panicked when I saw the error line “Value of type ‘UIScrollView’ has no member ‘setTranslatesAutoResizingMaskIntoConstraints'” (you never know what evil plans have Apple for its developers ;). But luckily, it was all a matter of changing it to a property syntax.

(Yet another) Different way of getting the length of a string

Strings are easily the weakest point of Swift for me. Apart from the confusion between the different lengths returned by strings with UTF-16 or emoji characters depending on the method you used, the “right” way of getting the length itself has changed from “countElements(string)” to “count(string)”, and now we have this ugly new way, counting the length of the array of characters contained in the string:

myString.characters.count

I don’t really like having to refer to a part or collection inside a string to be able to get its length, but I guess by Swift 3 we’ll have another way of doing this, so not really bothered ;).

Collections now own their search, filter and map functions

This is a logical change for me, and really welcomed in my opinion. Previously in swift, you needed to call a “external” function to manage these kind of operations in collections. So for example, you would say:

if startsWith(myCollection, mySearchedItems) { ... }

This was a really unintuitive syntax, and you got the feeling that these methods were not part of their collections. The reason this was done this way is related to how generics were defined and used for functions in swift. Now everything has changed, and we have the more intuitive syntax:

if myCollection.startsWith(mySearchedItems) {...}

Goodbye join, hello joinWithSeparator

Related to the previous one, and another welcomed change. How would you mentally define a function that joins a set of elements together with a common separator? If you are like me, you would think “get these elements and join them together using this separator”. I think it’s the logical way of defining this. Previously in swift, we had the exact same opposite with “join”: it was something like “get this separator and use it to separate these elements”. Luckily, Apple has changed this function from the string to the elements, and now it makes more sense (in my mind at least). So now instead of:

"-".join(nameComponents)

You would use something like:

nameComponents.joinWithSeparator("-")

Isn’t it beautiful?

No more tags for named properties in methods

It seems that Apple finally has unified the calling of functions (from struct or root level code) with class methods (fair enough), so now you no longer need to specify the tag “#” in functions to make the parameters appear explicitly. It all works like a class method definition now: the first parameter name’s not specified (as it’s supposed to be included in the function’s name) and the rest are.

More accurate properties for good old Cocoa classes

Swift 2 incorporates some tweaking for the interaction with our beloved cocoa classes that I find really nice. For example, something as intuitive as view.subviews returning an array of UIView instances instead of an array of AnyObject. Great!

Some changes in String Indexing & management (but not really good)

The string management in Swift is definitely its weakest point, and the Index concept is usually harder to use than it was with our good old NSStrings. Now, instead of advance(index, distance), you have a Index method called index2 = index1.advancedBy(number). Not really an improvement here…

Protocols have changed

Ok, so “Printable” has become “CustomStringConvertible”, and “DebugPrintable” has become “CustomDebugStringConvertible”. I liked the old names, but I think I’ll get over this change.

But more importantly, my swift classes inheriting from NSObject seem to adapt automatically to protocols such as “Hashable”, “Equatable” and “CustomStringConvertible”, so you don’t need to specify those in your class definition anymore (in fact, doing that will throw an error).

No more stringByAppendingPathComponent

This is a real loss. I don’t quite like managing file paths with NSURLs (I usually end up adding a bug because of the way Cocoa manages filepath URLs), so I have always used stringByAppendingPathComponent. Now I have to use URLByAppendingPathComponent.

We already miss you, bro.

Goodbye NSError, hello try-catch Exceptions

I don’t really like this addition to Swift. One of the big advantages of Swift, for me at last, was the use of optionals as an error handling mechanism thanks to the “if let … {} else {}” construct, and later the inclusion of “guard let = … {} else {}”. I think the try-catch syntax in swift is not quite intuitive to use (the whole point of defining a try block is not having to add “try” sentences on every instruction that can throw an exception), and I think it mixes three error handling paradigms (exceptions, optionals if-let, and the remaining NSError APIs) in a confusing mess.

❤️ Enjoying this post so far?

If you find this content useful, consider showing your appreciation by buying me a coffee using the button below 👇.

Buy me a coffeeBuy me a coffee

Anyway, if you had something like this in the past:

if let contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentsPath, error: nil) {
   ...
}

now you need to write it like this:

do {
   let contents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentsPath)
   // do something with contents
} catch  {
   // handle the error.
}

I also have the feeling that this syntax is somewhat harder to read and requires more code and flow structures (that’s not always a good thing).

Some APIs changed (methods and property definitions)

This is unfortunately another classic in swift changes. For example, the method parser:didStartElement:namespace:qualifiedName:attributes: from the class NSXMLParser (which I happen to use a lot):

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) { ... }

has become:

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { ... }

And the method:

func parser(parser: NSXMLParser, foundCharacters string: String?) {

has become:

func parser(parser: NSXMLParser, foundCharacters string: String) {

No big deal, actually, but implies a lot of time changing bits here and there.

So in summary, some really beautiful and logical changes, and also some minor bothering adjusting to new APIs and language structs here and there, but in general I like this new Swift, and I really hope it will keep on evolving and improving.

One last note: please be careful when letting Xcode to automatic changes for you, and always review them, it’s not quite accurate yet and sometimes it will substitute the wrong range in the line and mess up your code even more.