[iOS development] Use of JSONModel

1. What is JSONModel?

JSONModel is a third-party open source library for converting json to model. After we send a request to the server, it can be easily used by us by converting the data into attributes in the model through JSONModel.

Second, the most basic usage method of JSONModel
Take the simplest json data requested by the version check API as an example
Insert picture description here

The sent version is version 2.3, then the json data at this time is

Insert picture description here

This is the json data
we get from the network request. Our next steps are:

  1. Create a Model class, this class is inherited from JSONModel
  2. Declare the requested json data as attributes in the .h file, there is no need to do other things in the .m file temporarily (if nesting is involved, there will be others)
#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
  1. Initialize the model with the data requested from the network
- (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];
}

If the passed JSON is valid, all the attributes you define will correspond to the value of the JSON, and even JSONModel will try to convert the data to the type you expect. The JSONValueTransformer class can support us to do many conversions as follows:

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

At this point we can see the output
Insert picture description here

Three, collection, nested data

Still know a request from the API
Insert picture description here

The data this time is very complicated. It has nesting and arrays. How should we deal with this nested model? We should write a class for each one to be nested, but it does not mean that we have to write multiple class files, but only need to write what should be done in one class file and line the following code:

//
//  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

In the .m file, we have to complete the realization of the class, otherwise an error will be reported

#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

We print the value of the first set of top_stories after the network request assignment is over, we can see that the acquisition has been successful
Insert picture description here

Four points to note

  1. +(BOOL)propertyIsOptional:(NSString *)propertyName does not want to crash the program because a certain value of the server does not return (nil). We will add the keyword Optional. If we don’t want to add every property, we can also use it. The rewriting method in the m file is a rewriting method. For
    example, if the version of msg of the first API is up to date, then msg has no return value. If you don’t write it, the program will crash.

  2. When I first wrote the demo, everything was correct, but the network request failed
    Insert picture description here

The following information was found:
iOS9 introduced a new feature: App Transport Security (ATS), which requires that the network accessed in the App must use the HTTPS protocol.

But now the company's project uses the HTTP protocol, using private encryption to ensure data security. Now it cannot be changed to HTTPS protocol transmission immediately.

Finally found the following solution:

Add the following in Info
Insert picture description here

  1. How can I get the elements in the mosaic array?
    You can see that the dot syntax does not work. Because it is a model nested model, it cannot be called directly.Insert picture description here

We can declare the nested model that we need, and then assign a value to it, and we can call it directly.
Insert picture description here
Insert picture description here

  1. The key setting global key mapping (applied to all models)
    is implemented in the .m file to change the name of the variable
    :
    Insert picture description here

  2. Automatically convert underlined naming to camel case naming attributes. There is a similar method, such as uppercase to lowercase: mapperFromUpperCaseToLowerCase

Insert picture description here

Guess you like

Origin blog.csdn.net/m0_46110288/article/details/109102891