I’m reading through some commits in preparation of receiving a massive pull request for migrating the iOS codebase at work from Swift 2.3 to Swift 3. The first interesting element I encountered was a new access modifier. According a StackOverflow and the linked Swift proposal they introduced a new access modifier. Public is no longer extensible by default, it must be explicitly marked open for modification. It will be interesting to see how this could be useful as an application client of the iOS platform.

After the Swift 3 migration wizard was run, it looks like the following changes were made:

  • NSDate became Date
  • Methods without a label got the default _ indicating now label.
  • Enumeration name to string conversion became String( describing: enumValue )
  • Enumeration convention is all lower case now.
  • Many Swift 2 private access modifiers have migrated to Swift 3’s fileprivate. private now means the member isn’t accessible outside of the element it’s defined in, while fileprivate is accessible only within the file it’s defined in. This will be useful for creating test assertions, and I feel like I’ve encoutnered a need for this elesewhere.
  • NSURL has become URL. Although interestingly enough NSMutableURLRequest still retains the NextStep prefix.
  • someObject.dynamicType has become type(of: someObject). It feels like they are trying to be more functional here or it’s a throw back to C++’s typing to runtime interface.
  • UIApplication.sharedInstance() has become UIApplication.shared.
  • NSOperationQueue has become OperationQueue. Additionally to access to the main queue it’s turned from mainQueue() to main. I suppose in the context of Swift this makes sense.
  • To store data in [String:AnyObject] we cast to AnyObject?. I wonder if this is an artifact of migration wizard or if there are new typing rules around AnyObject.
  • String.uppsercaseString has become String.uppercased(). This feels kind of strange; I wonder what the rational was. I would like to track down a document for why the changed some fields to methods and vice-versa.
  • In one case it removed an existing label and didn’t add the _ back in. Additionally it removed labels on closures within the same func declaration. I’m slightly confused about that one.
  • @noescape – I’ve seen references to this before. KRAKENDEV’s Hipster Swift claims this is to inform the compiler the closure will be utilized in the body of the func. The wizard has marked several closures which are utilized in callbacks of the method they are passed in. I hope this doesn’t cause much issue.
  • Interesting NSDate still exists and we can invoke methods on it. Either that or we’ll get a compliation error.
  • An all capitalized enumeration value has been entirely lowercased.
  • A [String:AnyObject] dictionary now uses .intValue instead of .integerValue
  • There are a few entities in our system which have been ported to Swift that need to drop the extension of NSObject.
  • Some integer constants get explicitly typed such as 0 as Int32
  • Swift 3 dropped support of comparison of conditional Comparable expressions. It kindly generates a series of fileprivate operator implementions for you in every file using optional variables. Annoyingly it doesn’t place a fixme above the offending line. Known operators which it complains about: >, <, >=.
  • Probably not new however a postfix operator ? wil match values but not nil.
  • NSTimer -> Timer
  • Many methods have moved apart of it’s name into it’s label. For example: NSTimer.scheduleTimerWithInterval(...) has become Timer.scheduledTimer(timeInterval:...)

So many changes, this doesn’t even capture everything I saw. Some of them weren’t even worth commenting on. Definitely would have been redicously tedious to have to do this by hand, but really? The Swift team at Apple should be a least a little concerned about Swift 3 migrations. There are some cryptic statemetns I’ll need to look up like ??. but I’ll have to come back to it later.