I did migration from Swift2 to Swift3.0 in my app called Esafeed. I’ll take a note for future myself and may be others. I hope it’ll be useful for you.

In my opinion, if your app is small compared to other apps, it may be better to skip Swift2.3. In short, use Swift3.0. At first, I’m afraid of skipping Swift2.3, but it’s easier than I thought. Give it a try!

The following steps are just 12 steps toward Migration to Swift3.0. Let’s go at ease.


1. Create a feature/swift3.0 or swift3.0 branch as you like

For me, to create a branch make me inevitable. It’s like a putting pressure on myself.

2. Use automatic converting

Be careful of choosing buttons. convert button’s position is different. That’s it.

3. Set OS_ACTIVITY_MODE (Option)

I set OS_ACTIVITY_MODE disable in order not to show many redundant logs in Xcode console.

Mode

4. Update libraries in response to Swift3.0

Check each library, and then choose swift3.0 branch, master including Swift3.0 or swift3. You may find an obsolete library, so it may be time to abandon an old library.

My Cartfile is like this for now (I only use Carthage in this app)

github "ishkawa/APIKit" ~> 3.0
github "Hearst-DD/ObjectMapper" ~> 2.0.0
github "SwiftyBeaver/SwiftyBeaver"
github "ReactiveX/RxSwift" "3.0.0-beta.1"
github "delba/TextAttributes"
github "sberrevoets/SDCAlertView" ~> 7.0
github "venmo/Markingbird" ~> 1.13
github "onevcat/Kingfisher"
github "duemunk/Async" "feature/Swift_3.0"
github "kishikawakatsumi/KeychainAccess"
github "radex/SwiftyUserDefaults"
github "realm/realm-cocoa"
github "ArtSabintsev/Siren"
github "delba/SwiftyOAuth"

In some libraries(In the case of APIKit), I faced a problem. In Swift2.0, I used HTTPHeaderFields as a property.

protocol EsaRequestType: RequestType {}

extension EsaRequestType {
    ...
    var HTTPHeaderFields: [String: String] {
        ...
        return [
          "Authorization": "Bearer \(token)"
        ]
    }
    ...
}

In APIKit, HTTPHeaderFields was defined in Request extension like this.

// In APIKit
public extension Request {
    ...
    public var HTTPHeaderFields: [String: String] {
        return [:]
    }
    ...
}

HTTPHeaderFields became headerFields, so there was no warnings and no errors in original codes. I could build for sure. But APIKit never use HTTPHeaderFields.

In Swift3.0,

protocol EsaRequestType: RequestType {}

extension EsaRequestType {
    ...
    // var HTTPHeaderFields : [String: String] will be OK, but...
    // You have to change here!!
    var headerFields: [String: String] {
        ...
        return [
          "Authorization": "Bearer \(token)"
        ]
    }
    ...
}
// In APIKit
public extension Request {
    ...
    public var headerFields: [String: String] {
        return [:]
    }
    ...
}

I have to notice that change by myself. It means if you miss the change, your application doesn’t work correctly. From this example, I think you should carefully read library’s migration guides. I needed to have warning or error

APIKit 2 Migration Guide
APIKit 3 Migration Guide

5. Check entitlements

For instance, Keychain needs entitlements. Check apple official reference in details.
About Entitlements

6. Change libraries if needed (Option)

As I said, I changed some libraries for migration.
ex) In OAuth authentication, I used to use OAuthSwift, but I replaced OAuthSwift with SwiftyOAuth.

7. Fix red errors

This part is tough for me at first, because it needs many manual and boring works. In a different perspective, I learned a lot of new features.
You can confirm build success in here.

8. Fix warnings as possible (Option)

I don’t like remaining any warnings. Some warnings said that this will be deprecated in the future.
Build success without any warnings.

9. Check diff mainly generated by Xcode

I don’t believe any generated codes. I did very careful review based on Github PR step by step. In my project, 1,977 lines (+1,044 -933) changed. Sometimes I found some strange convert. Xcode has done a great job :+1:

10. Refer to API Design Guidelines

I think this is a really important point. This is my real examples.

// Swift2
func requestWithPage(page: Int) -> MembersRequest {

// Swift3.0
func request(withPage page: Int) -> MembersRequest {

// Swift2
func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) -> Response? {

// Swift3.0
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Status {

// Swift2
UINavigationBar.appearance().tintColor = .whiteColor()

// Swift3.0
UINavigationBar.appearance().tintColor = UIColor.white

// Swift2
enum Section: Int, Enumerable {
  case Profile = 0
  ...
}

// Swift3.0
enum Section: Int, Enumerable {
  case profile = 0
  ...
}

I kept in mind to select good first labels.

11. Fix CI and release process(like a Fastlane)

Skip the details because there are a ton of options.

12. Merge Swift3.0 branch

This is a short and brief memo. If you don’t yet, I recommend updating right now. Enjoy with Swift3.0:)

I’m still not used to writing codes like Swift3.0. @volbap said

A piece of advice: Read the Swift 3 API design guidelines once and again. Every day in the morning, if necessary, until you get used to the new way of writing Swift code.

That makes sense. If you know about something that I missed, please leave a comment.

Ref