成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

自己動手 打造Swift全功能 JSON 解析、生成庫

移動開發
在我動手搞這個 JSON 解析庫之前,我一直在用 SwiftyJSON 這個庫,這個庫是國人開源的最受歡迎的 Swift 項目,沒有之一,也是全球最受歡迎的 Swift 庫第二名,第一名是網絡庫 Alamofire。由于要實現 ["key"]["key1"] 這樣的遞歸查找,我一直覺得 JSON 解析庫非常復雜難搞。

準備工作

起因

在我動手搞這個 JSON 解析庫之前,我一直在用 SwiftyJSON 這個庫,這個庫是國人開源的***的 Swift 項目,沒有之一,也是全球***的 Swift 庫第二名,***名是網絡庫 Alamofire。由于要實現 ["key"]["key1"] 這樣的遞歸查找,我一直覺得 JSON 解析庫非常復雜難搞。

過程

最近比較閑,我打算把之前用過的開源庫都自己實現一下,提升一下自己。而且我在實際使用 SwiftyJSON 的過程中,遇到過非合法長字符串導致奔潰的情況,我打算先從 JSON 解析庫下手,于是中秋節的前一天,吃完午飯我就開搞了,到了下午六七點,解析的功能就全部搞定了,十分出乎預料。中秋節這天我又把生成的功能做了,整理下代碼,收拾收拾就給開源了。

API 統計

言歸正傳,我們的準備工作還是要做的:統計 SwiftyJSON 的主要 API。經過簡單統計,我找到了所有我在項目中使用過的 SwiftyJSON 的 API,主要分為四類:

通過特定路徑取出特定類型的值,如:json["key"]["key1"].stringValue

取出某個數組類型的子 JSON,循環拿到里面的值

將某個 JSON 對象格式化成字符串

使用 Dictionary 生成 JSON 對象

遞歸取值

設計基本結構

既然要兼容 SwiftyJSON 的主要 API,那調用方式跟它一樣就行了:先使用 NSData、Array 或者 Dictionary 生成 JSON 對象,再對這個對象進行操作,拿到我們想要的值、數組、完整的 JSON 字符串等。

為了對比 API 的執行結果,我們仍然引入 SwiftyJSON 庫,所以我們需要一個其他的類名,在這里我們就暫定為 JSONND,是 JSON Never Die 的縮寫,含義是永不奔潰的 JSON 解析庫。

我們先從網絡數據下手。網絡數據的來源一般為 NSData,經過簡單查詢我們知道系統提供了一個 JSON 解析方法,可以把 NSData 格式的解析為 AnyObject,構造出 JSONND 類:

  1. public struct JSONND { 
  2. public var jsonObject: AnyObject! 
  3. public static func initWithData(data: NSData) -> JSONND! { 
  4. do { 
  5. return JSONND(jsonObject: try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments)) 
  6. catch let error as NSError { 
  7. let e = NSError(domain: "JSONNeverDie.JSONParseError", code: error.code, userInfo: error.userInfo) 
  8. NSLog(e.localizedDescription) 
  9. return JSONND() 

需要注意的是,我們給 JSON 類使用的是 struct 結構體,為了它能夠具備自動初始化函數,值類型等優良特性。JSON 直觀上感覺是 String 的衍生,故使用值類型也起到降低學習成本的作用。

我們使用下面的代碼來檢驗成果:

  1. let data = NSData(contentsOfURL: NSURL(string: "http://httpbin.org/get?hello=world")!)! 
  2. let json = JSONND.initWithData(data) 

運行,正常,初始化代碼完成。

支持 ["key"]["key1"] 形式的遞歸取值

為了支持遞歸取值,同時不讓我們的 JSONND 結構體變的過于臃腫,我們考慮將遞歸取值的任務交給第二個結構體:

  1. public struct JSONNDElement { 
  2. public var data: AnyObject! 
  3. public init(data: AnyObject!) { 
  4. self.data = data 
  5. public subscript (index: String) -> JSONNDElement { 
  6. if let jsonDictionary = self.data as? Dictionary { 
  7. if let value = jsonDictionary[index] { 
  8. return JSONNDElement(data: value) 
  9. else { 
  10. NSLog("JSONNeverDie: No such key '\(index)'"
  11. return JSONNDElement(data: nil) 

同時,我們需要在 JSONND 結構體中觸發遞歸取值的***次:

  1. public subscript (index: String) -> JSONNDElement { 
  2. let jsonNDElement = JSONNDElement(data: self.jsonObject) 
  3. return jsonNDElement[index] 

檢驗成果:

  1. let data = NSData(contentsOfURL: NSURL(string: "http://httpbin.org/get?hello=world")!)! 
  2. let json = JSONND.initWithData(data) 
  3. let args = json["args"
  4. let hello = args["hello"

運行,正常,遞歸取值完成。

取出 Int、Float、String、Array、Bool 類型的值

在我們通過 ["key"]["key1"] 的形式拿到最終的 JSONNDElement 對象之后,我們就需要把他的 data 轉換成我們想要的類型輸出了。介紹 JSON 數據類型的文檔:http://www.yiibai.com/json/json_data_types.html

SwiftyJSON 采用兩級函數來取值,即 .int 為 Int? 類型, .intValue 為 Int 類型,這顯然是為了適應不同的 API 設計作出的兼容,我們也要實現這樣的兩級取值。要實現取值,其實是非常簡單的,if let 轉換一下類型,基本就 OK 了:

  1. public var int: Int? { 
  2. get { 
  3. if let _ = self.data { 
  4. return self.data.integerValue 
  5. else { 
  6. return nil 
  7. public var intValue: Int { 
  8. get { 
  9. if let i = self.int { 
  10. return i 
  11. else { 
  12. return 0 

由于代碼比較繁瑣無趣,這里只用 Int 展示一下,更多代碼請見 Github。

Array 類型的處理要單獨拿出來處理,因為 Array 有子級,所以我們得到的將是 JSONNDElement 數組。Array 處理代碼如下:

  1. public var array: [JSONNDElement]? { 
  2. get { 
  3. if let _ = self.data { 
  4. if let arr = self.data as? Array { 
  5. var result = Array() 
  6. for i in arr { 
  7. result.append(JSONNDElement(data: i)) 
  8. return result 
  9. else { 
  10. return nil 
  11. else { 
  12. return nil 
  13. public var arrayValue: [JSONNDElement] { 
  14. get { 
  15. if let i = self.array { 
  16. return i 
  17. else { 
  18. return [] 

將 JSONND 對象格式化成字符串

通過在 JSONND 和 JSONNDElement 中添加兩個函數,將成員變量 data 轉換成 String 就可以加上這個功能了:

JSONND 中:

  1. public var jsonString: String? { 
  2. let jsonNDElement = JSONNDElement(data: self.jsonObject) 
  3. return jsonNDElement.jsonString 
  4. public var jsonStringValue: String { 
  5. let jsonNDElement = JSONNDElement(data: self.jsonObject) 
  6. return jsonNDElement.jsonStringValue 

JSONNDElement 中:

  1. public var jsonString: String? { 
  2. get { 
  3. do { 
  4. if let _ = self.data { 
  5. return NSString(data: try NSJSONSerialization.dataWithJSONObject(self.data, options: .PrettyPrinted), encoding: NSUTF8StringEncoding) as? String 
  6. else { 
  7. return nil 
  8. catch { 
  9. return nil 
  10. public var jsonStringValue: String { 
  11. get { 
  12. if let i = self.jsonString { 
  13. return i 
  14. else { 
  15. return "" 

使用 Array、Dictionary 生成 JSON 對象

這一步操作我們將使用從 SwiftyJSON 中偷來的函數,稍加改裝就可以利用了:

  1. // stolen from SwiftyJSON 
  2. extension JSONND: DictionaryLiteralConvertible { 
  3. public init(dictionaryLiteral elements: (String, AnyObject)...) { 
  4. self.init(jsonObject: elements.reduce([String : AnyObject]()){(dictionary: [String : AnyObject], element:(String, AnyObject)) -> [String : AnyObject] in 
  5. var d = dictionary 
  6. d[element.0] = element.1 
  7. return d 
  8. }) 
  9. // stolen from SwiftyJSON 
  10. extension JSONND: ArrayLiteralConvertible { 
  11. public init(arrayLiteral elements: AnyObject...) { 
  12. self.init(jsonObject: elements) 

代碼的原理也很簡單,利用系統的自動轉換 protocol:DictionaryLiteralConvertible 和 ArrayLiteralConvertible,讓 Array 和 Dictionary 自動轉換為 JSONND 類型。現在我們可以采用這種方式定義 JSONND 對象了:

  1. let dictionaryJSON: JSONND = ["a"1"b": [123]] 
  2. let arrayJSON: JSONND = [012

搞定!

檢驗成果

我已經給 JSONNeverDie 項目寫了完整的單元測試來測試每一項功能,感興趣的同學可以去 Github 查看測試代碼。

責任編輯:chenqingxiang 來源: CocoaChina
相關推薦

2015-09-01 09:49:28

2023-12-15 10:14:42

數據庫select語句

2009-03-16 16:30:18

2013-11-26 13:11:20

編程優秀產品移動應用

2013-11-29 14:07:29

編程產品

2009-12-10 18:24:17

2009-01-08 09:52:26

2009-02-20 12:09:10

數據備份數據安全NAS

2022-05-11 09:50:02

GitLinux

2017-02-14 10:20:43

Java Class解析器

2011-08-25 09:30:22

2016-04-11 09:58:53

iOSJSONModel

2009-12-07 10:27:51

WCF分頁

2010-09-02 15:28:30

DHCP功能

2020-05-20 13:53:41

HTTP環境安裝

2020-09-29 12:13:46

SQL引擎底層

2021-02-21 13:40:12

Windows 10Windows微軟

2015-01-20 09:11:19

2012-12-11 10:35:39

MDM安全MDM

2010-10-08 11:49:35

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人性视频在线播放 | 中文字幕一区二区在线观看 | 男女午夜激情视频 | 久久久久精 | 国产精品久久久久无码av | 丝袜美腿一区二区三区动态图 | 日韩在线免费视频 | 成人在线观看免费 | 91在线视频免费观看 | 久久精品久久综合 | 日韩高清一区 | 亚洲美女视频 | 正在播放一区二区 | 九色在线观看 | 国产毛片久久久 | 毛片av免费在线观看 | 亚洲乱码国产乱码精品精的特点 | 国产成人精品久久二区二区91 | 中文字幕 国产精品 | 久久国产精品久久久久久久久久 | 亚洲综合小视频 | 日韩爱爱网 | 亚洲人成网亚洲欧洲无码 | 成人在线免费观看视频 | 国产精品久久久久久久久久久久久久 | 日韩在线中文 | a级片在线观看 | av中文在线 | 日韩精品在线播放 | 国产精品亚洲一区二区三区在线观看 | 日韩高清三区 | 日韩欧美专区 | 久久精品一 | 亚洲日韩中文字幕一区 | 中文字幕综合 | 日韩第1页 | 在线精品一区 | 国产激情视频在线观看 | 天堂成人国产精品一区 | 亚洲黄色一级 | 精品影院|