2010-12-16 59 views
76

我是新來的Objective-C和我開始把精力大量進入請求/響應由於最近在HTTP請求發送JSON數據。我有一個可以調用url(通過http GET)並解析返回的json的工作示例。如何使用的NSURLRequest

這樣做的工作例子如下

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [responseData setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [responseData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 
    //do something with the json that comes back ... (the fun part) 
} 

- (void)viewDidLoad 
{ 
    [self searchForStuff:@"iPhone"]; 
} 

-(void)searchForStuff:(NSString *)text 
{ 
    responseData = [[NSMutableData data] retain]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]]; 
    [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
} 

我的第一個問題是 - 將這種做法擴大?或者這是不是異步(意思是我阻止用戶界面線程而應用程序正在等待響應)

我的第二個問題是 - 我怎麼可能會修改這一請求的一部分做了POST,而不是得到什麼?是否只是像這樣修改HttpMethod?

[request setHTTPMethod:@"POST"]; 

最後 - 我怎麼一組JSON數據添加到這個崗位作爲一個簡單的字符串(例如)

{ 
    "magic":{ 
       "real":true 
      }, 
    "options":{ 
       "happy":true, 
       "joy":true, 
       "joy2":true 
       }, 
    "key":"123" 
} 

預先感謝您

+1

這是一個教程:HTTP:// mobileorchard .com/tutorial-json-over-http-on-iphone/ – Josh 2010-12-16 02:33:04

回答

101

這裏的大風扇是我做的(請注意,JSON去我的服務器需要有一個值(另一個字典)關鍵= question..ie字典{ :問題=> {字典}}):

NSArray *objects = [NSArray arrayWithObjects:[[NSUserDefaults standardUserDefaults]valueForKey:@"StoreNickName"], 
    [[UIDevice currentDevice] uniqueIdentifier], [dict objectForKey:@"user_question"],  nil]; 
NSArray *keys = [NSArray arrayWithObjects:@"nick_name", @"UDID", @"user_question", nil]; 
NSDictionary *questionDict = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; 

NSDictionary *jsonDict = [NSDictionary dictionaryWithObject:questionDict forKey:@"question"]; 

NSString *jsonRequest = [jsonDict JSONRepresentation]; 

NSLog(@"jsonRequest is %@", jsonRequest); 

NSURL *url = [NSURL URLWithString:@"https://xxxxxxx.com/questions"]; 

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


NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding]; 

[request setHTTPMethod:@"POST"]; 
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
[request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; 
[request setHTTPBody: requestData]; 

NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 
if (connection) { 
receivedData = [[NSMutableData data] retain]; 
} 

的receivedData然後由處理:

NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSDictionary *jsonDict = [jsonString JSONValue]; 
NSDictionary *question = [jsonDict objectForKey:@"question"]; 

這不是100%的透明,並會採取一些重新讀,但一切都應該在這裏讓你開始。據我所知,這是異步的。進行這些調用時,我的用戶界面沒有被鎖定。希望有所幫助。

+0

一切看起來不錯,除了這行[dict objectForKey:@「user_question」],nil]; - dict沒有在你的示例中聲明。這只是一個簡單的字典或特別的東西? – 2010-12-19 00:01:23

+1

對不起。是的,「字典」只是一個簡單的字典,我從iOS用戶文檔加載。 – 2010-12-23 15:55:28

+17

這是使用'NSDictionary'實例方法'JSONRepresentation'。我可能會建議我使用'NSJSONSerialization'類方法'dataWithJSONObject',而不是[json-framework](https://github.com/stig/json-framework/)。 – Rob 2012-11-14 15:26:50

6

我會建議使用ASIHTTPRequest

ASIHTTPRequest是一個易於使用的 包裝圍繞CFNetwork的API,它 使得一些比較繁瑣的環節與Web服務器 容易溝通的 。這是寫在Objective-C 和在Mac OS X及iPhone應用程序 工作。

它適合執行基本HTTP 請求並與基於REST的服務(GET/POST/PUT /DELETE)進行交互。所包含的 ASIFormDataRequest子使得 容易使用的multipart/form-data的提交POST數據和文件 。


請注意,原作者停止這個項目。查看後續文章的原因和替代方案:http://allseeing-i.com/%5Brequest_release%5D;

個人我的AFNetworking

+0

@Almo,你沒看完整篇文章,是嗎? – vikingosegundo 2013-07-03 19:01:29

+0

杜,我沒有。抱歉。 – Almo 2013-07-03 19:04:05

2

下面是使用Restkit

一個偉大的文章它解釋上串行化嵌套的數據到JSON和數據附加到HTTP POST請求。

3

你們中的大多數人已經知道這一點,但我發佈這個,只是incase,你們中的一些人仍然在與iOS6 +的JSON掙扎。

在iOS6和更高版本中,我們有NSJSONSerialization Class,它非常快速,並且不依賴於包含「外部」庫。

NSDictionary *result = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; 

這是正路iOS6的,後來現在可以解析JSON efficiently.The使用SBJson的也是弧前實施,它也帶來了這些問題,如果你是在ARC環境中工作。

我希望這有助於!

0

這裏有一個更新的例子是使用NSURLConnection的+ sendAsynchronousRequest:(10.7以上版本,iOS 5以上)中,「郵報」的要求是一樣的,與接受的答案,這裏不再爲清楚起見:

NSURL *apiURL = [NSURL URLWithString: 
    [NSString stringWithFormat:@"http://www.myserver.com/api/api.php?request=%@", @"someRequest"]]; 
NSURLRequest *request = [NSURLRequest requestWithURL:apiURL]; // this is using GET, for POST examples see the other answers here on this page 
[NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue mainQueue] 
         completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
    if(data.length) { 
     NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     if(responseString && responseString.length) { 
      NSLog(@"%@", responseString); 
     } 
    } 
}]; 
+0

問題是關於POST – ahmad 2014-03-10 05:54:01

+2

不是,問題的第一部分是關於異步性,這裏沒有答案可以回答。爲downvote歡呼。 – auco 2014-03-10 09:19:47

6

我掙扎了一會兒。在服務器上運行PHP。此代碼將發佈JSON和從服務器獲取

NSURL *url = [NSURL URLWithString:@"http://example.co/index.php"]; 
NSMutableURLRequest *rq = [NSMutableURLRequest requestWithURL:url]; 
[rq setHTTPMethod:@"POST"]; 
NSString *post = [NSString stringWithFormat:@"command1=c1&command2=c2"]; 
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding]; 
[rq setHTTPBody:postData]; 
[rq setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 

[NSURLConnection sendAsynchronousRequest:rq queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
{ 
    if ([data length] > 0 && error == nil){ 
     NSError *parseError = nil; 
     NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
     NSLog(@"Server Response (we want to see a 200 return code) %@",response); 
     NSLog(@"dictionary %@",dictionary); 
    } 
    else if ([data length] == 0 && error == nil){ 
     NSLog(@"no data returned"); 
     //no data, but tried 
    } 
    else if (error != nil) 
    { 
     NSLog(@"there was a download error"); 
     //couldn't download 

    } 
}]; 
+1

content type =「application/x-www-form-urlencoded」做了訣竅。謝謝 – SamChen 2015-04-28 22:49:43

+0

很好的答案。在我的情況下,我使用了「application/json」 – 2017-06-12 10:32:25

2

json的答覆。由於我的編輯邁克·G的回答以現代化的代碼被拒絕,以3比2的

此修改旨在解決該帖子的作者並沒有將 作爲編輯的意義。它應該已被寫爲評論或 答案

我正在重新發布我的編輯作爲單獨的答案在這裏。正如Rob的評論中提到的那樣,這個編輯將刪除JSONRepresentation依賴關係NSJSONSerialization

NSArray *objects = [NSArray arrayWithObjects:[[NSUserDefaults standardUserDefaults]valueForKey:@"StoreNickName"], 
     [[UIDevice currentDevice] uniqueIdentifier], [dict objectForKey:@"user_question"],  nil]; 
    NSArray *keys = [NSArray arrayWithObjects:@"nick_name", @"UDID", @"user_question", nil]; 
    NSDictionary *questionDict = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; 

    NSDictionary *jsonDict = [NSDictionary dictionaryWithObject:questionDict forKey:@"question"]; 

    NSLog(@"jsonRequest is %@", jsonRequest); 

    NSURL *url = [NSURL URLWithString:@"https://xxxxxxx.com/questions"]; 

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


    NSData *requestData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; //TODO handle error 

    [request setHTTPMethod:@"POST"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
    [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; 
    [request setHTTPBody: requestData]; 

    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 
    if (connection) { 
    receivedData = [[NSMutableData data] retain]; 
    } 

的receivedData然後由處理:

NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
    NSDictionary *question = [jsonDict objectForKey:@"question"]; 
0

你可以嘗試發送JSON字符串此代碼

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:ARRAY_CONTAIN_JSON_STRING options:NSJSONWritin*emphasized text*gPrettyPrinted error:NULL]; 
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
NSString *WS_test = [NSString stringWithFormat:@"www.test.com?xyz.php&param=%@",jsonString]; 
相關問題