Swift 通過 http 發送 JSON-RPC 命令

我們在進行網路開發的時候,難免要從網路伺服器中獲取資料,很多時候還需要給伺服器提交資料,就現在來說,一般我們都會習慣使用 JSON 格式的資料,因為它方便好用,這次我們就一起來看看,如何用 Swift 發送 JSON-RPC 命令並獲取回復。

JSON-RPC

JSON-RPC是一個無狀態且羽量級的遠端程序呼叫(RPC)協議。 本規範主要定義了一些資料結構及其相關的處理規則。它允許運行在基於 socket, HTTP 等諸多不同消息傳輸環境的同一進程中。其使用JSON(RFC 4627)作為資料格式。

當我們需要從伺服器獲取資料的時候,要麼通過 URL 附帶資訊,要麼就需要使用一些特定的方法給伺服器提交資訊,比如常見的 HTTP POST 。

我們通過 HTTP 的 POST 來給伺服器發送 JSON 請求物件以表示一次 RPC 調用,按照 JSON-RPC 規則,我們需要傳入 4 個基本成員:

好了,大概瞭解了這些資訊後,我們就可以嘗試寫出一個 RPC 調用物件:

關於格式規則部分我們就介紹這麼多,要瞭解更多關於 JSON-RPC 的資訊請看文章末尾「延伸閱讀」中的相關連結。

Swift 裡的網路請求

在 Swift 裡邊,我們使用網路請求的話還是會使用 Cocoa 裡的 API,一般我們常用的即 NSURLConnection ,使用它的 sendSynchronousRequest(_:returningResponse:) 方法來進行網路請求,但不幸的是這個方法將終止在 OS X 10.11 了,所以我們應當儘量不去使用它。

NSURLSession

它是徹底重構過的 NSURLConnection ,在 iOS 7 中引入,我們使用它來替代 NSURLConnection ,不過,既然重構了,那麼使用方法也會有些許的不同,現在我們就來嘗試看看使用 NSURLSession 獲取資料。

首先來說說 NSURLSession 並不是一個類,而是一個工廠,它最終會返回一個 NSURLSessionDataTask ,而我們需要調用 task 的 .resume() 方法來啟動連結,這裡我們用到 NSURLSession 的 dataTaskWithRequest(_:) 方法來產生 NSURLSessionDataTask 實例。

這裡我們創建了一個落格博客首頁的 Request ,然後從 NSURLSession 的 sharedSession() 方法直接獲取預設配置的 NSURLSession 實例,然後調用其中的 dataTaskWithRequest(_:) 方法,傳入 Request ,由於這東西是並行的我們直接順便調用 resume() 讓它立即啟動。

…… 等等,這麼執行好像什麼也沒有? 對,由於我們還要得到伺服器返回的 JSON 物件,所以我們還要給 dataTaskWithRequest(_:) 方法追加一個閉包進去——如果你不知道什麼是閉包,也沒關係,其實就是多傳入一個函數作為參數,這個函數用來處理獲取到的資料:

按照 dataTaskWithRequest(_:) 方法的聲明:

我們的函數需要接收三個實際參數,而且不能帶有傳回值,那麼我們的函數實際上也可以單獨聲明為這樣:

總之,按照上邊的代碼執行,我們就可以在終端看到獲取到的落格首頁的 HTML 資料了。

對於要發送更多的資料進去,使用 NSURLRequest 必然是不夠的,這裡我們要使用 NSMutableURLRequest ,它是 NSURLRequest 的一個子類,擁有更多的功能,比如添加 HTTP 頭,以及添加我們所需要提交的 HTTP Body 資訊:

稍後我們來把它提交到伺服器。

Swift 裡的 JSON

說起來,Swift 對 JSON 的處理至今也不盡人意,不過好在我們只需要簡單地將 RPC 調用封裝,所以用起來也不會那麼困難。

NSJSONSerialization

我們通過這個類將 Swift 裡的物件轉換為 JSON 物件,它能把 Swift 裡的 NSString、NSNumber、NSArray、NSDictionary、NSNull 與 JSON 互轉,這裡我們只用到 NSDictionary 就可以了,因為這個最方便。

我們只需要寫好一個對應的 NSDictionary 然後傳給 dataWithJSONObject 方法即可:

這樣,我們的 JSON-RPC 命令就寫好了!

通過 HTTP 進行 JSON-RPC 遠程調用

最後要做的就是把它發出去了!

不過,這個測試你可能需要在專案而不是 Playground 裡做,因為在 iOS 9 以後蘋果引入了新特性 App Transport Security (ATS),預設禁止了不安全的 HTTP 連結,如果你測試的位址是 HTTPS 則無所謂,如果你的位址是 HTTP,那你需要先禁用這個安全機制。

禁用 App Transport Security (ATS)

在你的專案當中找到專案的屬性,然後進入 Info 選項卡,在裡邊添加一條 NSAppTransportSecurity 類型的 Dictionary ,然後再在 NSAppTransportSecurity 裡邊添加一條 NSAllowsArbitraryLoads 鍵,對應的值為 Boolean 類型的 YES 。

如果你嘗試使用 CLI 專案測試,那估計你找不到 信息.plist中 檔...... 所以還是不要嘗試了,不然你不但得不到期望的結果,連錯誤提示都不會得到。

封裝一個類型方法

好了,做足了前期的準備,我們來看看如何封裝一個類來進行 RPC 調用:

首先我們寫一個叫做 JSONRPC 的類,這裡邊寫一個類型方法 郵政 :

這個類型方法接收一個 NSDictionary 的實際參數,它就是我們要發送的資料;然後是伺服器的位址,最後接收一個閉包,它用來產生回檔,這個閉包包含:

一個 succeeded 用來給你判斷是否成功, msg 返回 HTTP Response,如果成功無錯,則 數據 會包含返回的 JSON。

首先我們根據傳入的資訊來準備資料:

然後我們把資料傳入,同時扔一個閉包進去根據結果來執行我們函數接收的那個函數(也就是回呼函數):

總之,最終的類型方法是這樣的:

測試

好了,最終我們來測試一下,這裡本地我運行了一個 Twisterd 用戶端進程,如果你不知道它是什麼...... 就去看看文章末尾的延伸閱讀...... 總之,我們來給它發送 RPC 指令:

最終,我們會得到結果:

接下來就是你操作這些結果的時間了:)

延伸閱讀

swift通過HttpRequest要求傳送json格式的資料

NSURLSession使用說明及後臺工作流程分析

iOS9 HTTP 不能正常使用的解決辦法

(譯) JSON-RPC 2.0 規範(中文版)

 

本文由 落格博客 原創撰寫:落格博客 » Swift 通過 http 發送 JSON-RPC 命令

轉載請保留出處和原文鏈接:https://www.logcg.com/archives/1554.html

關於作者

R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。