AFNetworking, as read in this article, is version 3.2.0.

The AFHTTPSessionManager class is the most commonly used AFNetworking class. This class is a subclass of AFURLSessionManager, which encapsulates the creation method of HTTP requests. So after reading afurlssession Manager in the previous article, it will be much easier to look at this class again.

1. Interface file

1.1. The attribute

/ * * is used to construct the NSURL object + URLWithString: relativeToURL: method of the relative path * / @ property (readonly, nonatomic, strong, nullable) NSURL *baseURL; /** request serialization object, The default is the AFHTTPRequestSerializer object */ @property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer; /** response serialized object, The default is the AFJSONResponseSerializer object */ @property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer; /** the securityPolicy object used to ensure a secure connection. The default is' defaultPolicy '*/ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy;Copy the code

Method of 1.2.

/* + (instanceType)manager; */ - (instancetype)initWithBaseURL:(nullable NSURL *)url; */ - (instancetype)initWithBaseURL:(nullable NSURL *)url sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; /** create a nullable NSURLSessionDataTask for a GET request */ - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Create an NSURLSessionDataTask that executes a GET request, with a progress callback, but the progress callback is in the operation queue created in the AFURLSessionManager class, */ - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; Nullable NSURLSessionDataTask */ - (NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task))success failure:(nullable void  (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; Nullable NSURLSessionDataTask */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Create an NSURLSessionDataTask that executes a POST request with a progress callback, but the progress callback is in the operation queue created in the AFURLSessionManager class. */ - (nullable NSURLSessionDataTask *)POST (NSString *)URLString parameters:(nullable id)parameters progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** create a nullable NSURLSessionDataTask */ - (nullable NSURLSessionDataTask *)POST:(NSString) *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Create an NSURLSessionDataTask that executes a multipart/form-data POST request with a progress callback, but the progress callback is in the operation queue created in the AFURLSessionManager class. */ - (nullable NSURLSessionDataTask *)POST (NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** create an NSURLSessionDataTask that executes a PUT request */ - (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; Nullable NSURLSessionDataTask */ - (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** create a nullable NSURLSessionDataTask that executes a DELETE request */ - (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;Copy the code

2. Implementation file

Classification of 2.1.

*/ @property (readWrite, nonatomic, strong) NSURL *baseURL;Copy the code

2.2. The key word

@dynamic responseSerializer;
@dynamic securityPolicy;
Copy the code

The @dynamic keyword tells the compiler not to implement the getter and setter for me. So in the following method we can see the manually implemented setter, but we can’t find the manually implemented getter, won’t it crash when calling the getter? It doesn’t, because this property inherits from its parent class, where its getter is already implemented, and that’s what’s called when the getter of a subclass is called.

2.3. Method implementation

  • Initialization method
+ (instanceType)manager {// Do not specify the base pathreturn[[[self class] alloc] initWithBaseURL:nil]; } - (instanceType)init {// Do not specify a base pathreturn[self initWithBaseURL:nil]; } - (instancetype)initWithBaseURL:(NSURL *)url {// specify the basic path without specifying the network session configuration objectreturn[self initWithBaseURL:url sessionConfiguration:nil]; } - (instancetype) initWithSessionConfiguration configuration: (NSURLSessionConfiguration *) {/ / basic path is not specified, the specified network session configuration objectreturn[self initWithBaseURL:nil sessionConfiguration:configuration]; } - (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration { // To call his father first class AFURLSessionManager initialization method of self = [super initWithSessionConfiguration: configuration];if(! self) {returnnil; } // Ensure terminal slash if there is no slash after a valid URLfor baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
    if([[url path] length] > 0 && ! [[url absoluteString] hasSuffix:@"/"]) {
        url = [url URLByAppendingPathComponent:@""]; } // Save the base path self.baseurl = url; Self. requestSerializer = [AFHTTPRequestSerializer serializer]; // Set request and response serializer objects self.requestSerializer = [AFHTTPRequestSerializer serializer]; self.responseSerializer = [AFJSONResponseSerializer serializer];return self;
}
Copy the code
  • Setters implemented manually
- (void)setRequestSerializer RequestSerializer: (AFHTTPRequestSerializer < AFURLRequestSerialization > *) {/ / in the debug, Crash NSParameterAssert(requestSerializer) // Save the parameter _requestSerializer = requestSerializer; } - (void)setResponseSerializer ResponseSerializer: (AFHTTPResponseSerializer < AFURLResponseSerialization > *) {/ / in the debug, Crash NSParameterAssert(responseSerializer); // Call setter [super of its parent classsetResponseSerializer:responseSerializer];
}

- (void)setSecurityPolicy:(AFSecurityPolicy *) SecurityPolicy {// if the SecurityPolicy is intended for validation, but the base path passed in does not begin with HTTPS, an exception will be thrownif(securityPolicy.SSLPinningMode ! = AFSSLPinningModeNone && ! [self.baseURL.scheme isEqualToString:@"https"]) {
        NSString *pinningMode = @"Unknown Pinning Mode";
        switch (securityPolicy.SSLPinningMode) {
            case AFSSLPinningModeNone:        pinningMode = @"AFSSLPinningModeNone"; break;
            case AFSSLPinningModeCertificate: pinningMode = @"AFSSLPinningModeCertificate"; break;
            case AFSSLPinningModePublicKey:   pinningMode = @"AFSSLPinningModePublicKey"; break;
        }
        NSString *reason = [NSString stringWithFormat:@"A security policy configured with `%@` can only be applied on a manager with a secure base URL (i.e. https)", pinningMode];
        @throw [NSException exceptionWithName:@"Invalid Security Policy"reason:reason userInfo:nil]; } // call setter [super for the parent classsetSecurityPolicy:securityPolicy];
}
Copy the code
  • Create a public method for the request
- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success :(void (^)(NSURLSessionDataTask *task, NSError *error))failurereturn[self GET:URLString parameters:parameters progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task))success failure:(void (^)(NSURLSessionDataTask *task, {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) {
        if(success) { success(task); } } failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success :(void (^)(NSURLSessionDataTask *task, NSError *error))failurereturn[self POST:URLString parameters:parameters progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST"URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id<AFMultipartFormData> _Nonnull))block success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure {// Call the following methodreturn[self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure {// Instantiate NSMutableURLRequest object NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; // Call back the error if the instantiation failsif (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }

        returnnil; } / / instantiate the object NSURLSessionDataTask __block NSURLSessionDataTask * task = [self uploadTaskWithStreamedRequest: request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {
            if(failure) { failure(task, error); }}else {
            if(success) { success(task, responseObject); }}}]; // Start task [task resume];returntask; } - (NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT"URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask  *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH"URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, {// instantiate NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE"URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; // Start dataTask [dataTask resume];returndataTask; } - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {// Instantiate NSMutableURLRequest object NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; // Call back the error if the instantiation failsif (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }

        returnnil; } // instantiate NSURLSessionDataTask __block NSURLSessionDataTask *dataTask = nil; dataTask = [self dataTaskWithRequest:request uploadProgress:uploadProgress downloadProgress:downloadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {
            if(failure) { failure(dataTask, error); }}else {
            if(success) { success(dataTask, responseObject); }}}];return dataTask;
}
Copy the code
  • NSObject methods
- (NSString *)description {// Customize print datareturn [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue];
}
Copy the code
  • NSSecureCoding method
+ (BOOL)supportsSecureCoding {
    return YES;
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))];
    NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
    if(! configuration) { NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class]forKey:@"identifier"];
        if (configurationIdentifier) {
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100)
            configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier];
#else
            configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier];
#endif
        }
    }

    self = [self initWithBaseURL:baseURL sessionConfiguration:configuration];
    if(! self) {return nil;
    }

    self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))];
    self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
    AFSecurityPolicy *decodedPolicy = [decoder decodeObjectOfClass:[AFSecurityPolicy class] forKey:NSStringFromSelector(@selector(securityPolicy))];
    if (decodedPolicy) {
        self.securityPolicy = decodedPolicy;
    }

    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [super encodeWithCoder:coder];

    [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))];
    if ([self.session.configuration conformsToProtocol:@protocol(NSCoding)]) {
        [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"];
    } else {
        [coder encodeObject:self.session.configuration.identifier forKey:@"identifier"];
    }
    [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))];
    [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
    [coder encodeObject:self.securityPolicy forKey:NSStringFromSelector(@selector(securityPolicy))];
}
Copy the code

About NSSecureCoding proxy method implementation in AFNetworking source reading (2), from AFURLRequestSerialization 4.1.2.4.7 in this article NSSecureCoding protocol methods have introduced the implementation of the paragraph.

  • NSCopying method implementation
- (instancetype)copyWithZone:(NSZone *)zone {
    AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration];

    HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone];
    HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone];
    HTTPClient.securityPolicy = [self.securityPolicy copyWithZone:zone];
    return HTTPClient;
}
Copy the code

3. Summary

AFHTTPSessionManager is a class that encapsulates the most commonly used HTTP requests.

AFNetworking

AFNetworking (A) — Start using it

Source: reading AFNetworking (2) — AFURLRequestSerialization

Source: reading AFNetworking (3) — AFURLResponseSerialization

AFNetworking (4) — AFSecurityPolicy

Source: reading AFNetworking (5) — AFNetworkReachabilityManager

AFNetworking (6) — Afurlssession Manager

AFNetworking (7) — Afhttpssession Manager

AFNetworking (8) – AFAutoPurgingImageCache

AFNetworking (9) — AFImageDownloader

The source code to read: AFNetworking (10) — AFNetworkActivityIndicatorManager

AFNetworking — UIActivityIndicatorView+AFNetworking

AFNetworking (12) — UIButton+AFNetworking

AFNetworking (13) — UIImageView+AFNetworking

UIProgressView+AFNetworking

AFNetworking — UIRefreshControl+AFNetworking

UIWebView+AFNetworking