Ich bin neu in Objective-C und fange seit kurzem an, große Anstrengungen in die Anfrage / Antwort zu investieren. Ich habe ein funktionierendes Beispiel, das eine URL (über http GET) aufrufen und den zurückgegebenen JSON analysieren kann.
Das Arbeitsbeispiel hierfür ist unten
- (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];
}
Meine erste Frage lautet: Wird sich dieser Ansatz vergrößern? Oder ist dies nicht asynchron (was bedeutet, dass ich den UI-Thread blockiere, während die App auf die Antwort wartet)?
Meine zweite Frage lautet: Wie kann ich den Anforderungsteil ändern, um einen POST anstelle von GET durchzuführen? Ist es einfach, die HttpMethod so zu ändern?
[request setHTTPMethod:@"POST"];
Und schließlich - wie füge ich diesem Beitrag eine Reihe von JSON-Daten als einfache Zeichenfolge hinzu (zum Beispiel)?
{
"magic":{
"real":true
},
"options":{
"happy":true,
"joy":true,
"joy2":true
},
"key":"123"
}
Danke im Voraus
iphone
objective-c
cocoa-touch
json
nsurlrequest
Toran Billups
quelle
quelle
Antworten:
Folgendes mache ich (bitte beachten Sie, dass der JSON, der zu meinem Server geht, ein Wörterbuch mit einem Wert (ein anderes Wörterbuch) für key = question..ie {: question => {dictionary}} sein muss):
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]; }
Die empfangenen Daten werden dann verarbeitet von:
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [jsonString JSONValue]; NSDictionary *question = [jsonDict objectForKey:@"question"];
Dies ist nicht 100% klar und erfordert ein erneutes Lesen, aber alles sollte hier sein, um Ihnen den Einstieg zu erleichtern. Und soweit ich das beurteilen kann, ist dies asynchron. Meine Benutzeroberfläche ist während dieser Anrufe nicht gesperrt. Hoffentlich hilft das.
quelle
NSDictionary
InstanzmethodeJSONRepresentation
. Ich könnte vorschlagen, dass ich dieNSJSONSerialization
KlassenmethodedataWithJSONObject
anstelle des json-Frameworks verwende .[[NSNumber numberWithUnsignedInt:requestData.length] stringValue]
.Ich hatte eine Weile damit zu kämpfen. Ausführen von PHP auf dem Server. Dieser Code sendet einen JSON und erhält die JSON-Antwort vom Server
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 } }];
quelle
Ich würde vorschlagen, ASIHTTPRequest zu verwenden
Bitte beachten Sie, dass der ursprüngliche Autor dieses Projekt eingestellt hat. Gründe und Alternativen finden Sie im folgenden Beitrag: http://allseeing-i.com/%5Brequest_release%5D ;
Persönlich bin ich ein großer Fan von AFNetworking
quelle
Die meisten von Ihnen wissen das bereits, aber ich poste dies, nur für den Fall, dass einige von Ihnen immer noch mit JSON in iOS6 + zu kämpfen haben.
In iOS6 und höher haben wir die NSJSONSerialization-Klasse , die schnell ist und nicht davon abhängt, "externe" Bibliotheken einzuschließen .
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
Auf diese Weise kann iOS6 und höher JSON jetzt effizient analysieren. Die Verwendung von SBJson ist auch eine Implementierung vor ARC und bringt diese Probleme auch mit sich, wenn Sie in einer ARC-Umgebung arbeiten.
Ich hoffe das hilft!
quelle
Hier ist ein großartiger Artikel mit Restkit
Es wird erläutert, wie verschachtelte Daten in JSON serialisiert und an eine HTTP-POST-Anforderung angehängt werden.
quelle
Da meine Bearbeitung von Mike Gs Antwort zur Modernisierung des Codes 3 zu 2 als abgelehnt wurde
Ich reposte meine Bearbeitung hier als separate Antwort. Diese Bearbeitung entfernt die
JSONRepresentation
Abhängigkeit mit,NSJSONSerialization
wie Robs Kommentar mit 15 positiven Stimmen nahe legt.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]; }
Die empfangenen Daten werden dann verarbeitet von:
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSDictionary *question = [jsonDict objectForKey:@"question"];
quelle
Hier ist ein aktualisiertes Beispiel, das NSURLConnection + sendAsynchronousRequest verwendet: (10.7+, iOS 5+). Die "Post" -Anforderung bleibt dieselbe wie bei der akzeptierten Antwort und wird hier aus Gründen der Klarheit weggelassen:
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); } } }];
quelle
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¶m=%@",jsonString];
quelle