网络通信

1、判断网络连接情况

开源第三方类Swift-Reachability实现判断网络情况,支持3G和WiFi检测。

// MARK: - 检测网络连接情况
    @IBOutlet var typeLabel: UILabel!
    
    @IBAction func checkButtonUpinside(sender: UIButton) {
        
        let reachability = Reachability.reachabilityForInternetConnection()
        reachability?.stopNotifier()
        
        let statusType:Reachability.NetworkStatus = (reachability?.currentReachabilityStatus)!
        
        if statusType == Reachability.NetworkStatus.ReachableViaWWAN
        {
            typeLabel.text = "连接类型:移动网络4G"
        }
        else if statusType == Reachability.NetworkStatus.ReachableViaWiFi
        {
            typeLabel.text = "连接类型:WiFi"
        }
        else if statusType == Reachability.NetworkStatus.NotReachable
        {
            typeLabel.text = "连接类型:没有网络连接"
        }
    }

2、网络请求JSON解析

使用NSURLConnection实现HTTP通信方式,NSURLConnection提供了异步请求和同步请求两种通信方式。同步请求数据容易造成主线程的阻塞,通常在请求大数据或者网络状态不好的情况下不建议使用。

建立通信的步骤如下:

1)创建NSURL;

2)创建Request对象;

3)创建NSURLConnection连接。

<1>同步请求数据方式

 1 // MARK: - 同步请求
 2     func httpSynchronousRequest()
 3     {
 4         //创建NSURL对象
 5         let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
 6         
 7         //创建请求对象
 8         let urlRequest : NSURLRequest = NSURLRequest(URL: url)
 9 
10         
11         //发出请求
12         NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler: { (response:NSURLResponse?, data:NSData?, error:NSError?) -> Void in
13             
14             
15             if (error != nil)
16             {
17                 print(error?.code)
18                 print(error?.description)
19             }else
20             {
21                 let jsonString = NSString(data: data!, encoding: NSUTF8StringEncoding)
22                 
23                 print(jsonString)
24             }
25             
26         })
27         
28     }

<2>异步请求方式

 1 // MARK: - 异步请求
 2     func httpAsynchronousRequest()
 3     {
 4         //创建NSURL对象
 5         let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
 6         
 7         //创建请求对象
 8         let urlRequest : NSURLRequest = NSURLRequest(URL: url)
 9         
10         //网络连接对象
11         let conn : NSURLConnection? =  NSURLConnection(request: urlRequest, delegate: self)
12         
13         conn?.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
14         
15         //执行
16         conn?.start()
17     }
 1 // MARK: - NSURLConnectionDataDelegate
 2     func connection(connection: NSURLConnection, willSendRequest request: NSURLRequest, redirectResponse response: NSURLResponse?) -> NSURLRequest?
 3     {
 4         //将要发送请求
 5         return request
 6     }
 7     
 8     func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
 9     {
10         //接收响应
11     }
12     
13     //接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
14     var jsonData:NSMutableData =  NSMutableData()
15 func connection(connection: NSURLConnection, didReceiveData data: NSData) 16 { 17 //收到数据 18 self.jsonData.appendData(data) 19 } 20 21 func connection(connection: NSURLConnection, needNewBodyStream request: NSURLRequest) -> NSInputStream? 22 { 23 //需要新的内容流 24 return request.HTTPBodyStream 25 } 26 27 func connection(connection: NSURLConnection, didSendBodyData bytesWritten: Int, totalBytesWritten: Int, totalBytesExpectedToWrite: Int) 28 { 29 //发送数据请求 30 } 31 32 func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse? 33 { 34 //缓存响应 35 return cachedResponse 36 } 37 38 func connectionDidFinishLoading(connection: NSURLConnection) 39 { 40 //请求结束,解析jsonData数据流。 41 let jsonString = NSString(data: self.jsonData, encoding: NSUTF8StringEncoding) 42 43 print(jsonString) 44 45 do { 46 if let dic:Dictionary<String,AnyObject> = try NSJSONSerialization.JSONObjectWithData(self.jsonData, options: NSJSONReadingOptions()) as? Dictionary<String,AnyObject> 47 { 48 49 print(dic) 50 51 if let weatherinfoDic:Dictionary<String,AnyObject> = dic["weatherinfo"] as? Dictionary<String,AnyObject> 52 { 53 if let city = weatherinfoDic["city"] as? String{ 54 print(city) 55 } 56 57 if let WD = weatherinfoDic["WD"] as? String{ 58 print(WD) 59 } 60 61 if let WS = weatherinfoDic["WS"] as? String{ 62 print(WS) 63 } 64 } 65 } 66 } 67 catch let error as NSError { 68 print("失败:(error)")//如果失败,error 会返回错误信息 69 } 70 }

3、同步Get方式

对于Get方式,服务器端用Request.QueryString获取变量的值,对于Post方式,服务器端用Request.From获取提交的数据。

在做数据查询的时,建议用Get方式;在进行数据的添加、修改和删除时,建议用Post方式。

// MARK: - 同步Get方式
    func synchronousGet()
    {
        //创建NSURL对象
        let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
        
        //创建请求对象
        let urlRequest : NSURLRequest = NSURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10)
        
        //响应对象
        var response:NSURLResponse?
        
        //发出请求
        do
        {
            let received = try NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: &response)
            
            let jsonString = NSString(data: received, encoding: NSUTF8StringEncoding)
            
            print(jsonString)
        }
        catch let error as NSError {
            print("失败:(error)")//如果失败,error 会返回错误信息
        }
    }
public enum NSURLRequestCachePolicy : UInt {
    case UseProtocolCachePolicy //基础策略
    case ReloadIgnoringLocalCacheData  //忽略本地缓存
    case ReloadIgnoringLocalAndRemoteCacheData // 无视任何缓存策略,无论是本地还是远程的,总是从原地址重新下载
    case ReturnCacheDataElseLoad  //首先使用缓存,如果没有本地缓存,才从原地址下载
    case ReturnCacheDataDontLoad  //使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作。
    case ReloadRevalidatingCacheData // 如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载
}

4、异步Get请求方式

// MARK: - 异步Get方式
    func asynchronousGet()
    {
        //创建NSURL对象
        let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
        
        //创建请求对象
        let urlRequest : NSURLRequest = NSURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10)
        
        //连接服务器
        let connection = NSURLConnection(request: urlRequest, delegate: self)
        
        print(connection)
    }

主要实现下面的两个异步请求代理方法NSURLConnectionDataDelegate,来接收相关数据。

func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
    {
        //接收响应
    }
    
    //接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
    var jsonData:NSMutableData =  NSMutableData()
    func connection(connection: NSURLConnection, didReceiveData data: NSData)
    {
        //收到数据
        self.jsonData.appendData(data)
    }

5、同步post请求如下:

 1 // MARK: - 同步Post方式
 2     func synchronousPost()
 3     {
 4         //创建NSURL对象
 5         let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
 6         
 7         //创建请求对象
 8         let request : NSMutableURLRequest = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10)
 9         
10         request.HTTPMethod = "POST"//设置请求方式为POST,默认为GET
11         
12         let str:String = "type=focus-c";//设置参数
13         let data:NSData = str.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
14         request.HTTPBody = data;
15         
16         //响应对象
17         var response:NSURLResponse?
18         
19         //发出请求
20         do
21         {
22             let received = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response)
23             let jsonString = NSString(data: received, encoding: NSUTF8StringEncoding)
24             
25             print(jsonString)
26         }
27         catch let error as NSError {
28             print("失败:(error)")//如果失败,error 会返回错误信息
29         }
30     }

6、异步post请求方式

 1 // MARK: - 异步Post方式
 2     func asynchronousPost()
 3     {
 4         //创建NSURL对象
 5         let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
 6         
 7         //创建请求对象
 8         let request : NSMutableURLRequest = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 10)
 9         
10         request.HTTPMethod = "POST"//设置请求方式为POST,默认为GET
11         
12         let str:String = "type=focus-c";//设置参数
13         let data:NSData = str.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
14         request.HTTPBody = data;
15         
16         //连接服务器
17         let connection = NSURLConnection(request: request, delegate: self)
18     }

7、NSURLSession加载数据、下载、上传

NSURLSession类支持三种类型任务:加载数据、下载和上传。

Data Task用于加载数据,使用全局的sharedSession()和func dataTaskWithRequest(request: NSURLRequest, completionHandler:((NSData!, NSURLRequesse!, NSError!)-> Void?)-> NSURLSessionDataTask方法创建。

1)加载数据

// MARK: - /* 使用NSURLSessionDataTask加载数据 */
    func sessionLoadData()
    {
        //创建NSURL对象
        let url:NSURL! = NSURL(string: "http://swift.leadingdo.com/weather.json")
        
        //创建请求对象
        let request : NSURLRequest = NSURLRequest(URL: url)
        
        let session = NSURLSession.sharedSession()
        
        
        let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
            
            //返回错误信息情况
            if (error != nil)
            {
                print(error?.code)
                print(error?.description)
            }else
            {
                let jsonString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print(jsonString)
            }
        }) as NSURLSessionTask
        
        //使用resume方法启动任务
        dataTask.resume()
    }

2)下载文件任务

 1 // MARK: - /* 使用NSURLSessionDataTask下载文件  ---- 简单下载,不需要知道下载进度 */
 2     func sessionSimpleDownload()
 3     {
 4         //下载地址
 5         let url = NSURL(string: "http://swift.leadingdo.com/SwiftClassIcon.jpg")
 6         //请求
 7         let request = NSURLRequest(URL: url!)
 8         //连接
 9         let session = NSURLSession.sharedSession()
10         //下载任务
11         let downloadTask = session.downloadTaskWithRequest(request, completionHandler: { (location:NSURL?,response:NSURLResponse?, error:NSError?) -> Void in
12 
13             // 输出下载文件原来的存放目录
14             print("location: (location)")
15 
16             //location位置转换
17             let locationPath = location?.path
18 
19             //拷贝到我们自己目录中
20             let documents:String = NSHomeDirectory() + "/Documents/1.png"
21 
22             // 创建文件管理器
23             let fileManager :NSFileManager = NSFileManager.defaultManager()
24             
25             do
26             {
27                 try fileManager.moveItemAtPath(locationPath!, toPath: documents)
28             }
29             catch let error as NSError {
30                 print("失败:(error)")//如果失败,error 会返回错误信息
31             }
32             print("location: (documents)")
33         })
34         
35         //使用resume方法启动任务
36         downloadTask.resume()
37     }
// MARK: - /* 使用NSURLSessionDataTask下载文件  ---- 获取进度 */
    //创建一个下载模式--单利实现,自定义NSURLSession对象方法如下:
    func currentSession()->NSURLSession{
        
        var predicate:dispatch_once_t = 0
        var currentSession:NSURLSession? = nil
        
        dispatch_once(&predicate,{
            
            let config = NSURLSessionConfiguration.defaultSessionConfiguration()
            
            currentSession = NSURLSession(configuration: config, delegate: self, delegateQueue: nil)
            }
        )
        return currentSession!
    }

下载方法代码如下:

func sessionSeniorDownload()
    {
        //下载地址
        let url = NSURL(string: "http://swift.leadingdo.com/SwiftClassIcon.jpg")
        //请求
        let request = NSURLRequest(URL: url!)
        
        //连接
        let session = currentSession() as NSURLSession
        
        //下载任务
        let downloadTask = session.downloadTaskWithRequest(request)
        
        //使用resume方法启动任务
        downloadTask.resume()
    }

实现NSURLSessionDownloadDelegate代理方法,来监听下载进度。

// MARK: - NSURLSessionDownloadDelegate
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL)
    {
        //下载结束
        print("下载结束")
        
    }
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
    {
        //获取进度
         let written:CGFloat = (CGFloat)(bytesWritten)
         let total:CGFloat = (CGFloat)(totalBytesExpectedToWrite)
        
        let pro:CGFloat = written / total
        print("下按进度:(pro)")
    }
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64)
    {
        //下载偏移,主要用于暂停续传
    }

下载完成后,下载的文件位于tmp目录下,所以需要将文件保存到持久化的目录下保存,拷贝到自己定义的目录下方便以后使用。

// 输出下载文件原来的存放目录
            print("location: (location)")

            //location位置转换
            let locationPath = location?.path

            //拷贝到我们自己目录中
            let documents:String = NSHomeDirectory() + "/Documents/1.png"

            // 创建文件管理器
            let fileManager :NSFileManager = NSFileManager.defaultManager()
            
            do
            {
                try fileManager.moveItemAtPath(locationPath!, toPath: documents)
            }
            catch let error as NSError {
                print("失败:(error)")//如果失败,error 会返回错误信息
            }
            print("location: (documents)")

3)上传文件任务

 1 // MARK: -  /* 使用NSURLSessionDataTask上传文件 */
 2     func sessionUpload()
 3     {
 4         //上传的位置地址
 5         let url = NSURL(string: "http://swift.leadingdo.com/data/")
 6         
 7         //请求
 8         let request = NSURLRequest(URL: url!)
 9         
10         //连接
11         let session = NSURLSession.sharedSession()
12         
13         //上传数据流
14         let documents:String = NSHomeDirectory() + "/Documents/1.png"
15         let imgData = NSData(contentsOfFile: documents)
16         
17         let uploadTask = session.uploadTaskWithRequest(request, fromData: imgData, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
18             
19             //上传完毕之后判断
20             print("上传完毕")
21         })
22         
23         //使用resume方法启动任务
24         uploadTask.resume()
25     }
原文地址:https://www.cnblogs.com/fengmin/p/5715457.html