Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
250 views
in Technique[技术] by (71.8m points)

ios - How to migrate Alamofire router class to Swift 3?

Does anybody know how to change this entire approach to Swift 3? At this moment I have something very similar to this working OK on Swift 2.2 but now I'm trying to change that to Swift 3.

I am getting some errors with the "URLRequestConvertible", with the Alamofire.Method (that I changed to HTTPMethod and now is working) and also with the parameter encoding, besides that I'm not conforming the entire protocol.

I'm waiting for guidance from engineers at Alamofire, but I am looking to see what I can accomplish in the meantime.

enum Router: URLRequestConvertible {
static let baseURLString = "http://example.com"
static var OAuthToken: String?

case CreateUser([String: AnyObject])
case ReadUser(String)
case UpdateUser(String, [String: AnyObject])
case DestroyUser(String)

var method: Alamofire.Method {
    switch self {
    case .CreateUser:
        return .POST
    case .ReadUser:
        return .GET
    case .UpdateUser:
        return .PUT
    case .DestroyUser:
        return .DELETE
    }
}

var path: String {
    switch self {
    case .CreateUser:
        return "/users"
    case .ReadUser(let username):
        return "/users/(username)"
    case .UpdateUser(let username, _):
        return "/users/(username)"
    case .DestroyUser(let username):
        return "/users/(username)"
    }
}

// MARK: URLRequestConvertible

var URLRequest: NSMutableURLRequest {
    let URL = NSURL(string: Router.baseURLString)!
    let mutableURLRequest = NSMutableURLRequest(URL: URL.URLByAppendingPathComponent(path))
    mutableURLRequest.HTTPMethod = method.rawValue

    if let token = Router.OAuthToken {
        mutableURLRequest.setValue("Bearer (token)", forHTTPHeaderField: "Authorization")
    }

    switch self {
    case .CreateUser(let parameters):
        return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0
    case .UpdateUser(_, let parameters):
        return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0
    default:
        return mutableURLRequest
    }
}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

EDITED for Alamofire 4.0.0 release (updated URLRequestConvertible protocol with throwing capabilities):

A lot has changed in Swift 3 and you should first really read up on all the changes, maybe starting at http://swift.org. Here's the fixed code:

enum Router: URLRequestConvertible {
    static let baseURLString = "http://example.com"
    static var OAuthToken: String?
    
    case createUser([String: AnyObject])
    case readUser(String)
    case updateUser(String, [String: AnyObject])
    case destroyUser(String)
    
    var method: Alamofire.HTTPMethod {
        switch self {
        case .createUser:
            return .post
        case .readUser:
            return .get
        case .updateUser:
            return .put
        case .destroyUser:
            return .delete
        }
    }
    
    var path: String {
        switch self {
        case .createUser:
            return "/users"
        case .readUser(let username):
            return "/users/(username)"
        case .updateUser(let username, _):
            return "/users/(username)"
        case .destroyUser(let username):
            return "/users/(username)"
        }
    }
    
    func asURLRequest() throws -> URLRequest {
        let url = URL(string: Router.baseURLString)!
        var urlRequest = URLRequest(url: url.appendingPathComponent(path))
        urlRequest.httpMethod = method.rawValue
        
        if let token = Router.OAuthToken {
            urlRequest.setValue("Bearer (token)", forHTTPHeaderField: "Authorization")
        }
        
        switch self {
        case .createUser(let parameters):
            return try Alamofire.JSONEncoding.default.encode(urlRequest, with: parameters)
        case .updateUser(_, let parameters):
            return try Alamofire.URLEncoding.default.encode(urlRequest, with: parameters)
        default:
            return urlRequest
        }
    }
}

The main changes for Swift 3 are :

  • enum cases are now lowercase and you should adopt it too.
  • Variable names now start with lowercase, even if it's an abbreviation like "URL". That why the protocol requires var urlRequest and not var URLRequest (and it would conflict with the next point)
  • Bye-bye NS prefix in many places. NSURLRequest and NSMutableURLRequest are now URLRequest, NSURL is URL, etc.
  • How you name your functions and parameters is now a lot less redundant and more natural. See for example how URLByAppendingPathComponent has changed.

And as for Alamofire v4 :

  • There's a new ParameterEncoding protocol to encoding parameters yourself is different but more versatile
  • MANY other changes which have no impact here but you sure have to read about them too.

And final word of advice : avoid migrating to unreleased versions of a programming language or API if it's time-sensitive. Swift 3 won't budge much but Alamofire still might! For example the ParameterEncoding protocol is only two days old! (EDIT: and indeed it changed since, now in its final version above)

Cheers


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...