swift自己封装一个简易网络请求,逃逸闭包的一个小坑

关于网络请求,swift版本的最多的就是alamofire,是afn的swift版本,git上有详细用法,这里就不列举了,平时网络请求也用不到这么大的框架,用URLSession足够了,就自己写了一个简易的网络请求

我定义了一个类似oc中block的东西,swift中叫闭包(closure)


typealias networkSuccessClosuse = (_ data:Data?, _ response:URLResponse?, _ error:Error?) -> Void

然后定义了一个枚举值,来表示请求的类型(POST, GET等,可以自己添加,我这里只写了这两个)


enum netMethod:String {

case GET = "get"

case POST = "post"

}

一般的工具类,我们都会设置一个单例来作为访问接口的唯一对象,这里我也写了一个单例(swift的单例比较直观)


static let netWorkManager = NetWorkTool()

private override init() {

接下来就是用URLSessino请求数据了


public func netWork(url:String, method:netMethod, paramates:[String : AnyObject]?, result:@escaping networkSuccessClosuse) {

var i = 0

var urlString = url

let session:URLSession = URLSession.shared

var request:URLRequest = URLRequest(url: URL.init(string: url)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 10)

request.httpMethod = method.rawValue

switch method {

case .GET:

if let para = paramates {

for (key, value) in para {

if i == 0 {

urlString += "?\(key)=\(value)"

}else {

urlString += "&\(key)=\(value)"

}

i += 1

}

}

request.url = URL.init(string: urlString)

break

case .POST:

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

do {

let para:Data = try JSONSerialization.data(withJSONObject: paramates!, options: JSONSerialization.WritingOptions.prettyPrinted)

request.httpBody = para

}catch {

}

break

default:

print("请求类型有误")

break

}

session.dataTask(with: request, completionHandler: { (data, response, error) in

if error == nil {

result(data!, response, error)//跟oc中block存储数据一样

}else {

print("请求出错")

return

}

}).resume()

}

这就是我自己写的一个简易的网络请求类,用tableview展示数据的时候,你会发现,在请求数据之后,model已经加入了数组中,你也在之后写了reloaddata,但是没有结果,你点击一下或者拉一下会出现结果,就像这样写


self?.data_ary.append(model)

self?.tb.reloadData()

导致这个结果的原因就是,URLSession是异步执行的,异步函数实在开始执行的时候,这个函数就返回了,但是逃逸闭包是在异步执行完成之后,这个闭包才会返回,你这样写,其实跟没写是一样的,tableview不会刷新数据,最简单的方法就是,将这个刷新操作,写在主线程里边,像这样


DispatchQueue.main.async {

self?.tb.reloadData()

}

这也不算是坑吧,就是习惯了oc中在请求成功的block中,执行一下reloaddata,这里需要注意一个就好。

你可能感兴趣的:(swift自己封装一个简易网络请求,逃逸闭包的一个小坑)