無線客戶端框架設計(5.1):將JSON映射爲實體對象(iOS篇)

iOS開發人員已經習慣於將JSON轉換爲字典或者數組來進行操做了,接下來我要作的事情,可能匪夷所思,可是,對WP和Android開發人員而言,他們更傾向於將JSON轉換爲實體對象進行操做。算法

我所設計的客戶端框架,三個平臺之間互相取長補短,保持統一的思想,而其中最重要的一環就是,面向對象的編程方式。編程

書接上文,我在異步調用完MobileAPI併成功獲取到JSON後,僅僅將其轉換爲jsonValue,以下所示:json

201309052152.jpg

後續要作的事情,就是把jsonValue轉換爲實體對象了。數組

首先,要說一下JSON的格式。app

MobileAPI返回的JSON字符串有幾種格式:框架

1)單一實體:異步

a)簡單屬性:單元測試

{測試

    "userName": "baobao",atom

    "userAge": 18

}

b)屬性中有複合屬性,且該複合屬性是另外一個自定義實體:

{

     "UserId": 1,

     "UserInfo": {

              "userName": "baobao",

       "userAge": 18

}

}

c)屬性中有複合屬性,且該複合屬性是一個數組:

{

     "Career": "IT",

     "Users": [

        {

             "userName": "Bill.Gates",

             "userAge": 60

        },

        {

             "userName": "baobao",

             "userAge": 18

        }

    ]

}

2)數組

    a)規範的寫法:

    {

    "Users": [

        {

            "userName": "Bill.Gates",

            "userAge": 60

        },

        {

            "userName": "baobao",

            "userAge": 18

        }

    ]

}    

    b)不規範的寫法:

    [

    {

        "userName": "Bill.Gates",

        "userAge": 60

    },

    {

        "userName": "baobao",

        "userAge": 18

    }

]


對以上格式進行概括,咱們發現,只須要指定好:

1)整個JSON字符串是規範的(這時是一個字典),仍是不規範的(這時是一個數組)

2)對於規範的JSON字符串,每一個JSON字段映射爲實體的哪一個字段,就是說,from是什麼,to是什麼?

3)實體字段的數據類型。對於JSON而言,簡單類型,只有NSString和NSNumber兩種(日期按字符串對待,布爾值按整數0和1對待)。複合類型,有2種:要麼是一個自定義實體(這時是一個字典),要麼是一個數組。

基於此,咱們建立統一格式的實體格式以下:

//如下爲UserEntity.h文件:

#import <Foundation/Foundation.h>

 

@class ObjectMapping;

 

@interface UserEntity : NSObject

{

NSString *name;

NSNumber *age;

}

 

@property (nonatomic,retain) NSString *name;

@property (nonatomic,retain) NSNumber *age;

 

- (ObjectMapping *)objectMapping;

 

@end

//如下爲UserEntity.m文件:

#import "UserEntity.h"

#import "ObjectMapping.h"

 

@implementation UserEntity

 

@synthesize name;

@synthesize age;

 

- (ObjectMapping *)objectMapping {

ObjectMapping *mapping = [ObjectMapping mappingForClass:[UserEntity class]];

[mapping converEntityFromJsonToEntity:@"userName" to:@"name" withClass: @"NSString"];

[mapping converEntityFromJsonToEntity:@"userAge" to:@"age" withClass: @"NSNumber"];

return mapping;

}

 

- (void)dealloc {

[name release];

[age release];

 

[super dealloc];

}

 

@end

  

在格式統一的狀況下,咱們來討論在MyApp中是如何使用的,參見APageViewController.m文件,咱們繼續改造上一節沒有完成的requestFinished方法:

201309101117.jpg

經過ObjectMappingLoader的loadObjectWithClassName方法,咱們將jsonValue轉換爲實體result,而後再一次將result強制轉換爲WeatherWrapEntity類型的實體。接下來咱們就可使用weatherWrapEntity實體中的任何屬性了,都是JSON裏面返回的數據。

使用起來很是簡單,但這一切都是MyLib類庫下ObjectMapping目錄中的3個類來實現的:

201309101122.jpg

原理比較簡單,使用到了迭代算法,把JSON格式的字符串先轉換爲字典,而後再迭代之,轉換爲實體。

本節源碼以下: YoungHeart-Chapter-05-1.zip

另外,對各類狀況的模擬,參見MyApp下的MyAppTest目錄,這是一個單元測試,相應的Target爲MyAppTests,每次修改MyLib的時候不是要把libMyLib.a從新引入到MyApp項目的MyApp這個Target中嘛,請同時將其也引入到MyAppTests這個Target中。

相關文章
相關標籤/搜索