AFNetWorking初探のAFHTTPRequestOperationManager(一)

10984 ワード

使用方法は以下のpost getと大同小異
-(void)getTrainOnWaySearchGroupList:(NSDictionary*)value isClean:(BOOL)clean completeblock:(void (^)(NSDictionary *))complete faild:(void (^)(void *))faild
{
    
    NSString* requestURI=[[NSString alloc] initWithFormat:@"%@%@",SERVER_URI,TRAINXCGROUPSEARCHLIST];
    
    
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
   // manager.responseSerializer = [AFHTTPResponseSerializer serializer];//          self.responseSerializer = [AFHTTPReponseSerializer serializer]
    
    [manager POST:requestURI parameters:value
     
          success:^(AFHTTPRequestOperation *operation,id responseObject) {
              
             
              
          }failure:^(AFHTTPRequestOperation *operation,NSError *error) {
              
              //NSLog(@"    !%@",error);
              faild(nil);
              
          }];
    
}

使い方が簡単
1.managerの初期化
2.managerを呼び出す方法、例えば上で呼び出すのはmanagerの中のpost方法で、もし開くならば.hファイルには他にもget put headを見つける方法がたくさんあります...
初期化
初期化プロセスafnetworingは、managerメソッドを呼び出すだけでソースコードを以下のようにカプセル化します.
+ (instancetype)manager {
    return [[self alloc] initWithBaseURL:nil];
}

- (instancetype)init {
    return [self initWithBaseURL:nil];
}

- (instancetype)initWithBaseURL:(NSURL *)url {
    self = [super init];
    if (!self) {
        return nil;
    }

    // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
    if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
        url = [url URLByAppendingPathComponent:@""];
    }

    self.baseURL = url; 

    self.requestSerializer = [AFHTTPRequestSerializer serializer]; 
    self.responseSerializer = [AFJSONResponseSerializer serializer];

    self.securityPolicy = [AFSecurityPolicy defaultPolicy]; //    

    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];

    self.operationQueue = [[NSOperationQueue alloc] init];//             post,get         request       

    self.shouldUseCredentialStorage = YES;

    return self;
}

この過程でまずif文が空の文字列注釈を追加するために書いたのはNSURL+URLWithString:relativeToURL:この方法が正常に動作することを保証するためです.詳しくはアップルのAPIを見ることができます.次に、一連の付与操作を示します.
まずself.requestSerializer初期化操作は何をしましたか?ソースコードは次の通りです.
+ (instancetype)serializer {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (!self) {
        return nil;
    }

    self.stringEncoding = NSUTF8StringEncoding;//  

    self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary];

    // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
    NSMutableArray *acceptLanguagesComponents = [NSMutableArray array];
    [[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        float q = 1.0f - (idx * 0.1f);
        [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g", obj, q]];
        *stop = q <= 0.5f;
    }];
    [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"];

    NSString *userAgent = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
    // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
    userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
    userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]];
#endif
#pragma clang diagnostic pop
    if (userAgent) {
        if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
            NSMutableString *mutableUserAgent = [userAgent mutableCopy];
            if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
                userAgent = mutableUserAgent;
            }
        }
        [self setValue:userAgent forHTTPHeaderField:@"User-Agent"];
    }

    // HTTP Method Definitions; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
    self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", @"DELETE", nil];

    self.mutableObservedChangedKeyPaths = [NSMutableSet set];
    for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
        if ([self respondsToSelector:NSSelectorFromString(keyPath)]) {
            [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext];
        }
    }

    return self;
}

このrequsetserializerメソッドでは、リクエストヘッダを設定するなど、あいまいなことがたくさん見られます.
ここではself.responseSerializer = [AFJSONResponseSerializer serializer]; 以前、AFHTTPRequestOperationについて紹介する際に、類似の付与操作selfを見たことがある.responseSerializer = [AFHTTPReponseSerializer serializer];実はこの2つの場所の声明は同じAFHTTPReponseSerializerはAFJSOnResponseSerializerの親です.AFJSOnResponseSerializerは親クラスのserializerの2つのserializerメソッドをカバーしています.
AFHTTPReponseSerializer
@implementation AFHTTPResponseSerializer

+ (instancetype)serializer {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (!self) {
        return nil;
    }

    self.stringEncoding = NSUTF8StringEncoding;

    self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
    self.acceptableContentTypes = nil;

    return self;
}

AFJSONResponseSerializer
@implementation AFJSONResponseSerializer

+ (instancetype)serializer {
    return [self serializerWithReadingOptions:(NSJSONReadingOptions)0];
}

+ (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions {
    AFJSONResponseSerializer *serializer = [[self alloc] init];
    serializer.readingOptions = readingOptions;

    return serializer;
}

- (instancetype)init {
    self = [super init]; //      
    if (!self) {
        return nil;
    }

    self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];//        nil        

    return self;
}

全体的に実は子類は親類よりもっと仕事を完成しなければならない.acceptableContentTypeに2を割り当てる.SerializerをAFJSOnResponseSerializerタイプとして宣言するとreadingOptionsに割り当てられます(まだ不明です)
注意:managerを使用する場合、エラーの原因を報告することが多い
Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/plain"UserInfo={com.alamofire.serialization.response.error.response=
これはacceptableContentTypeという値がデフォルトで我々に与えられているのは@「アプリケーション/json」、@「text/json」、@「text/javascript」であり、多くのサーバがtext/plainを要求しているためであり、この問題を解決するには2つの案がある.ソースコードを変更してtext/plainを追加します.2.manager初期化完了後に追加
//manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];//プロンプトがtext/htmlの場合、これを追加します.
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/plain"];
managerを呼び出す方法
...manager.h私たちはこの中に以下のような方法がたくさんあることを発見しました.名前をget headなどに変えて着るパラメータは同じです.
/**
 Creates and runs an `AFHTTPRequestOperation` with a `GET` request.

 @param URLString The URL string used to create the request URL.
 @param parameters The parameters to be encoded according to the client request serializer.
 @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
 @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.

 @see -HTTPRequestOperationWithRequest:success:failure:
 */
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                     parameters:(id)parameters
                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;

公式の解釈は最後に-HST PRequestOperationWithRequest:success:failure:この方法を参照してください.この方法が何をしているのかはともかく、私たちが呼び出す上の方法のソースコードを見てみましょう.
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                     parameters:(id)parameters
                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];//  self.requestSerializer requsetWithMethod:URLString :parameters:error:  ,        。
    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];//                 。

    [self.operationQueue addOperation:operation];//        

    return operation;
}

ソースコードをよく見るとget postでもheadでも基本的にはこのいくつかのステップがあります
1.selfを呼び出す.requestSerializerのrequsetWithMethod:URLString:parameters:error:メソッドはrequestを取得します.
2.このrequestをパラメータとしてHTTPRequestOperationWithRequest:success:failure:この方法でopreationが得られる.
3.opreationをリクエストキューに追加してリクエストを開始します.