自己动手写一个 iOS 网络请求库(一)—— NSURLSession 初探

代码示例:https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary

开源项目:Pitaya,适合大文件上传的 HTTP 请求库:https://github.com/johnlui/Pitaya

本系列文章中,我们将尝试使用 NSURLSession 技术构建一个自己的网络请求库。

NSURLSession 简介

NSURLSession 是 iOS7 引入的新网络请求接口,在 WWDC2013 中有详细介绍,下面是描述其结构的一页 slides:

Image

当应用在前台时,NSURLSession 跟 NSURLConnection 没有什么区别,但是在程序切换到后台之后 Background Session 就会更加灵活。

尝试 NSURLSession

准备工作

新建一个名为 BuildYourHTTPRequestLibrary 的单页面应用,在页面上居中放置一个按钮,名为 Request:

Image

拖动绑定 Touch Up Inside 事件:

Image

Image

使用 NSURLSession

在 mainButtonBeTapped 函数内填充以下代码:

@IBAction func mainButtonBeTapped(sender: AnyObject) {
    let session = NSURLSession.sharedSession()
    let request = NSURLRequest(URL: NSURL(string: "http://baidu.com")!)
    let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
        let string = NSString(data: data, encoding: NSUTF8StringEncoding)
        println(string)
    })
    task.resume()
}

运行项目,点击按钮,查看结果:

Image

使用成功!

感受异步

异步

改写 mainButtonBeTapped 函数的代码:

@IBAction func mainButtonBeTapped(sender: AnyObject) {
    let session = NSURLSession.sharedSession()
    let request = NSURLRequest(URL: NSURL(string: "http://baidu.com")!)
    let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
        println("just wait for 5 seconds!")
        sleep(5)
        let string = NSString(data: data, encoding: NSUTF8StringEncoding)
        println(string)
    })
    task.resume()
}

再次尝试,两次打印之间间隔了五秒,主线程未阻塞,证明 NSURLSession 为异步执行。

阻塞

尝试多次点击,我们能够看到每五秒执行一次,直到全部执行完毕。

NSURLSession 采用的是 “异步阻塞” 模型,即所有请求在发出后都进入 2# 线程执行,在 2# 线程内部按照阻塞队列模式执行。初步判断,此阻塞特性为 NSURLSession.sharedSession() 单例模式的结果。


下一步:自己动手写一个 iOS 网络请求库(二)——封装接口

WRITTEN BY

avatar
2015.5.19   /   热度:34182   /   分类: iOS & Swift

评论:

哈尼
2016-03-21 21:09
博主,您好。网络请求时碰到一个问题,"Error Domain=NSURLErrorDomain Code=-1017 "cannot parse response" ",请问这个问题该怎么解决啊
shuleihen
2016-07-08 11:34
@哈尼:检查下,http请求方法,是否写对了,我估计是POST方法,你写成了GET
xiaote
2016-01-20 20:54
大神请问下 在这个示例代码里
@IBAction func mainButtonBeTapped(sender: AnyObject) {
    let session = NSURLSession.sharedSession()
    let request = NSURLRequest(URL: NSURL(string: "http://baidu.com")!)
    let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
        let string = NSString(data: data, encoding: NSUTF8StringEncoding)
        println(string)
    })
    task.resume()
}
如果我想用 string 这个常量 应该怎么写,刚开始学习请指教
xiaote
2016-01-22 08:31
@xiaote:找到方法了,使用代理
Jason
2015-10-24 14:12
博主,现在这个代码是不是已经用不了?
我照着打了一遍,提示data是nil了。。
新手求教
JohnLui
2015-10-25 00:24
@Jason:Github 上的代码是最新的,可以参考那上面的
高鹏飞
2015-10-22 10:05
data中的数据是在哪里啊?
JohnLui
2015-10-25 00:24
@高鹏飞:在哪里?没懂你的问题
john
2015-06-08 18:13
请问博主,该站的代码块部分是如何实现的呢?我这里pre标签里的所有的php标签和html等标签都是被注释掉的,前台页面显示不出来
JohnLui
2015-06-08 20:17
@john:目测编辑器的问题。我用的markdown 编辑器
john
2015-06-08 20:47
@JohnLui:哦~ 我刚才用网上的代码解决了,谢谢~
诺_你的一百块
2015-05-30 00:02
怎么大神都用swift,不用oc了吗?!看来我要翻译一个oc版本!

发表评论:

© 2011-2017 岁寒  |  Powered by Emlog