在我們的日常開發中,我們需要對一些加載的本地數據進行建模,但是在某些情況下,無法成功保存數據也是常有的情況,所以今天武林技術頻道小編詳解Obejective-C中將JSON數據轉為模型的方法。
首先我們還是先要嘗試下使用KVC的方式來解決這個問題
模型如下:
JSON數據如下:
?
?
?
{ "title" : "順平侯", "name" : "趙云", "id" : "sph" }, { "title" : "恒侯", "html" : "張飛", "id" : "hh" }, { "title" : "威侯", "html" : "馬超", "id" : "wh" }, { "title" : "剛侯", "html" : "黃忠", "id" : "gh" }, { "title" : "壽亭侯", "html" : "關羽", "id" : "sth" }從上面的數據對比我們不難發現,因為在OC中的id是關鍵字所有我們使用ID來替代,但是這樣的話就不能直接使用KVC,所以我們需要進行相應的處理來繼續使用我們的KVC轉換模型。代碼如下:
首先在模型.h文件中更新一下代碼,提供一個類方法進行模型轉換:
?
+(instancetype) heroDict:(NSDictionary*) dict;
在.m文件中實現該方法
?
?
?
??? [item setValuesForKeysWithDictionary:dict];
??? return item;
}
程序走到這里就會去模型中遍歷字典當中的所有的key。所以我們要修改的地方也就是這里去重寫KVC中的setValue forKey方法.代碼如下:
?
?
程序修改到這里,基本就可以使用KVC的方法進行轉換。但是如果我們的數據有很多不一致的情況呢?那么就讓我們一起來看下今天的重頭戲runtime來的轉換。
上面的例子的思路是通過遍歷字典當中的key去模型中比對,而我們這次試著遍歷模型,然后去字典中比對響應的key
首先在我們的模型.m里導入我們需要的頭文件
?
?
完成這一步在模型類中就可以使用runtime了,然后我們在.m中創建一個轉換的類方法
?
?
?
}
在這個方法中我們需要做的是通過runtime來遍歷模型中的屬性,進行屬性的比對,如果模型中的屬性在字典中不存在,那么就會去updateDict中尋找,如果updateDict字典中存在的話就會進行轉換。objctWithDict:方法更新如下:
?
?
到了這里轉換已經完成,那么我們更新下heroDict:方法代碼:
?
?
到了這里runtime轉換的方法也完成了。對比兩個方法的話可能明顯會發現第一種方法會比較簡單。但是如果是多個模型的話就需要大量的來重寫setValue:方法了,而第二種方法則可以封裝起來用以適用于各種模型。當然了如果真的是大型項目的話還是比較推薦使用一些非常優秀的第三方框架來處理模型,比如MJ大神的MJExtension使用起來簡單方便,絕對是開發的上上之選了。
?
使用jastor
如果有jastor這個庫,也會方便很多現在就基本的用法做個介紹。
假如我們有如下這么一個類
?
@interface DeviceEntity : Jastor
@property (nonatomic,strong) NSNumber *isonline;
@property (nonatomic,strong) NSNumber *isopen;
@property (nonatomic,copy) NSString *brand;
@end
#import "DeviceEntity.h"
@implementation DeviceEntity
@synthesize isopen,isonline,brand;
@end
#import <Foundation/Foundation.h>
#import "Jastor.h"
#import "DeviceEntity.h"
@interface UserDevicesEntity : Jastor
@property (nonatomic,strong) NSNumber *closecount;
@property (nonatomic,strong) NSNumber *opencount;
@property (nonatomic,copy) NSString *success;
@property (nonatomic,strong) NSArray *items;
@end
#import "UserDevicesEntity.h"
#import "DeviceEntity.h"
@implementation UserDevicesEntity
@synthesize closecount,opencount,success,items;
+ (Class) items_class {
??? return [DeviceEntity class];
}
@end
注意這里在定義相應屬性的時候如果是基本類型我們需要用NSNumber來進行包裝,上面的例子也表明了我們可以用數組來做為一個屬性,只在是實現的時候需要告訴它這個數組是什么類型的,你定義的屬性名后跟_class的形式,注意這一點不能搞錯。
?
在調用服務的時候,對方一般都會返回一個json,我們要做的就是根據這個字符串實例化一個NSDictionary出來,然后就可以根據這個NSDictionay實例化相應的模型了,比我們直接解析這個字符串方便多了,代碼如下:
我們可以驗證下,
?
?
將會打印出
?
2014-02-17 22:36:37.602 objc-grammar-learing[819:f803] device's brand is brand12014-02-17 22:36:37.605 objc-grammar-learing[819:f803] device's isonline is 12014-02-17 22:36:37.605 objc-grammar-learing[819:f803] device's isopen is 1
看看是否更方便,當然,上面的模型只是一個非常簡短的章節。一般來說,實際項目中的模型必須比這個更復雜,希望大家能繼續支持武林技術頻道哦!
新聞熱點
疑難解答