AFN - AFURLRequestSerialization

這個(gè)類主要實(shí)現(xiàn)了對(duì)于不同情況的請(qǐng)求的request對(duì)象的封裝。尤其是對(duì)于multipart/form-data類型的request的封裝,簡(jiǎn)化了我們自己封裝過程的痛苦。如果我們要使用multipart/form-data類型的請(qǐng)求

字符串編碼

將參數(shù)進(jìn)行百分號(hào)編碼(URL編碼)為什么需要Url編碼

AFQueryStringPairsFromDictionary(NSDictionary *dictionary);

期間調(diào)用全局函數(shù)百分號(hào)編碼
AFPercentEscapedStringFromString(NSString *string)

AFURLRequestSerialization協(xié)議

內(nèi)部使用方法,實(shí)現(xiàn)可以在AFJSONRequestSerializer、AFHTTPRequestSerializer、AFPropertyListRequestSerializer情況下對(duì)requst的設(shè)置恰當(dāng)?shù)恼?qǐng)求頭和請(qǐng)求體。

setter方法

AFHTTPRequestSerializerObservedKeyPaths全局方法指定了request請(qǐng)求序列化要觀察的屬性列表、是一個(gè)數(shù)組,里面有對(duì)蜂窩數(shù)據(jù)、緩存策略、cookie、管道、網(wǎng)絡(luò)狀態(tài)、超時(shí)這幾個(gè)元素。

@property (nonatomic, assign) BOOL allowsCellularAccess;
@property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy;
@property (nonatomic, assign) BOOL HTTPShouldHandleCookies;
@property (nonatomic, assign) BOOL HTTPShouldUsePipelining;
property (nonatomic, assign) NSTimeInterval timeoutInterval;
@property (nonatomic, assign) NSURLRequestNetworkServiceType networkServiceType;


KVO的應(yīng)用詳解鍵值觀察(KVO)及其實(shí)現(xiàn)機(jī)理

static NSArray * AFHTTPRequestSerializerObservedKeyPaths() {
    static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))];
    });

    return _AFHTTPRequestSerializerObservedKeyPaths;
}


//
- (instancetype)init {
    self = [super init];
    if (!self) {
        return nil;
    }
    
    …………
       self.mutableObservedChangedKeyPaths = [NSMutableSet set];
    for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
        if ([self respondsToSelector:NSSelectorFromString(keyPath)]) {
            [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext];
        }
    }
    
   }

NSKeyValueObserving 代理實(shí)現(xiàn)

首先通過automaticallyNotifiesObserversForKey方法來阻止一些屬性的KVO機(jī)制的觸發(fā),然后我們通過重寫蜂窩數(shù)據(jù)、緩存策略、cookie、管道、網(wǎng)絡(luò)狀態(tài)、超時(shí)的觀察??梢杂糜跍y(cè)試這些屬性變化是否崩潰等。

- (void)setAllowsCellularAccess:(BOOL)allowsCellularAccess {
    [self willChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))];
    _allowsCellularAccess = allowsCellularAccess;
    [self didChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))];
}



/**
 如果kvo的觸發(fā)機(jī)制是默認(rèn)出發(fā)。則返回true,否則返回false。在這里,只要是`AFHTTPRequestSerializerObservedKeyPaths`里面的屬性,我們都取消自動(dòng)出發(fā)kvo機(jī)制,使用手動(dòng)觸發(fā)。

 @param key kvo的key
 @return bool值
 */
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
    if ([AFHTTPRequestSerializerObservedKeyPaths() containsObject:key]) {
        return NO;
    }
    return [super automaticallyNotifiesObserversForKey:key];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(__unused id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    //是否是選擇要觀察的屬性
    if (context == AFHTTPRequestSerializerObserverContext) {
        //如果屬性值為null,則表示么有這個(gè)屬性,移除對(duì)其的觀察
        if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) {
            [self.mutableObservedChangedKeyPaths removeObject:keyPath];
        } else {
            //添加到要觀察的屬性的集合
            [self.mutableObservedChangedKeyPaths addObject:keyPath];
        }
    }
}


請(qǐng)求頭處理

@property (readonly, nonatomic, strong) NSDictionary <NSString *, NSString *> *HTTPRequestHeaders;
//設(shè)置一個(gè)請(qǐng)求頭域
- (void)setValue:(nullable NSString *)value
forHTTPHeaderField:(NSString *)field;
- (nullable NSString *)valueForHTTPHeaderField:(NSString *)field;

//設(shè)置Basic Authorization的用戶名和密碼。記住需要是base64編碼格式的
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username
                                       password:(NSString *)password;
- (void)clearAuthorizationHeader;

http body設(shè)置


//默認(rèn)直接從參數(shù)創(chuàng)建
- (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style;

//自定義創(chuàng)建body
- (void)setQueryStringSerializationWithBlock:(nullable NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block;


創(chuàng)建request對(duì)象

/**
 根據(jù)給定的url、方法名、參數(shù)構(gòu)建一個(gè)request。

 */
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                 URLString:(NSString *)URLString
                                parameters:(id)parameters
                                     error:(NSError *__autoreleasing *)error
                                     
                                     
                                     
  /**
 構(gòu)建一個(gè)multipartForm的request。并且通過`AFMultipartFormData`類型的formData來構(gòu)建請(qǐng)求體
 */
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
                                              URLString:(NSString *)URLString
                                             parameters:(NSDictionary *)parameters
                              constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                                                  error:(NSError *__autoreleasing *)error
                                                  
                                                  
   /**
 通過一個(gè)Multipart-Form的request創(chuàng)建一個(gè)request。新request的httpBody是`fileURL`指定的文件。
 并且是通過`HTTPBodyStream`這個(gè)屬性添加,`HTTPBodyStream`屬性的數(shù)據(jù)會(huì)自動(dòng)添加為httpBody。
 */
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
                             writingStreamContentsToFile:(NSURL *)fileURL
                                       completionHandler:(void (^)(NSError *error))handler

子類

  • AFStreamingMultipartFormData

AFStreamingMultipartFormData負(fù)責(zé)multipart/form-data的Body的具體構(gòu)建,實(shí)現(xiàn)了AFMultipartFormData的代理方法

  • AFJSONRequestSerializer

對(duì)于AFJSONRequestSerializer。重寫了構(gòu)建request的方法,把Content-Type指定為"application/json"

  • AFPropertyListRequestSerializer

AFPropertyListRequestSerializer,也是同樣的道理,把Content-Type指定為"application/x-plist"

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容