2013-10-31 53 views
19

我正在使用AFHTTPRequestOperationManager(2.0 AFNetworking庫)進行REST POST請求。但經理只需要設置參數。如何使用AFNetwork的AFHTTPRequestOperationManager設置HTTP請求正文?

-((AFHTTPRequestOperation *)POST:(NSString *)URLString 
        parameters:(NSDictionary *)parameters 
        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 
        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 

我需要爲字符串設置HTTP請求正文。我怎樣才能使用AFHTTPRequestOperationManager?謝謝。

回答

6

檢查該便利方法(POST:parameters:success:failure)在底層做了什麼,並自己動手去實際訪問實際的NSMutableRequest對象。

我正在使用AFHTTPSessionManager而不是AFHTTPRequestOperation,但我想象的機制是類似的。

這是我的解決方案:

  1. 設置會話管理器(頭等等)

  2. 手動創建NSMutable請求和添加我HTTPBody,即方便方法內基本上覆制粘貼代碼。看起來是這樣的:

    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:<url string>] absoluteString] parameters:parameters]; 
    
    [request setHTTPBody:[self.POSTHttpBody dataUsingEncoding:NSUTF8StringEncoding]]; 
    __block NSURLSessionDataTask *task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 
        if (error) { 
         // error handling 
        } else { 
         // success 
        } 
    }]; 
    
    [task resume]; 
    
4

如果你挖得在AFNetworking的來源,你會發現,在POST方法參數的情況下被設置成你的HTTP請求的身體。

將每個鍵值字典對以key1=value1&key2=value2的形式添加到主體中。對由&標誌分隔。

搜索application/x-www-form-urlencodedAFURLRequestSerialization.m

如果字符串只是一個字符串,而不是鍵值對,那麼您可以嘗試使用AFQueryStringSerializationBlockhttp://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock:但這只是我的猜測。

31

我有同樣的問題,並通過添加代碼解決了這個問題如下圖所示:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL 
       cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 

[request setHTTPMethod:@"POST"]; 
[request setValue:@"Basic: someValue" forHTTPHeaderField:@"Authorization"]; 
[request setValue: @"application/json" forHTTPHeaderField:@"Content-Type"]; 
[request setHTTPBody: [body dataUsingEncoding:NSUTF8StringEncoding]]; 

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
op.responseSerializer = [AFJSONResponseSerializer serializer]; 
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

    NSLog(@"JSON responseObject: %@ ",responseObject); 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSLog(@"Error: %@", [error localizedDescription]); 

}]; 
[op start]; 
+0

這是好事,但如何與此上傳圖片,多部分? –

+10

但如何處理'AFHTTPRequestOperationManager'? –

0

可能是我們可以使用NSMutableURLRequest,這裏是代碼:

NSURL *url = [NSURL URLWithString:yourURLString]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
                 cachePolicy:NSURLRequestUseProtocolCachePolicy 
                timeoutInterval:60.0]; 

[request setHTTPMethod:@"POST"]; 
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil]; 
NSString *contentJSONString = [[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding]; 
[request setHTTPBody:[contentJSONString dataUsingEncoding:NSUTF8StringEncoding]]; 

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
[connection start]; 
4

你可以創建你的自己定製的子類AFHTTPRequestSerializer,並將其設置爲您的AFHTTPRequestOperationManager的requestSerializer。

在這種定製requestSerializer,您可以覆蓋

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request   
           withParameters:(id)parameters 
             error:(NSError *__autoreleasing *)error; 

內,您的這個方法的實現,你將有機會到NSURLRequest,所以你可以做這樣的事情

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request  
           withParameters:(id)parameters 
             error:(NSError *__autoreleasing *)error 
{  
    NSURLRequest *serializedRequest = [super requestBySerializingRequest:request withParameters:parameters 
    error:error]; 
    NSMutableURLRequest *mutableRequest = [serializedRequest mutableCopy];   
    // Set the appropriate content type 
    [mutableRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];    
    // 'someString' could eg be passed through and parsed out of the 'parameters' value 
    NSData *httpBodyData = [someString dataUsingEncoding:NSUTF8StringEncoding]; 
    [mutableRequest setHTTPBody:httpBodyData]; 

    return mutableRequest; 
} 

你可以看看AFJSONRequestSerializer的實現,以查看設置自定義HTTP主體內容的示例。

3
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
[manager POST:url parameters:jsonObject success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    //success 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    //fail 
}]; 

這是我找到的最好,最簡潔的方式。

+0

這比其他方法簡單得多。然而奇怪的是,這似乎並沒有與GET一起工作... – Hampotato

+0

@Hampotato通常你不應該有一個身體在你的請求。這是可能的,但不標準。 – tdeegan

+0

是的,我想通了。謝謝tdeegan! – Hampotato

7

爲AFHTTPRequestOperationManager

[requestOperationManager.requestSerializer setValue:@"your Content Type" forHTTPHeaderField:@"Content-Type"]; 
[requestOperationManager.requestSerializer setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; 

// Fill parameters 
NSDictionary *parameters = @{@"name"  : @"John", 
          @"lastName" : @"McClane"}; 

// Customizing serialization. Be careful, not work without parametersDictionary 
[requestOperationManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) { 

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil]; 
    NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
    return argString; 
}]; 

[requestOperationManager POST:urlString parameters:parameters timeoutInterval:kRequestTimeoutInterval success:^(AFHTTPRequestOperation *operation, id responseObject) { 

    if (success) 
     success(responseObject); 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

    if (failure) 
     failure(error); 
}]; 
相關問題