2012-11-01 49 views
0

我一直試圖抓住AFHTTPClient在特定實例中調度請求到基於REST的服務,需要OAuth身份驗證。我使用GTMOAuth創建OAuth身份驗證沒有問題。AFNetworking與AFJSONRequestOperation的AFHTTPClient // MIME類型問題

我也可以成功編組參數來分派請求並使用手工修改的NSMutableURLRequest和AFJSONRequestOperation和NSURLConnection來獲取格式良好的JSON響應。後兩個機制是我的理智檢查,我正在正確地接觸這項服務。

我得到使用

[AFHTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject)] 

但無論怎樣的迴應 - 它解釋爲text/plain的。返回的對象的類是__NCFData。

沒有bueno。

這段代碼不想返回任何類型的字典的響應。

- (IBAction) testFlickr { 
// marshall parameters 
NSString *urlStr = @"http://api.flickr.com/"; 
NSURL *url = [NSURL URLWithString:urlStr]; 

AFHTTPClient *client = [[AFHTTPClient alloc]initWithBaseURL:url]; 
[client registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
[client setParameterEncoding:AFJSONParameterEncoding]; 
NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"[email protected]", @"user_id", @"1", @"jsoncallback", nil]; 

NSString *path = [[NSString alloc]initWithFormat:@"services/rest/?method=flickr.people.getPhotos"]; 

NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params]; 

// flickrAuth instance variable is an instance of GTMOAuthAuthentication 
[self.flickrAuth authorizeRequest:af_request]; 

[client setAuthorizationHeaderWithToken:[self.flickrAuth accessToken]]; 
[client setDefaultHeader:@"Accept" value:@"application/json"]; 

[client requestWithMethod:@"GET" path:path parameters:params]; 

LOG_FLICKR_VERBOSE(0, @"Can Authorize? %@", ([self.flickrAuth canAuthorize] ? @"YES":@"NO")); 
LOG_FLICKR_VERBOSE(0, @"%@", client); 


// first way of trying.. 
AFHTTPRequestOperation *af_operation = [client HTTPRequestOperationWithRequest:af_request success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    NSString *str = [[NSString alloc] initWithData:responseObject 
              encoding:NSUTF8StringEncoding]; 
    LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics, but.. %@", str); 
    LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics returns %@", [responseObject class]); 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    // 
    LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics, error.. %@", error); 

}]; 

[af_operation start]; 
} 

這個請求通過沒問題。響應數據本身就是我所期望的,但它不是任何一種字典類。

我寧願繼續使用AFHTTPClient的方法(而不是,例如,[AFJSONRequestOperation JSONRequestOperationWithRequest]),所以我可以用AFHTTPClient的可達性的方法等等。

奇怪的是(對我來說,至少),如果我不喜歡這樣的要求:

NSMutableURLRequest *aj_request = [client requestWithMethod:@"GET" path:path parameters:params]; 
[self.flickrAuth authorizeRequest:aj_request]; 

AFJSONRequestOperation *aj_operation = 
[AFJSONRequestOperation JSONRequestOperationWithRequest:af_request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
    LOG_FLICKR_VERBOSE(0, @"AFJSONRequestOperation %@", JSON); 
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
    LOG_FLICKR_VERBOSE(0, @"AFJSONREquestOperation Error %@", error); 
}]; 

[aj_operation start]; 

它失敗,出現「401」,因爲它期待在響應頭應用/ JSON,而是認爲它收到text/plain的

但是,如果我做這樣的要求:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[[NSURL alloc]initWithString:@"http://api.flickr.com/services/rest/?method=flickr.people.getPhotos&format=json&[email protected]&nojsoncallback=1"]]; 
[self.flickrAuth authorizeRequest:request]; 

AFJSONRequestOperation *operation = 
[AFJSONRequestOperation JSONRequestOperationWithRequest:request 
               success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
                LOG_FLICKR_VERBOSE(0, @"Success Flickr =========\n%@ %@", JSON, [JSON valueForKeyPath:@"photos.total"]); 
                /////handler(JSON, nil); 
               } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
                LOG_FLICKR(0, @"URL Was %@", url); 
                LOG_FLICKR(0, @"Failed Flickr ==========\n%@ %@", error, JSON); 
                /////handler(nil, error); 
               }]; 
[operation start]; 

它工作正常,包括漂亮的JSON,字典形成的數據。

在第一個實例中,我使用AFHTTPClient生成NSMutableURLRequest。在第二個例子中,我自己創建了NSMutableURLRequest。在這兩種情況下,我使用AFJSONRequestOperation發送請求,將問題留給唯一的罪魁禍首(除了我自己..)AFHTTPClient。

在我可以開始工作的第一個示例中,它不返回JSON-y數據。

在第二個例子中,AFHTTPClient似乎創建了一個明顯失敗的NSMutableURLRequest,但是當使用[NSMutableURLRequest requestWithURL]手動創建該URL時,(AFAICT)相同的URL成功。

我想知道 - 我在使用AFHTTPClient時丟失了什麼?

幫助?

回答

2

在你的第一個代碼示例中,它看起來像你在做NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params];,然後設置默認標題。默認標題僅適用於在指定後創建的請求。也許這就是事情發生錯誤的地方。

此外,401錯誤可能是抱怨它的內容類型,但401是錯誤狀態代碼,這意味着你是未經鑑定的。

0

我最終刪除了所有標題參數來隔離問題,但沒有任何區別。仔細檢查響應給了我一個線索。雖然Flickr確實返回「JSON」,但它不是無毛刺的,看起來並且需要對其中一個參數進行調整。我一直在發送jsoncallback = 1,但它應該是nojsoncallback = 1。一旦我修復了參數AFJSONRequestOperation正確處理響應並解析JSON。

我的最終代碼看起來像這樣(爲他人,注:該nojsoncallback = 1個參數)

- (IBAction)testFlickrAFJSON:(id)sender 
{ 
// marshall parameters 
NSString *urlStr = @"http://api.flickr.com/"; 
NSURL *url = [NSURL URLWithString:urlStr]; 
//NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"[email protected]", @"user_id", nil]; 
NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"[email protected]", @"user_id", @"1", @"nojsoncallback", nil]; 
NSString *path = [[NSString alloc]initWithFormat:@"services/rest/?method=flickr.people.getPhotos"]; 

AFHTTPClient *client = [[AFHTTPClient alloc]initWithBaseURL:url]; 

NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params]; 

[self.flickrAuth authorizeRequest:af_request]; 

LOG_FLICKR_VERBOSE(0, @"Can Authorize? %@", ([self.flickrAuth canAuthorize] ? @"YES":@"NO")); 
AFJSONRequestOperation *af_operation_2 = [AFJSONRequestOperation JSONRequestOperationWithRequest:af_request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     LOG_FLICKR_VERBOSE(0, @"AFJSONRequestOperation Alt %@", JSON); 
     LOG_FLICKR_VERBOSE(0,@"AFJSONRequestOperation Alt response MIMEType %@",[response MIMEType]); 

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
     LOG_FLICKR_VERBOSE(0, @"AFJSONREquestOperation Alt Error %@", error); 
     NSHTTPURLResponse *resp = [[error userInfo] valueForKey:AFNetworkingOperationFailingURLResponseErrorKey]; 
     LOG_FLICKR_VERBOSE(0,@"AFJSONRequestOperation Alt Error response MIMEType %@",[resp MIMEType]); 

    }]; 

    [af_operation_2 start]; 

}