关于网络请求,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,这里需要注意一个就好。