1. 程式人生 > >[Xcode10 實際操作]八、網絡與多線程-(11)使用同步Post方式查詢IP地址信息

[Xcode10 實際操作]八、網絡與多線程-(11)使用同步Post方式查詢IP地址信息

定位 created 錯誤代碼 可能 輸出日誌 receive override n) 導航

本文將演示如何通過Post請求,同步獲取IP地址信息。

一旦發送同步請求,程序將停止用戶交互,直至服務器返回數據。

在項目導航區,打開視圖控制器的代碼文件【ViewController.swift】

 1 import UIKit
 2 
 3 class ViewController: UIViewController {
 4     
 5     //給當前視圖控制器類,添加一個標簽屬性。
 6     //該標簽對象,將用來顯示遠程服務器返回的信息
 7     var label = UILabel()
 8     
 9     override func viewDidLoad() {
10 super.viewDidLoad() 11 // Do any additional setup after loading the view, typically from a nib. 12 13 //設置標簽對象的位置在(20,40),尺寸為(280,500) 14 label.frame = CGRect(x: 20, y: 40, width: 280, height: 500) 15 //設置標簽對象的文字內容 16 label.text = "Loading..." 17 //
設置標簽對象的字體和大小 18 label.font = UIFont(name: "Arial", size: 14) 19 //設置標簽對象的背景顏色為淺灰色 20 label.backgroundColor = UIColor.lightGray 21 //設置標簽對象的行數屬性值為0,表示不限制標簽對象的行數 22 label.numberOfLines = 0 23 //遠程服務器有可能返回較多的文字內容, 24 //在此設置標簽對象在進行換行時,保留所有的字符 25 label.lineBreakMode = NSLineBreakMode.byWordWrapping
26 //將設置好的標簽對象,添加到當前視圖控制器的根視圖 27 self.view.addSubview(label) 28 29 //創建一個網址對象,指定請求網絡數據的網址。 30 //網址最後面的參數,代表需要查詢的IP地址 31 let url = URL(string: "http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42") 32 33 //創建一個網絡請求對象,參數說明: 34 //1.代表請求訪問的路徑 35 //2.代表網絡請求的緩存協議 36 //3.代表網絡請求的超時時間 37 var request = URLRequest.init(url:url!, 38 cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, 39 timeoutInterval: 30) 40 41 //設置網絡通信方式為Post,默認為Get請求 42 //相比Get請求,Post具有傳送的數量較大,安全性較高, 43 //但執行效率相對較低的特點 44 request.httpMethod = "POST" 45 46 //初始化一個信號量,它是一種用來控制並發訪問資源的機制, 47 //常用於多線程中,可以控制並發線程的數量。 48 //這裏設置信號量為0,使線程一直等待,從而產生同步請求的效果。 49 let semaphore = DispatchSemaphore(value: 0) 50 51 //網址會話URLSession在2013年發布,蘋果對它的定位是作為舊的網絡請求接口的替代者。 52 //這裏獲得網址會話的單例對象 53 let session = URLSession.shared 54 //所有網絡請求工作,都是通過網址會話任務對象來完成的。 55 //可以使用閉包、代理或者兩者混合的方式,來創建網絡請求任務。 56 let task = session.dataTask(with: request, completionHandler: {(data, response, error) -> Void in 57 //如果出現網絡請求錯誤, 58 if error != nil{ 59 //則在控制臺打印輸出錯誤代碼和錯誤信息 60 print(error.debugDescription) 61 }else{ 62 //將網絡返回的數據對象,根據指定的編碼方式,轉換為字符串 63 let result = String(data: data!, encoding: String.Encoding.utf8) 64 //然後返回主線程, 65 DispatchQueue.main.async(execute: { () -> Void in 66 //更新標簽對象的文字內容 67 //界面元素的刷新,需要在主線程進行 68 self.label.text = result! as String 69 }) 70 } 71 //將信號量進行發送,使信號量加1, 72 //此時其他等待中的線程就會被喚醒, 73 //從而完成同步網絡請求的操作 74 semaphore.signal() 75 }) 76 77 //任務創建後,調用resume方法開始工作。 78 task.resume() 79 //等待信號量,timeout參數可以控制等待的最長時間,distantFuture表示永久等待 80 _ = semaphore.wait(timeout: DispatchTime.distantFuture) 81 //在網絡的同步請求結束之後,在控制臺輸出日誌信息 82 print("Task completed.") 83 } 84 85 override func didReceiveMemoryWarning() { 86 super.didReceiveMemoryWarning() 87 // Dispose of any resources that can be recreated. 88 } 89 }

[Xcode10 實際操作]八、網絡與多線程-(11)使用同步Post方式查詢IP地址信息