• 无线客户端框架设计(5.1):将JSON映射为实体对象(iOS篇)


    iOS开发人员已经习惯于将JSON转换为字典或者数组来进行操作了,接下来我要做的事情,可能匪夷所思,但是,对WP和Android开发人员而言,他们更倾向于将JSON转换为实体对象进行操作。

    我所设计的客户端框架,三个平台之间互相取长补短,保持统一的思想,而其中最重要的一环就是,面向对象的编程方式。

    书接上文,我在异步调用完MobileAPI并成功获取到JSON后,仅仅将其转换为jsonValue,如下所示:

    201309052152.jpg

    后续要做的事情,就是把jsonValue转换为实体对象了。

    首先,要说一下JSON的格式。

    MobileAPI返回的JSON字符串有几种格式:

    1)单一实体:

    a)简单属性:

    {

        "userName": "baobao",

        "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中。

  • 相关阅读:
    CSS清浮动
    深入理解BFC
    深入理解CSS浮动
    CSS颜色模式转换器的实现
    深入理解CSS背景
    理解CSS前景色和透明度
    深入理解CSS六种颜色模式
    HTML学习目录
    深入理解display属性
    深入理解盒模型
  • 原文地址:https://www.cnblogs.com/Jax/p/3311832.html
Copyright © 2020-2023  润新知