zhou的博客.

网络库的使用

字数统计: 933阅读时长: 4 min
2019/01/18 Share

为日益衰退的记忆力做点微不足道的补救措施

一套大佬们封装好的网络库用了快一年了,虽然业务来的时候匆匆忙忙依葫芦画瓢还以应付过关,但是真的遇到点复杂的逻辑就有点棘手了。
所以秉着知其然,也要知其所以然的态度,准备对做业务的时候用到过的网络请求有关的方式方法做一个简单的总结,以便老年人不知道什么时候记忆失常的时候可以翻看下,重新拾起当时的点滴。

业务中是怎么使用网络请求的

业务中的网络请求并不是直接用的第三方类似Alamofire库,而是对Alamofire又做了一层二次封装。里面封装的逻辑大致看过一两遍,凭着老年人的理解和记忆能力,好像也并不是一遍两遍就能理解得通的,咱也不能将此归咎于封装库的大佬代码逻辑能力太强,即使封装得再简单点我这木鱼脑袋也是理解不来的。

总得来看,业务中网络请求的调用方式细分的话应该有两种:

  • **在对应的API类里面写好调用接口的URL,在这个类里面写一个发送接口的方法,类似
    1
    2

    调用方式形如: ``` API(params).fetch()

api类实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import UIKit
import RxSwift
import SCCModelKeeper
import SCCSwiftyNetwork

final class BindingAlipayApi: SCCStandardApi {

var mobile = ""
var alipayUserId = ""

override func apiURL() -> String! {
return NSString.dst_leaseconsumerPath("XXXXXXXXXXXXXX")
}

override func apiType() -> HTTPMethod {
return .post
}

func fetch() -> Observable<JSON> {
return apiURL()
.validatableParamters(["mobile": (mobile, {self.mobile.keep("mobile").notEmpty.errors}),
"alipayUserId": (alipayUserId, {self.alipayUserId.keep("authCode").notEmpty.errors})])
.post()
.validData
}
}
  • 另一种方式其实对上一种方式的RX封装

调用方式形如:

  • 不带参数返回JSON
1
2
3
4
5
6
7
8
LogoutApi()
.rx.jsonWithPropertyParams()
.delaySubscription(0.2, scheduler: MainScheduler.instance)
.map({ (JSON) -> JSON in
self.clearUserInfo()
NotificationCenter.default.post(name: Notification.Name(rawValue: kLogoutSuccessNotification), object: self)
return JSON
})

这是在Rx封装的方法中的其中一种调用方式,还有其他几种列举如下:

  • 带参数返回JSON
1
2
3
4
AddClueApi()
.rx.jsonWithParams(_params)
.subscribe()
.disposed(by: bag)
  • 不带参数返回一个model
1
2
3
CarModelSwitchAPI()
.rx
.modelWithPropertyParams(CarModelSwitchModel.self)
  • 带参数返回一个model
1
2
3
OrderListAPI()
.rx
.modelWithParams(["page": page, "pageSize": 20], modelType: OrderList.self, key: nil)
  • 不带参数返回一个model数组
1
2
3
4
5
6
7
public func modelsWithPropertyParams<T: Mappable>(_ modelType: T.Type, key: String? = nil) -> Observable<[T]?> {
return base
.rx
.jsonWithPropertyParams()
.map(valueForKey(key))
.map(=>)
}
  • 带参数返回一个model数组
1
2
3
4
5
6
7
public func modelsWithParams<T: Mappable>(_ params: Parameters = [:], modelType: T.Type, key: String? = nil) -> Observable<[T]?> {
return base
.rx
.jsonWithParams(params)
.map(valueForKey(key))
.map(=>)
}

后面这两种情况用的比较少,平时用的话基本上前面几种就够用了。
大体看上去其实第二种方式和第一种方式也没什么大的区别,好像也就是用第一种方式没有返回一个model的情况,但其实只要model遵循了SCCTransformable协议,第一种调用方式也是可以将获取到的JSON转化为model的。
形如:

1
2
3
4
5
6
7
func fetch() -> Observable<UserInfoModel?> {
return apiURL()
.parameters(["mobile": mobile, "captcha": captcha, "authCode": authCode,"agent": agent,"deviceId": deviceId, "udid": udid, "latitude": latitude, "longitude": longitude, "cityName": cityName, "isForcedLogin": isForcedLogin])
.post()
.validDataUrl
.transform(to: UserInfoModel.self)
}

在UserInfoModel里面遵守协议SCCTransformable,协议方法:

1
2
3
4
5
6
7
8
9
public static func transform(json: [String : Any]?) -> UserInfoModel? {
guard let json = json else { return nil }
return Mapper<UserInfoModel>().map(JSON: json)
}

public static func transformArray(json: [[String : Any]]?) -> [UserInfoModel] {
guard let json = json else { return [] }
return Mapper<UserInfoModel>().mapArray(JSONArray: json)
}

流水账暂时先记到这里,下次尝试把网络库解析一遍。

CATALOG
  1. 1. 为日益衰退的记忆力做点微不足道的补救措施
  2. 2. 业务中是怎么使用网络请求的