Swift 3 Migration
• Mark Eschbach
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
privateaccess modifiers have migrated to Swift 3’sfileprivate.privatenow means the member isn’t accessible outside of the element it’s defined in, whilefileprivateis 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. NSURLhas becomeURL. Although interestingly enoughNSMutableURLRequeststill retains the NextStep prefix.someObject.dynamicTypehas becometype(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 becomeUIApplication.shared.NSOperationQueuehas becomeOperationQueue. Additionally to access to the main queue it’s turned frommainQueue()tomain. I suppose in the context of Swift this makes sense.- To store data in
[String:AnyObject]we cast toAnyObject?. I wonder if this is an artifact of migration wizard or if there are new typing rules aroundAnyObject. String.uppsercaseStringhas becomeString.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 samefuncdeclaration. 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 thefunc. 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
NSDatestill 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.intValueinstead 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
Comparableexpressions. It kindly generates a series offileprivateoperator implementions for you in every file using optional variables. Annoyingly it doesn’t place afixmeabove 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 becomeTimer.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.