你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS7技巧 >> Swift使用反射將自定義對象數據序列化成JSON數據

Swift使用反射將自定義對象數據序列化成JSON數據

編輯:IOS7技巧
JSON數據在任何的一個開發應用應用中我們都用到的非常的多了,這裡來看一個ios開發中Swift使用反射將自定義對象數據序列化成JSON數據的例子。

我們知道蘋果從IOS5.0後推出了SDK自帶的JSON解決方案NSJSONSerialization,這是一個非常好用的JSON生成和解析工具,效率也比其他第三方開源項目高。
但用其生成JSON數據有個限制:只能將Foundation對象轉換成JSON。即頂層對象必須是NSArray或者NSDictionary,所有的對象必須是NSString、NSNumber、NSArray、NSDictionary、NSNull的實例。
所以,如果我們想要把自定義類型的數據對象轉成JSON數據,NSJSONSerialization就無能為力了。 

1,將自定義對象轉成JSON數據的實現原理(不借助第三方庫)

(1)首先我們使用反射(Reflection)對自定義類型的數據對象中所有的屬性進行遞歸遍歷,生成字典類型的數據並返回。
(2)接著使用NSJSONSerialization就可以把這個字典類型的數據轉換成jSON數據了。

2,比如我們自定義一個的聯系人類

//用戶類
class User {
    var name:String = ""  //姓名
    var nickname:String?  //昵稱
    var age:Int?   //年齡
    var emails:[String]?  //郵件地址
    var tels:[Telephone]? //電話
}
 
//電話結構體
struct Telephone {
    var title:String  //電話標題
    var number:String  //電話號碼
}

3,JSON串生成的功能實現

(1)首先定義一個叫JSON的協議,並對其擴展,實現協議中定義的兩個方法。
toJSONModel():將數據轉成可用的JSON模型。
toJSONString():將數據轉成JSON字符串(其內部會調用前面的toJSONModel()方法)。
(2)將可選類型(Optional),自定義類(User、TeleTelephone),以及基本數據類型進行擴展,使其遵循JSON協議。
同時對於可選類型還要重寫toJSONModel()方法,為的是當可選類型值不存在時返回nil,存在時將其轉成具體類型並序列化。

//自定義一個JSON協議
protocol JSON {
    func toJSONModel() -> AnyObject?
    func toJSONString() -> String?
}
 
//擴展協議方法
extension JSON {
    //將數據轉成可用的JSON模型
    func toJSONModel() -> AnyObject? {
        let mirror = Mirror(reflecting: self)
        if mirror.children.count > 0  {
            var result: [String:AnyObject] = [:]
            for case let (label?, value) in mirror.children {
                //print("屬性:\(label)     值:\(value)")
                if let jsonValue = value as? JSON {
                    result[label] = jsonValue.toJSONModel()
                }
            }
            
            return result
        }
        return self as? AnyObject
    }
    
    //將數據轉成JSON字符串
    func toJSONString() -> String? {
        let jsonModel = self.toJSONModel()
        //利用OC的json庫轉換成OC的NSData,
        let data : NSData! = try? NSJSONSerialization.dataWithJSONObject(jsonModel!, options: [])
        //NSData轉換成NSString打印輸出
        let str = NSString(data:data, encoding: NSUTF8StringEncoding)
        return str as String?
    }
}
 
//擴展可選類型,使其遵循JSON協議
extension Optional: JSON {
    //可選類型重寫toJSONModel()方法
    func toJSONModel() -> AnyObject? {
        if let x = self {
            if let value = x as? JSON {
                return value.toJSONModel()
            }
        }
        return nil
    }
}
 
//擴展兩個自定義類型,使其遵循JSON協議
extension User: JSON { }
extension Telephone: JSON { }
 
//擴展Swift的基本數據類型,使其遵循JSON協議
extension String: JSON { }
extension Int: JSON { }
extension Bool: JSON { }
extension Dictionary: JSON { }
extension Array: JSON { }

4,測試樣例

//創建一個User實例對象
let user1 = User()
user1.name = "hangge"
user1.age = 100
user1.emails = ["[email protected]","[email protected]"]
//添加動畫
let tel1 = Telephone(title: "手機", number: "123456")
let tel2 = Telephone(title: "公司座機", number: "001-0358")
user1.tels = [tel1, tel2]
 
//輸出json字符串
print(user1.toJSONString()!)
看到控制台輸出如下信息:
原文:Swift - 使用反射將自定義對象數據序列化成JSON數據

格式化後數據如下:
{
    "tels": {
        "[1]": {
            "number": "001-0358",
            "title": "公司座機"
        },
        "[0]": {
            "number": "123456",
            "title": "手機"
        }
    },
    "age": 100,
    "name": "hangge",
    "emails": {
        "[1]": "[email protected]",
        "[0]": "[email protected]"
    }
}

使用第三方庫 - JSONKit 


1,新建橋街頭文件Bridging-Header.h,並設置到編譯參數裡
1 #include "JSONKit.h"
2,將JSONKit的庫文件導入到項目中來(JSONKit.h和JSONKit.m)
3,這時編譯會發現報錯,這是由於JSONKit庫不支持Objective-C的自動引用計數功能導致。
需要在Build Phases -> Compile Sources -> JSONKit.m,雙擊添加Comipler Flag:-fno-objc-arc 。這樣就完成了不支持自動引用計數的配置。
 

測試代碼:

import UIKit
 
class ViewController: UIViewController {
     
    override func viewDidLoad() {
        super.viewDidLoad()
        testJson()
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
     
    func testJson() {
        //Swift 字典對象
        let user = [
            "uname": "user1",
            "tel": ["mobile": "138", "home": "010"]
        ]
        //使用 JSONKit 轉換成為 JSON 字符串
        let jsonstring = (user as NSDictionary).JSONString()
        print(jsonstring);
        //由字符串反解析回字典
        print(jsonstring.objectFromJSONString() as! NSDictionary)
         
        //使用 JSONKit 轉換成為 NSData 類型的 JSON 數據
        let jsondata = (user as NSDictionary).JSONData()
        print(jsondata);
        //由NSData 反解析回為字典
        print(jsondata.objectFromJSONData() as! NSDictionary)
    }
}

輸出結果:

{"uname":"user1","tel":{"home":"010","mobile":"138"}}
{
    tel =     {
        home = 010;
        mobile = 138;
    };
    uname = user1;
}
<7b22756e 616d6522 3a227573 65723122 2c227465 6c223a7b 22686f6d 65223a22 30313022 2c226d6f 62696c65 223a2231 3338227d 7d>
{
    tel =     {
        home = 010;
        mobile = 138;
    };
    uname = user1;
}

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