Swift 通過 http 發送 JSON-RPC 命令

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

JSON-RPC

JSON-RPC是一個無狀態且羽量級的遠端程序呼叫(RPC)協議。 本規範主要定義了一些資料結構及其相關的處理規則。它允許運行在基於 socket, HTTP 等諸多不同消息傳輸環境的同一進程中。其使用JSONRFC 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() 方法來啟動連結,這裡我們用到 NSURLSessiondataTaskWithRequest(_:) 方法來產生 NSURLSessionDataTask 實例。

這裡我們創建了一個落格博客首頁的 Request ,然後從 NSURLSessionsharedSession() 方法直接獲取預設配置的 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 的類,這裡邊寫一個類型方法 post

這個類型方法接收一個 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

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

發表評論

您的電子郵件地址不會被公開. 必填字段標 *