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
private
access modifiers have migrated to Swift 3’sfileprivate
.private
now means the member isn’t accessible outside of the element it’s defined in, whilefileprivate
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 becomeURL
. Although interestingly enoughNSMutableURLRequest
still retains the NextStep prefix.someObject.dynamicType
has 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
.NSOperationQueue
has 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.uppsercaseString
has 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 samefunc
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 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
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 offileprivate
operator implementions for you in every file using optional variables. Annoyingly it doesn’t place afixme
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 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.