Providers
使用Moya,你可以通過一個 MoyaProvider
的實例發送所有網絡請求,通過枚舉來指定你要訪問的具體API。在配置你的 Endpoint 之后,你差不多就做好了基礎配置:
let provider = MoyaProvider<MyService>()
簡單配置后,你就可以使用:
provider.request(.Zen) { result in
// `result` is either .Success(response) or .Failure(error)
}
就是這樣!request()
方法返回一個 Cancellable
,這只有一個函數,用於取消請求。 更多關於 Result
的信息請查閱 Examples。
記住,target和provider放在什么地方,完全由你自己決定。可以參考 Artsy's implementation 作為示例。
但不要忘了provider要作為屬性持有,如果中途被釋放的話,會出現"cancelled"` 的錯誤提示。
高級用法
為了解釋清楚 MoyaProvider
的所有結構參數,我們將在下面一個個講解。
endpointClosure:
MoyaProvider
初始化的第一個參數(可選)是一個endpoints閉包,它可以將你的target轉換成具體的Endpoint
實例。讓我們看看應該怎么寫。
let endpointClosure = { (target: MyTarget) -> Endpoint<MyTarget> in
let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
return Endpoint(URL: url, sampleResponseClosure: {.NetworkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
}
let provider = MoyaProvider(endpointClosure: endpointClosure)
注:這樣初始化 MoyaProvider
的時候,不需要再說明target的具體類型,Swift會根據endpointClosure
推斷。
endpointClosure
就是這么簡單。MoyaProvider.DefaultEndpointMapping
有默認實現。
如果需要自定義,請查看 Endpoints 文檔。
requestClosure:
另一個可選的初始化參數是 requestClosure
,可以將 Endpoint
轉換為 NSURLRequest
。同樣,查看 Endpoints 文檔可以獲得更多信息。
stubClosure:
下一個選擇是提供一個 stubClosure
。它返回一個.Never
(默認),或者.Immediate
, 或者.Delayed(seconds)
, 你可以延遲這個stub模擬請求(具體n秒)。例如,.Delayed(0.2)
會把每個stub模擬請求延遲0.2s。 這在單元測試中可以很好的模擬網絡延遲。
這樣的好處是當你需要模擬不同於其他的特殊請求時,可以編寫自己的閉包。
let provider = MoyaProvider<MyTarget>(stubClosure: { target: MyTarget -> Moya.StubBehavior in
switch target {
/* Return something different based on the target. */
}
})
但大多數時候你想對所有targets做同樣的模擬測試,這里有三個 MoyaProvider
的函數可以直接調用用。
MoyaProvider.NeverStub
MoyaProvider.ImmediatelyStub
MoyaProvider.DelayedStub(seconds)
所以,如果你就是要做同樣的模擬測試,可以像下面這樣寫:
let provider = MoyaProvider<MyTarget>(stubClosure: { (_: MyTarget) -> Moya.StubBehavior in return .Immediate })
let provider = MoyaProvider<MyTarget>(stubClosure: MoyaProvider.ImmediatelyStub)
manager:
接下來是 manager
參數。默認的,你可以通過基本設置獲得一個Alamofire.Manager
。
public final class func DefaultAlamofireManager() -> Manager {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
let manager = Alamofire.Manager(configuration: configuration)
manager.startRequestsImmediately = false
return manager
}
有一點需要特別注意:在AF中,構造一個 Alamofire.Request
會默認立即發起請求,包括在單元測試模擬請求的時候。因此在Moya中, startRequestsImmediately
默認設為 false
。
如果你想自定義自己的manager,例如,加上SSL pinning,所有請求都將會通過自定義的manager發送。代碼如下:
let policies: [String: ServerTrustPolicy] = [
"example.com": .PinPublicKeys(
publicKeys: ServerTrustPolicy.publicKeysInBundle(),
validateCertificateChain: true,
validateHost: true
)
]
let manager = Manager(
configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies)
)
let provider = MoyaProvider<MyTarget>(manager: manager)
plugins:
最后,你可能需要一個 plugins
數組。它們在發起請求之前和收到返回值之后回調。這兒已經有一小部分plugins:一個是network activity (NetworkActivityPlugin
), 一個打印輸出所有network activity (NetworkLoggerPlugin
),另一個是 HTTP Authentication.
例如,你只需要將 [NetworkLoggerPlugin()]
作為參數傳遞給 Endpoint
的plugins
,就可以允許log。注意:plugin也可以配置,比如 NetworkActivityPlugin
需要一個networkActivityClosure
參數。配置代碼如下:
public final class NetworkActivityPlugin: PluginType {
public typealias NetworkActivityClosure = (change: NetworkActivityChangeType) -> ()
let networkActivityClosure: NetworkActivityClosure
public init(networkActivityClosure: NetworkActivityClosure) {
self.networkActivityClosure = networkActivityClosure
}
// MARK: Plugin
/// Called by the provider as soon as the request is about to start
public func willSendRequest(request: RequestType, target: TargetType) {
networkActivityClosure(change: .Began)
}
/// Called by the provider as soon as a response arrives
public func didReceiveResponse(data: NSData?, statusCode: Int?, response: NSURLResponse?, error: ErrorType?, target: TargetType) {
networkActivityClosure(change: .Ended)
}
}
networkActivityClosure
是一個閉包,你可以在請求開始或結束時進行一些操作。和network activitiy indicator 一起很好用。
注意這個閉包的參數 (change: NetworkActivityChangeType) -> ()
,你只能在request .Began
或者 .Ended
的時候使用,無法提供請求的其他任何細節。
轉載請注明出處http://www.cnblogs.com/liuliuliu/p/5627650.html,並注明轉載。
原文鏈接
翻譯: bibibi_liuliu
聯系方式: 395985239@qq.com