一、什么是JSONModel?
JSONModel是json轉model的第三方開源庫,當我們向服務器發送一個請求之后,通過JSONModel把資料轉成model中的屬性就可以很方便的供給我們使用了,
二、JSONModel的最基本使用方法
以最簡單的一個知乎版本檢查API請求到的json資料為例

發送的版本為2.3版本 那么此時的json資料為

這個就是我們發送網路請求得到的json資料
我們接下來的步驟就是:
- 創建一個Model的類,這個類是繼承自JSONModel的
- 將請求到的json的資料在.h檔案中宣告為屬性,.m檔案中暫時不需要做其他事情(如果涉及到嵌套會有其他的)
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestModel : JSONModel
@property (nonatomic, assign) int status;
@property (nonatomic, copy) NSString* msg;
@property (nonatomic, copy) NSString* latest;
@end
NS_ASSUME_NONNULL_END
- 使用網路請求到的資料將model初始化
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString* json = @"http://news-at.zhihu.com/api/4/version/ios/2.3.0";
json = [json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *testUrl = [NSURL URLWithString:json];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testUrl];
NSURLSession *testSession = [NSURLSession sharedSession];
NSURLSessionDataTask *testDataTask = [testSession dataTaskWithRequest:testRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//這個TestModel就是上面說到的類
TestModel* country = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@",country);
}];
//任務啟動
[testDataTask resume];
}
如果傳過來的JSON合法,你所定義的所有的屬性都會與該JSON的值想對應,甚至JSONModel會嘗試去轉換資料為你期望的型別 JSONValueTransformer類可以支持我們做許多轉換 如下:
NSMutableString <-> NSString
NSMutableArray <-> NSArray
NS(Mutable)Array <- JSONModelArray
NSMutableDictionary <-> NSDictionary
NSSet <-> NSArray
BOOL <-> number/string
string <-> number
string <-> url
string <-> time zone
string <-> date
number <-> date
此時我們就可以看到輸出了

三、集合、嵌套型資料
還是知乎API的一個請求

這次的資料很復雜他有嵌套, 有陣列,我們應該怎樣處理這種嵌套模型呢?我們應該對每一個要嵌套的都寫成一個類,但并不是意味著要寫成多個類檔案,而是只需要在一個類檔案里把該有的寫好就行 如下代碼:
//
// TestModel.h
// JSONModel
//
// Created by young_jerry on 2020/10/12.
//
@protocol StoriesModel
@end
@protocol Top_StoriesModel
@end
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface StoriesModel : JSONModel
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *id;
@end
@interface Top_StoriesModel : JSONModel
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *id;
@end
@interface TestModel : JSONModel
@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSArray<StoriesModel>* stories;
@property (nonatomic, copy) NSArray<Top_StoriesModel>* top_stories;
//
//@property (nonatomic, assign) int status;
//@property (nonatomic, copy) NSString *msg;
//@property (nonatomic, copy) NSString *latest;
@end
NS_ASSUME_NONNULL_END
在.m檔案中我們則要完成類的實作,不然會報錯
#import "TestModel.h"
@implementation Top_StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation TestModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
我們在網路請求賦值結束后列印一下第一組top_stories的值,可以看見已經獲取成功了

四、注意的幾點
-
+(BOOL)propertyIsOptional:(NSString *)propertyName 作用是不想因為服務器的某個值沒有回傳(nil)就使程式崩潰, 我們會加關鍵字Optional,如果不想每一條屬性都添加,我們也可以在.m檔案中重寫方法 這個就是重寫了方法
比如第一個API的msg如果版本已經最新了,那么msg就沒有回傳值 如果不寫就會造成程式的崩潰 -
在剛開始寫demo時,所有的正確,但是網路請求就是失敗

查詢到以下資訊:
iOS9引入了新特性:App Transport Security (ATS),新特性要求App內訪問的網路必須使用HTTPS協議,
但是現在公司的專案使用的是HTTP協議,使用私有加密方式保證資料安全,現在也不能馬上改成HTTPS協議傳輸,
最終找到以下解決辦法:
在Info中添加如下

- 怎么樣可以獲取鑲嵌陣列中的元素呢
可以看到點語法是行不通的 由于是model嵌套model所以不能直接呼叫
我們可以再宣告一下需要的被嵌套的model,然后給其賦值,就可以直接呼叫了,


-
key設定全域鍵映射(應用于所有model)
在.m檔案中實作 作用是給變數換名字
換名:

-
自動把下劃線方式的命名轉為駝峰命名屬性,還有類似的,如大寫轉為小寫的方法:mapperFromUpperCaseToLowerCase

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/181979.html
標籤:其他
