2012-11-14 39 views
6

所以我只是切換到RestKit 0.2,我目前正在使用新的「HttpClient」,它基本上是一個AFHTTPClient。我有這行代碼:postPath AFHTTPClient中的JSON響應

RKObjectManager* objectManager = [RKObjectManager sharedManager]; 
NSDictionary* params = [[NSDictionary alloc] initWithObjectsAndKeys: login, @"username", password, @"password", nil]; 

[[objectManager HTTPClient]postPath:@"users/login/?format=json" parameters:params 
    success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     //reponseObject vs operation.response 
     NSLog(@"%@", responseObject); 
    } 
    failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    { 
     NSLog(@"ERROR"); 
    }]; 

這POST調用返回的形式的JSON響應:{ 「API_KEY」: 「...... 」「 用戶名 」:「 ......」}。就如此容易。

切換到0.2之前,我能夠做得到的響應API_KEY鍵:

[[RKClient sharedClient] post:@"https://stackoverflow.com/users/login/?format=json" usingBlock:^(RKRequest *request) 
{ 
    request.onDidLoadResponse = ^(RKResponse *response) 
    { 
     id parsedResponse = [response parsedBody:NULL]; 
     NSString *apiKey = [parsedResponse valueForKey:@"api_key"]; 
    } 
    }.....]; 

http://restkit.org/api/master/Classes/RKResponse.html

但現在,我不能這樣做,如果我做的NSLog在responseObject,我得到:

< 7b227265 61736f6e 223a2022 41504920 4b657920 666f756e 64222c20 22617069 5f6b6579 223a2022 61356661 65323437 66336264 35316164 39396338 63393734 36386438 34636162 36306537 65386331 222c2022 73756363 657373 22 3a207472 75657d>

而且奇怪的是,如果我這樣做:

 NSLog(@"%@", operation.responseString); 

我確實有JSON(在的NSString)顯示出來。

所以兩個問題:

1)爲什麼打印出我的十六進制代碼的responseObject,而不是實際的JSON響應?

2)爲什麼如果我做operation.responseString它顯示實際的響應對象?有沒有辦法從JSON中解析出ResponseObject中的實際數據?

謝謝!

回答

11

如果我沒有弄錯,你看到的是當你的成功塊被調用時NSData的原始字節。

您發佈的十六進制寫着:

{"reason": "API Key found", "api_key": "a5fae247f3bd51ad99c8c97468d84cab60e7e8c1", "success": true}

究其原因,第二NSLog顯示你想要的東西是,%@格式字符串調用描述(糾正我,如果我錯了這裏,SO)你傳遞它的對象的大小和NSData可能知道它是一個下面的字符串。

所以,就如何獲得JSON。這真的很簡單。一旦你有你的響應對象,你可以做這樣的事情:

NSDictionary* jsonFromData = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

什麼這會爲你做的是利用返回NSDictionary編碼的JSON根對象,然後將每個值在字典中會是類型NSString,NSNumber,NSArray,NSDictionaryNSNull。有關文檔,請參見NSJSONSserialization

NSJSONReadingMutableContainers使詞典和數組變得可變。這只是我的代碼中剩下的一部分。

希望你在iOS 5或更高版本,或者你需要找到解析的另一個解決方案。

+2

雖然這是一個正確的答案,但我認爲@ phix23更好,至少對於AFNetworking庫。 ;) – Kjuly

17

AFNetworking應該實例化一個AFJSONRequestOperation。可能它會創建一個基本的AFHTTPRequestOperation而不是(檢查[operation class]),從而產生一個NSData對象作爲響應。

確保您在AFHTTPClient子類(initWithBaseURL)的init方法註冊操作類:

[self registerHTTPOperationClass:[AFJSONRequestOperation class]]; 

// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 
[self setDefaultHeader:@"Accept" value:@"application/json"]; 

您也可以嘗試直接使用AFJSONRequestOperation這樣的:

NSURLRequest *request = [[objectManager HTTPClient] requestWithMethod:@"POST" path:@"users/login/?format=json" parameters:params]; 
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
    NSLog(@"JSON: %@", JSON); 
} failure:nil]; 
[[objectManager HTTPClient] enqueueHTTPRequestOperation:operation]; 
+2

+1,用於正確使用AFNetworking。應該接受這個。 – Kjuly

+1

這有助於thx很多 –

3
success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    NSData *responseData = operation.HTTPRequestOperation.responseData; 
    id parsedResponse = [RKMIMETypeSerialization objectFromData:responseData MIMEType:RKMIMETypeJSON error:nil]; 
    NSString *apiKey = [parsedResponse valueForKey:@"api_key"] 
}