单身模式和正确使用Alamofire的URLRequestConvertible

Sno*_*col 17 swift alamofire

这是一个2部分问题,第一个问题与此问题相似:正确使用Alamofire的URLRequestConvertible.但我还需要一些帮助!

1)我是否为模型层中的每个模型创建了一个实现URLRequestConvertible的枚举路由器?

alamofire github页面提供了我在这里复制的路由器示例:

  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: NSURLRequest {
        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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我看到这个(我是swift的新人,所以请耐心等待> _ <)我看到用户对象的操作; 他们正在创建一个用户,更新用户等...所以,如果我的模型对象是人,公司,我的模型层中的位置,我会为每个模型对象创建一个路由器吗?

2)当与API进行大量交互时,我习惯于创建一个"网络管理器"单例来抽象出网络层并保存该API的标头和基础.alamofire有一个"经理"在这里描述:

像Alamofire.request这样的顶级便捷方法使用Alamofire.Manager的共享实例,该实例配置了默认的NSURLSessionConfiguration.因此,以下两个陈述是等效的:

Alamofire.request(.GET, "http://httpbin.org/get")

let manager = Alamofire.Manager.sharedInstance
manager.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/get")))
Run Code Online (Sandbox Code Playgroud)

这位经理是我应该用作我的单身人士吗?如果是这样,我如何在经理上设置baseurl?另外,如果我使用这个管理器确实/可以与上面显示的路由器结构一起工作(每个模型对象设置它的baseurl和NSURLRquest)?如果是这样,你能举一个简单的例子吗?

我是Alamofire图书馆的新手,很快.所以,我知道我的理解中存在很多漏洞,但我只是想了解我能做到的最好的事情!任何信息都有帮助 谢谢.

cno*_*oon 32

这些是一些非常好的问题.让我试着依次回答每一个问题.

我是否为模型层中的每个模型创建了一个实现URLRequestConvertible的枚举路由器?

这是一个很好的问题,遗憾的是没有一个完美的答案.肯定有一些方法可以扩展Router模式以适应多种对象类型.第一种选择是添加更多案例以支持另一种对象类型.然而,当你得到超过6或7个病例时,这会很快变得毛茸茸.你的switch语句刚开始失控.因此,我不推荐这种方法.

解决这个问题的另一种方法是将泛型引入Router.

RouterObject协议

protocol RouterObject {
    func createObjectPath() -> String
    func readObjectPath(identifier: String) -> String
    func updateObjectPath(identifier: String) -> String
    func destroyObjectPath(identifier: String) -> String
}
Run Code Online (Sandbox Code Playgroud)

模型对象

struct User: RouterObject {
    let rootPath = "/users"

    func createObjectPath() -> String { return rootPath }
    func readObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func updateObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func destroyObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
}

struct Company: RouterObject {
    let rootPath = "/companies"

    func createObjectPath() -> String { return rootPath }
    func readObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func updateObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func destroyObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
}

struct Location: RouterObject {
    let rootPath = "/locations"

    func createObjectPath() -> String { return rootPath }
    func readObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func updateObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
    func destroyObjectPath(identifier: String) -> String { return "\(rootPath)/\(identifier)" }
}
Run Code Online (Sandbox Code Playgroud)

路由器

let baseURLString = "http://example.com"
var OAuthToken: String?

enum Router<T where T: RouterObject>: URLRequestConvertible {
    case CreateObject(T, [String: AnyObject])
    case ReadObject(T, String)
    case UpdateObject(T, String, [String: AnyObject])
    case DestroyObject(T, String)

    var method: Alamofire.Method {
        switch self {
        case .CreateObject:
            return .POST
        case .ReadObject:
            return .GET
        case .UpdateObject:
            return .PUT
        case .DestroyObject:
            return .DELETE
        }
    }

    var path: String {
        switch self {
        case .CreateObject(let object, _):
            return object.createObjectPath()
        case .ReadObject(let object, let identifier):
            return object.readObjectPath(identifier)
        case .UpdateObject(let object, let identifier, _):
            return object.updateObjectPath(identifier)
        case .DestroyObject(let object, let identifier):
            return object.destroyObjectPath(identifier)
        }
    }

    // MARK: URLRequestConvertible

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

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

        switch self {
        case .CreateObject(_, let parameters):
            return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0
        case .UpdateObject(_, _, let parameters):
            return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0
        default:
            return mutableURLRequest
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

示例用法

func exampleUsage() {
    let URLRequest = Router.CreateObject(Location(), ["address": "1234 Road of Awesomeness"]).URLRequest
    Alamofire.request(URLRequest)
        .response { request, response, data, error in
            print(request)
            print(response)
            print(data)
            print(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,你必须在这里进行一些权衡.首先,您的模型对象需要符合RouterObject协议.否则,Router不知道该路径使用什么.此外,您需要确保所有路径都可以使用单个路径构建identifier.如果他们不能,这个设计可能不起作用.最后一个问题是你无法存储baseURLOAuthToken直接在Router枚举中.遗憾的是,通用枚举中尚不支持静态和存储属性.

无论如何,这肯定是避免Router为每个模型对象创建一个有效的方法.

应该Alamofire.Manager.sharedInstance用作我的单例NetworkManager实例吗?

它当然可以以这种方式使用.这实际上取决于您的使用案例以及您如何设计网络访问权限.它还取决于您需要多少种不同类型的会话.如果您需要后台会话和默认会话,那么您可能仍需要NetworkManager包含每个自定义Manager实例的概念.但是,如果您只是使用默认会话访问网络,则sharedInstance可能就足够了.

如何baseURLAlamofire单身人士与Router模式结合使用?

好问题......下面的代码是如何完成的一个例子.

Alamofire Manager扩展

extension Manager {
    static let baseURLString = "http://example.com"
    static var OAuthToken: String?
}
Run Code Online (Sandbox Code Playgroud)

路由器URLRequestConvertible更新

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

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

    switch self {
    case .CreateObject(_, let parameters):
        return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0
    case .UpdateObject(_, _, let parameters):
        return Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: parameters).0
    default:
        return mutableURLRequest
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这有助于解决问题.祝你好运!