[iOS] Use a singleton to encapsulate network requests implemented through AFNetworking


Preface

Previously, in the weather forecast, the author used Foundationthe native network request class in the framework NSURLSession. Let's first take a look at our NSURLSessionexample of requesting network data:

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    request.HTTPMethod = @"GET";
    [request setValue:@"application/json" forHTTPHeaderField:@"Conten-Type"];
    
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
    
        if(error){
    
    
            NSLog(@"error = %@",error);
        }else{
    
    
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            NSLog(@"dic = %@",dic);
        }
    }];
    [task resume];

Next, let’s take a look at AFNetworkinghow to make network requests:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    
        NSLog(@"responseObject = %@",responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    
    
        if (error) {
    
    
            NSLog(@"error = %@",error);
        }
    }];

From such a comparison, it is obvious AFNetworkingthat less code is required to implement network requests.

Next, the author will use examples to explain in detail how to use singleton encapsulation to AFNetworkingimplement network requests.

Singleton encapsulates network requests

Before introducing the use of singleton encapsulation of network requests, let us first explain why we useSingletonTo encapsulate network requests:

In the previous weather forecast, because there were many pages, each page needed to request data from the network, so the author created multiple objects to request different network data, but this undoubtedly wasted memory. If there is a single For example, if you are specifically responsible for making network requests , such problems will not occur.

At the same time, the network request logic is encapsulated into a singleton class, which is responsible for creating, managing and sending network requests . In this way, you can centralize network request-related code in one place to improve code maintainability and readability.

Next, the author will explain this knowledge through examples:

1. First create a singleton class that inherits from NSObject. Here, the author names the singleton class after Manager, and then declares and implements the initialization method of the singleton class.

.h file:
Insert image description here

.m file:

//创建一个单例
static Manager *managerSington = nil;

@implementation Manager

+ (instancetype)shareManager {
    
    
    if (!managerSington) {
    
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
    
            managerSington = [[Manager alloc] init];
        });
    }
    return managerSington;
}

The author used GCD to create a singleton here. The role of GCD here is to ensure that the code block is only executed once. This is thread-safe and will not cause problems even in multi-threaded environments.

static dispatch_once_t onceToken;:This is a GCD variable used to ensure that a block of code is executed only once dispatch_once_t.

dispatch_once(&onceToken, ^{ ... }):This is a GCD dispatch_oncefunction that accepts a dispatch_once_tvariable and a code block as arguments. It ensures that the code within the block will only be executed on the first call and subsequent calls will be ignored.

2. After implementing the singleton creation method, we can make network requests through the method AFNetworkinginGET

- (void)NetWorkGetWithData:(id)TestModelBolck andError:(id)errorBlock {
    
    

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    NSString *url = @"https://news-at.zhihu.com/api/4/version/ios/2.3.0";
    
    [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    
    
        TestModel2 *testModel = [[TestModel2 alloc] initWithDictionary:responseObject error:nil];
        
        mainModelBolck(testModel);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    
    
    
        NSLog(@"Error: %@", error);
        
    }];
}

Let's analyze the source code of the GET method and parse it:

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(nullable id)parameters
                      headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                     progress:(nullable void (^)(NSProgress * _Nonnull))downloadProgress
                      success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
    
    
    
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                        URLString:URLString
                                                       parameters:parameters
                                                          headers:headers
                                                   uploadProgress:nil
                                                 downloadProgress:downloadProgress
                                                          success:success
                                                          failure:failure];
    
    [dataTask resume];
    
    return dataTask;
}

The author explains here the meaning of each parameter.

URLString(NSString type): Indicates the URL string to send a GET request, that is, the target address of the request.
parameters(optional id type): Contains the parameters of the GET request. These parameters will be appended to the URL string so that the server can return corresponding data based on these parameters. It is usually an NSDictionary or other data structure containing key-value pairs representing request parameters.
headers(optional NSDictionary type): A dictionary containing HTTP request headers. HTTP request headers usually contain information related to the request, such as authorization token, user agent, accepted data types, etc. The parameters here allow you to customize request headers.
downloadProgress(optional NSProgress type block): A block object used to track download progress. This block will be called when downloading data and can be used to update the UI or record download progress, etc.
success(optional block): A success callback block that will be called when the request completes successfully. This block usually accepts two parameters, the first parameter is an object containing the response data NSURLSessionDataTask, and the second parameter is the response data, usually one NSDictionaryor other data structure.
failure(optional block): A failure callback block that will be called when the request fails. This block usually accepts two parameters. The first parameter is NSURLSessionDataTaskan object containing information about the requested task, and the second parameter is an NSError object containing information about the request failure.
Inside this method, first dataTaskWithHTTPMethod:URLString:parameters:headers:uploadProgress:downloadProgress:success:failure:create an NSURLSessionDataTaskobject by calling the method, then use resumethe method to start executing the task (send a GET request), and finally return the task object so that the caller can perform further operations or cancel the task.

The source code of AFNetworking will be studied in depth in the future. What needs to be noted in the GET method is that it is returned when our request is successful id _Nullable responseObject. This parameter is the response data, usually one NSDictionaryor other data structure. We can get the data we request from the network by assigning responseObjectit to our objectJSONModel

When we successfully request the data and put it into our object, we pass its object to our other files through Block pass value

typedef void (^TestModelBlock) (TestModel2 *model);
typedef void (^TestModelBlockElse) (TestModel3 *model);

Then pass the code block in the implementation file:

    [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    
    
        TestModel2 *testModel = [[TestModel2 alloc] initWithDictionary:responseObject error:nil];
        
        mainModelBolck(testModel);
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    
    
    
        NSLog(@"Error: %@", error);
        
    }];

3. How to create a singleton in the Controller file and perform network requests

    [[Manager shareManager] NetWorkGetWithData:^(TestModel2 *TestModelBolck) {
    
    
        NSLog(@"%@",TestModelBolck);
        NSLog(@"请求成功");
    } andError:^(NSError * _Nullable error) {
    
    
        NSLog(@"失败");
    }];

Combining the above three steps, we successfully used a singleton to encapsulate the network request implemented through AFNetworking.

Guess you like

Origin blog.csdn.net/weixin_72437555/article/details/133904672