- 简化了网络请求
- 方便维护
- 方便单元测试
使用Moya,项目中网络请求的部分可能长这样。
点击查看官方教程
Moya发送简单的网络请求
枚举类型需满足TargetType
协议
public protocol TargetType {
var baseURL: NSURL { get }
var path: String { get }
var method: Moya.Method { get }
var parameters: [String: AnyObject]? { get }
var sampleData: NSData { get }
}
实现一个枚举代码如下:
(sampleData是接收到的数据实例)
import Moya
enum Joke {
case Image(count:Int,page:Int)
case Video(count:Int,page:Int)
case latest(count:Int,page:Int)
}
extension Joke : TargetType{
var baseURL: NSURL {
return NSURL(string: "http://m2.qiushibaike.com/article/list")!
}
var path: String {
switch self {
case .Image:
return "/imgrank"
case .Video:
return "/video"
case .latest:
return "/latest"
}
}
var method: Moya.Method {
return .GET
}
var parameters: [String: AnyObject]? {
return ["page":"1","count":"4"]
}
var sampleData: NSData {
return "{\"login\": \"xiaoMing\", \"id\": 100}".dataUsingEncoding(NSUTF8StringEncoding)!
}
}
现在就可以发送简单的网络请求了:
-
定义一个全局变量
MoyaProvider
(防止自动释放,网络请求被cancel掉)let provider = MoyaProvider<Joke>()
发送网络请求(暂且不管返回的
result
)
provider.request(Joke.Image(count: 1, page: 1)) { (result) -> () in
print(result)
}
MoyaProvider的初始化
我们观察下MoyaProvider
的初始化方法. MoyaProvider初始化都是有默认值的
public init(endpointClosure: EndpointClosure = MoyaProvider.DefaultEndpointMapping,
requestClosure: RequestClosure = MoyaProvider.DefaultRequestMapping,
stubClosure: StubClosure = MoyaProvider.NeverStub,
manager: Manager = MoyaProvider<Target>.DefaultAlamofireManager(),
plugins: [PluginType] = []) {
...
参数:
-
EndpointClosure
- 可以对请求参数做进一步的修改,如可以修改
endpointByAddingParameters
endpointByAddingHTTPHeaderFields
等
- 可以对请求参数做进一步的修改,如可以修改
RequestClosure
你可以在发送请求前,做点手脚. 如修改超时时间,打印一些数据等等StubClosure
可以设置请求的延迟时间,可以当做模拟慢速网络Manager
请求网络请求的方式。默认是Alamofire[PluginType]
一些插件。回调的位置在发送请求后,接受服务器返回之前
EndpointClosure
public class MoyaProvider<Target: TargetType> {
/// Closure that defines the endpoints for the provider.
public typealias EndpointClosure = Target -> Endpoint<Target>
...
默认的实现方式 (MoyaProvider.DefaultRequestMapping
)
let myEndpointClosure = { (target: Joke) -> Endpoint<Joke> in
let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
return Endpoint(
URL: url,
sampleResponseClosure:
{.NetworkResponse(200, target.sampleData)},
method: target.method,
parameters: target.parameters
)
}
还可以通过Endpoint
的初始化方法指定 parameterEncoding
、httpHeaderFields
。parameterEncoding 可以是.URL
, .JSON
, .PropertyList
, and .Custom
,这些都是和Alamofire parameter encodings对应的.
额外的,moya提供的添加httpHeaderFields的方法.
let myEndpointClosure = { (target: Joke) -> Endpoint<Joke> in
let url = target.baseURL.URLByAppendingPathComponent(target.path).absoluteString
let endpoint: Endpoint<GitHub> = Endpoint<GitHub>(
URL: url(target),
sampleResponseClosure: {.NetworkResponse(200, target.sampleData)},
method: target.method,
parameters: target.parameters
)
return endpoint.endpointByAddingHTTPHeaderFields(["APP_NAME": "MY_AWESOME_APP"])
}
RequestClosure
let requestClosure = { (endpoint: Endpoint<Joke>, done: NSURLRequest -> Void) in
let request = endpoint.urlRequest
/**
* 在这儿可以按你的需要,对网络请求做些修改
如修改超时时间
let requestMut = endpoint.urlRequest.mutableCopy() as! NSMutableURLRequest~~
requestMut.timeoutInterval = 10
*/
done(request)
}
manager
默认是Alamfire,也可以自己定制。如添加ssl
等。 具体 点击
PluginType
默认集成了3个
- NetworkLoggerPlugin
- NetworkActivityPlugin
- HTTP Authentication
例如发送请求就显示菊花
let networkPlugin1 = NetworkActivityPlugin { (change) -> () in
print("networkPlugin \(change)")
switch(change){
case .Ended:
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
case .Began:
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}
}
点击查看官方教程