这是一个2部分问题,第一个问题与此问题类似:Proper usage of the Alamofire's 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
}
}
}
当我看到这个(我在swift的新人,所以请耐心等待> _<)我看到用户对象的操作;他们正在创建一个用户,更新用户等...所以,如果我的模型对象是人,公司,我的模型层中的位置,我会为每个模型对象创建一个路由器吗?
2)当与API大量交互时,我习惯于创建一个"网络管理员" singleton抽象出网络层并保存该API的标头和baseurl。 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")))
这位经理应该使用什么作为我的单身人士?如果是这样,我如何在经理上设置baseurl?另外,如果我使用这个管理器,它/可以和上面显示的路由器结构一起工作(每个模型对象设置它的baseurl和NSURLRquest)吗?如果是这样,你能提供一个简单的例子吗?
我是Alamofire图书馆的新手并且很快。所以,我知道我的理解中有很多漏洞,但我只是想尽力了解最好的东西!任何信息都有帮助感谢。
答案 0 :(得分: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
}
模型对象
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)" }
}
<强>路由器强>
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
}
}
}
使用示例
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)
}
}
现在你必须在这里做一些权衡。首先,模型对象需要符合RouterObject
协议。否则Router
不知道该路径使用什么。此外,您还需要确保使用单个identifier
构建所有路径。如果他们不能,这个设计可能不起作用。最后一个问题是,您无法将baseURL
或OAuthToken
直接存储在Router
枚举中。遗憾的是,通用枚举中尚不支持静态和存储属性。
无论如何,这肯定是避免为每个模型对象创建Router
的有效方法。
Alamofire.Manager.sharedInstance
是否应该用作我的单身NetworkManager
实例?
当然可以这种方式使用。这实际上取决于您的使用案例以及您如何设计网络访问权限。它还取决于您需要多少种不同类型的会话。如果您需要后台会话和默认会话,那么您可能仍需要包含每个自定义NetworkManager
实例的Manager
概念。但是,如果您只是使用默认会话访问网络,则sharedInstance
可能就足够了。
baseURL
单身的Alamofire
如何与Router
模式结合使用?
好问题......下面的代码是如何完成的一个例子。
Alamofire Manager扩展程序
extension Manager {
static let baseURLString = "http://example.com"
static var OAuthToken: String?
}
路由器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
}
}
希望这有助于解决问题。祝你好运!