JSONModel的使用

weixin_33866037發表於2017-08-03
3626034-27fa7cdd6c6947b4.jpg
coverImage.jpg

1. 命名自動匹配

a. Model屬性名和伺服器返回資料欄位一致

{
    @"id":"123",
    @"name":"巧克力",
    @"price":"6.66"
}

  @interface ProductModel : BaseModel
  @property (nonatomic, strong) NSString *id;
  @property (nonatomic, strong) NSString *name;
  @property (nonatomic, assign) float     price;

  @end

2. Model關聯(model含有其它model)

a. Model屬性名和伺服器返回資料一致;
b. 關聯其它Model的屬性需要指定自身型別(例如:ProductModel *)

  {
      “order_id”:104,
      “total_price”:110,
      “product”: {
           “id”:”123”,
           “name”:”productName”,
           “price”:”110”,
      }
  }

  @interface OrderModel : BaseModel
  @property (nonatomic, strong) NSString     *order_id;
  @property (nonatomic, assign) float        total_price;
  @property (nonatomic, strong) ProductModel *product;

  @end

3. Model集合(Model含有其它model的集合)

a. NSArry後的就<>中包含一個協議,使用JSONModel必須實現這個協議!
b. 層級巢狀,Model中包含其他Model集合,必須實現該協議
c. 包含其他Model集合的屬性需要指定層級型別和自身型別(例如:NSArray<ProductModel> *)

 @protocol ProductModel
 @end
 @interface OrderModel : JSONModel
 @property (nonatomic, strong) NSString *order_id;
 @property (nonatomic, assign) float     total_price;
 @property (nonatomic, strong) NSArray<ProductModel> *products;

 @end

4. 鍵對映

a. 在一個Model中獲取伺服器返回資料不同層級的資料;
b. 例如:order_id和name不在同一層級;
c. 採用KVC的方式來取值,並賦值給Model屬性(order_details.name ---> productName order_details.price.usd ---> price);

 {
   "order_id": 104,
   "order_details" : [
     {
       "name": "name_#1",
       "price": {
         "usd": 12.95
       }
     }
   ]
 }

@interface OrderModel : BaseModel
@property (nonatomic, strong) NSString *id;
@property (nonatomic, assign) float    price;
@property (nonatomic, strong) NSString *productName;
@end
@implementation OrderModel
+ (JSONKeyMapper *)keyMapper 
{
    return [[JSONKeyMapper alloc] initWithDictionary:@{
                                        @"order_id": @"id",
@"order_details.name": @"productName",                                                                  @"order_details.price.usd": @"price"}];
}

@end

d.全域性Global key mapping. (使所有的模型都具備)

JSONKeyMapper *keyMapper = [[JSONKeyMapper alloc] initWithDictionary:@{@"id":@"modelId"}];
[BaseModel setGlobalKeyMapper:keyMapper];

5. 設定下劃線自動轉駝峰

a. 自定義把下劃線欄位解析為駝峰命名屬性
b. 場景:伺服器資料返回下劃線命名欄位可為Model中以駝峰命名的屬性相應的賦值
c. mapperFromUpperCaseToLowerCase 大寫轉小寫

 {
   "order_id": 104,
   "order_product" : @"Product#1",
   "order_price" : 12.95
 }

@interface OrderModel : BaseModel
@property (nonatomic, strong) NSString *orderId;
@property (nonatomic, assign) float     orderPrice;
@property (nonatomic, strong) NSString *orderProduct;

@end

@implementation OrderModel
+ (JSONKeyMapper *)keyMapper
{
    return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
}

@end

6. 可選屬性(屬性值可以為空或null)

a. 某些屬性值可以為空;
b. 防止由於伺服器返回資料為空導致JSONModel異常(程式崩潰);

eg: @property (nonatomic, strong) NSString<Optional> *urlString;

7. 忽略屬性(屬性值可以完全忽略)

a. 解析時完全忽略它;
b. 場景:該屬性不需要從伺服器資料中獲取;

 eg: @property (nonatomic, strong) NSString<Ignore> *urlString;

8. 設定所有屬性可選(所有屬性值可以為空)

a. Model 的所有屬性值可以為空;
b. 防止由於伺服器資料返回空導致JSONModel異常(程式崩潰);
c. 官方建議儘量避免使用該方法(即使要全部屬性為可選,也儘量是在每個屬性那裡標註為Optional);

eg: 
@implementation HomeHotModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName 
{
    return YES;
}
@end

9. 將Model匯出字典或JSON字串

a. 快速匯出Model中所有屬性和屬性值;

 eg:
 HomeHotModel *model = [[HomeHotModel alloc] initWithString:jsonString  error:nil];
 //以字典形式匯出
 NSDictionary *dict = [model toDictionary];
 //以字串形式匯出
 NSString *string = [model toJSONString];

10. 自定義資料處理(JSON資料格式:string, number, array, object, 以及null)

a. 新增NSDate轉換:根據後臺返回時間戳格式進行相應處理(eg:UIColor);
b. 場景:內嵌轉換,不能滿足需求,需要自定義;
c. JSONModel支援型別如下圖:

3626034-3c457e8d8dccda1c.png
JSONModel支援型別.png
eg:
#import "JSONValueTransformer+CustomTransformer.h"
@implementation JSONValueTransformer (CustomTransformer)
//時間戳轉NSDate
- (NSDate *)NSDateFromNSString:(NSString *)string
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSDate *date = [formatter dateFromString:string];
    return date;
}

//NSDate轉時間戳
- (NSString *)JSONObjectFromNSDate:(NSDate *)date
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *dateStr = [formatter stringFromDate:date];
    return dateStr;
}

@end

11. 延遲載入, 這種比較推薦,可以減少在網路讀取時的效能消耗,關鍵字為: ConvertOnDemand

{
    "order_id": 104,
    "total_price": 103.45,
    "products" : [
                  {
                      "id": "123",
                      "name": "Product #1",
                      "price": 12.95
                  },
                  {
                      "id": "137",
                      "name": "Product #2",
                      "price": 82.95
                  }
                  ]
}

使用模型:
@protocol ProductModel
@end

//產品Model
@interface ProductModel : JSONModel
@property (nonatomic, strong) NSString *id;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) float     price;
@end

//訂單Model
@interface OrderModel : JSONModel
@property (nonatomic, strong) NSString *order_id;
@property (nonatomic, assign) float    total_price;
@property (nonatomic, strong) NSArray<ProductModel, ConvertOnDemand> *products;
@end

12. 模型的批處理,即一次可以處理一批模型

NSArray *models = [OrderModel arrayOfObjectsFromDictionaries:jsonDatas error:nil];

相關文章