当前位置: > > > Swift - 异步获取网络数据封装类

Swift - 异步获取网络数据封装类

(自iOS9.0起,NSURLConnection.sendAsynchronousRequest被废除不用了。建议改用URLSession的dataTaskWithRequest方法。具体用法可以参考我的另一篇文章:Swift - 使用URLSession加载数据、下载、上传文件

使用NSURLConnection.sendAsynchronousRequest()可以采用异步获取的方式取得数据。下面通过对数据获取类进行封装,演示如何进行数据请求与接收。(本文代码已升级至Swift3)

1,HttpController.swift (数据获取封装类,结果处理协议)
import UIKit

//自定义http协议
protocol HttpProtocol{
    //定义一个方法接收一个字典
    func didRecieveResults(results:Dictionary<String, AnyObject>)
}

class HttpController:NSObject{
    //定义一个可选代理
    var delegate:HttpProtocol?
    
    //定义一个方法运过来获取网络数据,接收参数为网址
    
    func onSearch(url:String){
        //定义一个NSURL
        let url = URL(string: url)!
        //定义一个NSURLRequest
        let request = URLRequest(url: url)
        //异步获取数据
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main,
            completionHandler: {(response:URLResponse?,data:Data?,error:Error?)
                ->Void in
                //由于我们获取的数据是json格式,所以我们可以将其转化为字典。
                let jsonResult = try! JSONSerialization.jsonObject(with: data!,
                            options: JSONSerialization.ReadingOptions.mutableContainers)
                                    as! Dictionary<String, AnyObject>
                //将数据传回给代理
                self.delegate?.didRecieveResults(results: jsonResult)
        })
    }
}

2,ViewController.swift (使用样例)
import UIKit

class ViewController: UIViewController,HttpProtocol {
    
    //获取网络数据的类
    var eHttp = HttpController()
    //接收频道列表的数组
    var channelData:[AnyObject] = Array()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //为HttpController实例设置代理
        eHttp.delegate=self
        //获取频道数据
        eHttp.onSearch(url: "http://www.douban.com/j/app/radio/channels")
    }
    
    //实现HttpProtocol协议的方法
    func didRecieveResults(results:Dictionary<String, AnyObject>){
        if (results["channels"] != nil){
            //如果channels关键字的value不为nil,获取的就是频道数据
            self.channelData = results["channels"] as! Array
            print(self.channelData[0]["name"] as! String) //私人兆赫
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

3,请求数据样例
{   
 "channels": [
        {
            "name_en": "Personal Radio",
            "seq_id": 0,
            "abbr_en": "My",
            "name": "私人兆赫",
            "channel_id": 0
        },
        {
            "name": "华语",
            "seq_id": 0,
            "abbr_en": "",
            "channel_id": "1",
            "name_en": ""
        },
        {
            "name": "欧美",
            "seq_id": 1,
            "abbr_en": "",
            "channel_id": "2",
            "name_en": ""
        }
    ]
}
评论3
  • 3楼
    2016-08-04 10:16
    donald

    我想把这个改成闭包API封装,请问怎么做呢
    类似这样方便些
    let opt = try HTTP.GET("http://hangge.com")
    opt.start { response in
    //进行具体的响应操作...
    }

    站长回复

    NSURLConnection已经废除不用了,建议改用URLSession。参考我写的这篇文章:Swift - 使用URLSession加载数据、下载、上传文件

  • 2楼
    2015-12-02 10:28
    duofai

    老师,你这个挺好用的,能不能请你写个关于post请求的demo啊,现在开发中大多数还是post,我想用AFNetworking,但是语法老是报错,求老师能给个demo,跪谢啊

    站长回复

    推荐你使用Alamofire,可以说是Swift版的AFNetworking。这两个都是同一个人写的。在github主页上有详细样例,你可以去看看。我下周二之前也会写篇相关的文章的

  • 1楼
    2015-10-15 16:23
    小树

    老师,我在获取网络数据的类中遵守NSURLConnectionDelegate,NSXMLParse的协议方法获取数据,结果运行viecontroller中按你那样调用on search方法就崩溃了,为什么呢

    站长回复

    这样描述我也定位不出问题。你可以把控制台的错误信息放在下面评论框里提交给我看下。