你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 自己動手寫一個 iOS 網絡請求庫(三)——降低耦合

自己動手寫一個 iOS 網絡請求庫(三)——降低耦合

編輯:IOS開發基礎

之前篇目:自己動手寫一個 iOS 網絡請求庫(一)—— NSURLSession 初探

之前篇目:自己動手寫一個 iOS 網絡請求庫(二)——封裝接口

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

開源項目:Pitaya,適合大文件上傳的 HTTP 請求庫:https://github.com/johnlui/Pitaya

本文中,我們將一起降低之前代碼的耦合度,並使用適配器模式實現一層獨立於底層結構的網絡 API,造一個真正的網絡請求“庫”。

降低耦合度

如何降低耦合度

現在的清湯掛面式的代碼雖然便於理解,但是功能單一,代碼雜亂。我們一起來分析 NSURLSession 的使用過程:

  1. 構造 NSURLRequest

    1. 確定 URL

    2. 確定 HTTP 方法(GET、POST 等)

    3. 添加特定的 HTTP 頭

    4. 填充 HTTP Body

  2. 驅動 session.dataTaskWithRequest 方法,開始請求

具體實施

在 Network 下另外新建一個 NetworkManager 類,將 URL、params、files 等設為成員變量,讓他們在構造函數中初始化:

class NetworkManager {
    
    let method: String!
    let params: Dictionary    let callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void
    
    let session = NSURLSession.sharedSession()
    let url: String!
    var request: NSMutableURLRequest!
    var task: NSURLSessionTask!
    
    init(url: String, method: String, params: Dictionary = Dictionary(), callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
        self.url = url
        self.request = NSMutableURLRequest(URL: NSURL(string: url)!)
        self.method = method
        self.params = params
        self.callback = callback
    }
}

之後,將上面分析的

1. 確定 URL

2. 確定 HTTP 方法(GET、POST 等)

3. 添加特定的 HTTP 頭

4. 填充 HTTP Body

前三步封裝到一個 function 中,最後一步封裝到一個 function 中,然後把驅動 session.dataTaskWithRequest 的代碼封裝到一個 function 中:

func buildRequest() {
    if self.method == "GET" && self.params.count > 0 {
        self.request = NSMutableURLRequest(URL: NSURL(string: url + "?" + buildParams(self.params))!)
    }
    
    request.HTTPMethod = self.method
    
    if self.params.count > 0 {
        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    }
}
func buildBody() {
    if self.params.count > 0 && self.method != "GET" {
        request.HTTPBody = buildParams(self.params).nsdata
    }
}
func fireTask() {
    task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
        self.callback(data: data, response: response, error: error)
    })
    task.resume()
}

之後使用一個統一的方法來驅動上面三個 function,完成請求:

func fire() {
    buildRequest()
    buildBody()
    fireTask()
}

同時,不要忘了那三個 parse params 的從 Alamofire 偷來的函數哦,也要放到這個類裡面。至此,降低耦合的工作基本完成,接下來我們開始封裝“網絡API”。

使用適配器模式封裝“網絡API”

理解適配器模式

適配器模式是設計模式中的一種,很容易理解:我的 APP 需要一個獲取某一個 URL 返回的字符串的功能,我現在選擇的是 Alamofire,但是正在發展的 Pitaya 看起來不錯,我以後想替換成 Pitaya,所以我封裝了一層我自己的網絡接口,用來屏蔽底層細節,到時候只需要修改這個類,不需要再深入項目中改那麼多接口調用了。

適配器模式聽起來高大上,其實這是我們在日常編碼中非常常用的設計模式。

Do it!

修改 Network 類的代碼為:

class Network{
    static func request(method: String, url: String, params: Dictionary = Dictionary(), callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
        let manager = NetworkManager(url: url, method: method, params: params, callback: callback)
        manager.fire()
    }
}

搞定!

封裝多級接口

不帶 params 的接口:

static func request(method: String, url: String, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
    let manager = NetworkManager(url: url, method: method, callback: callback)
    manager.fire()
}

兩個 get 接口(帶與不帶 params):

static func get(url: String, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
    let manager = NetworkManager(url: url, method: "GET", callback: callback)
    manager.fire()
}
static func get(url: String, params: Dictionary, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
    let manager = NetworkManager(url: url, method: "GET", params: params, callback: callback)
    manager.fire()
}

兩個 post 接口(帶與不帶 params):

static func post(url: String, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
    let manager = NetworkManager(url: url, method: "POST", callback: callback)
    manager.fire()
}
static func post(url: String, params: Dictionary, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
    let manager = NetworkManager(url: url, method: "POST", params: params, callback: callback)
    manager.fire()
}

測試接口

修改 ViewController 中的調用代碼,測試多級 API:

@IBAction func mainButtonBeTapped(sender: AnyObject) {
    let url = "http://pitayaswift.sinaapp.com/pitaya.php"
    
    Network.post(url, callback: { (data, response, error) -> Void in
        println("POST 1 請求成功")
    })
    Network.post(url, params: ["post": "POST Network"], callback: { (data, response, error) -> Void in
        let string = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
        println("POST 2 請求成功 " + string)
    })
    
    Network.get(url, callback: { (data, response, error) -> Void in
        println("GET 1 請求成功")
    })
    Network.get(url, params: ["get": "POST Network"], callback: { (data, response, error) -> Void in
        let string = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
        println("GET 2 請求成功 " + string)
    })
    
    Network.request("GET", url: url, params: ["get": "Request Network"]) { (data, response, error) -> Void in
        let string = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
        println("Request 請求成功 " + string)
    }
}

運行項目,點擊按鈕,查看效果:

1.jpg

多級 API 封裝成功!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved