PHP JSON in richtige Syntax für iOS bringen

  • PHP JSON in richtige Syntax für iOS bringen

    Hallo,

    ich kämpfe seit ein paar Tagen mit der korrekten Syntax und komme einfach nicht weiter.

    Ich habe ein korrektes PHP-Script mit dem mir eine Anlage in JSON korrekt "antwortet".

    PHP-Quellcode

    1. $webboxip = "XXX.XXX.XXX.XXX";
    2. $requestarray1 = array(
    3. 'version'=>"1.0",
    4. 'proc'=>"GetPlantOverview",
    5. 'id'=>"1",
    6. 'format'=>"JSON"
    7. );
    8. //Aufruf der Funktion REQUEST und übergabe der IP und dem JSON Request
    9. request($webboxip,$requestarray1);
    10. function request($webboxip,$requestarray) {
    11. //codieren in JSON
    12. $request = json_encode($requestarray);
    13. // Hier der JSON request
    14. $request = 'RPC='.rawurlencode($request);
    15. $ch=curl_init();
    16. curl_setopt($ch, CURLOPT_URL, "http://".$webboxip."/rpc");
    17. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    18. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    19. curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
    20. curl_setopt($ch, CURLOPT_HEADER , 0);
    21. curl_setopt($ch, CURLOPT_POST, 1 );
    22. curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
    23. // Hier das Ergebnis
    24. $response = curl_exec ($ch);
    25. if (curl_errno($ch)) {
    26. $err=1;
    27. $errtext = curl_error($ch);
    28. }
    29. curl_close($ch);
    30. //Decodieren der Antwort
    31. $response = json_decode($response);
    32. // Auffruf der Funktion OUTPUT
    33. output($response);
    34. }
    Alles anzeigen


    Wie bekomme ich exakt die selbe Abfrage in Objective-C hin?

    Ich hab schon alles mögliche Probiert über das JSON-Framework, über die NSJSON Klassen ... ich bekomme immer einen Json-Fehler vom Server zurück.

    Hat einer eine Idee?

    Danke & Viele Grüße,
    Lena
  • Ok hier mal Versuch 1

    Quellcode

    1. //Version 1
    2. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://xxx.xxx.xxx.xxx/rpc"]];
    3. [request setHTTPMethod:@"POST"];
    4. NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];
    5. [jsonDict setValue:@"1.0" forKey:@"version"];
    6. [jsonDict setValue:@"GetPlantOverview" forKey:@"proc"];
    7. [jsonDict setValue:@"1" forKey:@"id"];
    8. [jsonDict setValue:@"JSON" forKey:@"format"];
    9. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:kNilOptions error:nil];
    10. NSString* jsonString2 = [jsonDict JSONRepresentation];
    11. [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    12. [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    13. [request setValue:@"json" forHTTPHeaderField:@"Data-Type"];
    14. [request setValue:[NSString stringWithFormat:@"%d", [jsonData length]] forHTTPHeaderField:@"Content-Length"];
    15. [request setHTTPBody: jsonData];
    16. [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:true];
    Alles anzeigen



    Und mal Version2 in der ich versucht habe den String direkt zu übergeben:

    Quellcode

    1. // Version 2
    2. NSString *post = @"RPC={"version":"1.0","proc":"GetPlantOverview","id":"1","format":"JSON"}";
    3. NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    4. NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
    5. NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
    6. [request setURL:[NSURL URLWithString:@"http://xxx.xxx.xxx.xxx/rpc?"]];
    7. [request setHTTPMethod:@"POST"];
    8. [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    9. [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    10. [request setHTTPBody:postData];
    11. [[NSURLConnection alloc] initWithRequest:request delegate:self];
    12. self.responseData = [NSMutableData data];
    Alles anzeigen


    Und Version 3

    Quellcode

    1. NSDictionary *dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"1.0", @"version", @"GetPlantOverview", @"proc", @"1", @"id", @"JSON", @"format", nil];
    2. NSString *JSON = [dict2 JSONString];
    3. NSLog(@"JSON: %@",JSON);
    4. [dict2 JSONRepresentation];
    5. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://xxx.xxx.xxx.xxx/rpc"]];
    6. [request setHTTPMethod: @"POST"];
    7. [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    8. [request setValue:@"text/xml charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    9. [request setHTTPBody: [JSON dataUsingEncoding:NSUTF8StringEncoding]];
    10. NSHTTPURLResponse * response = nil;
    11. NSError *theError;
    12. NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &theError ];
    13. NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
    14. NSDictionary *dict = [returnString JSONValue];
    Alles anzeigen
  • hab deinen code nicht komplett gelesen aber lass dir doch mal vom php-script das rawurlencode(json_encode($requestarray)) ausgeben. die ausgabe fügst du dann in deinen obj-c code ein (hardcoden). wenn das funktioniert weißt du schonmal woran es liegt und kannst schaun wie du mit obj-c an genau die gleiche form der daten kommst.
  • Danke für den Code, Lena!

    Bei Version 1)

    Du hast die JSON Daten nicht am rpc=... Query angehängt. Eventuell die Ursache.
    Ausserdem hoffe ich sehr, dass du die Objekte danach sauber freigibst.

    Bei Version 2)

    gcc müsste den Code gar nicht kompilieren können. Der String mit dem Variablenamen "post" lässt sich nicht so konstruieren.

    Bei Version 3)

    Wieder anders aufgebaut ...

    Es scheint dir nicht klar zu sein, was genau du machen musst, damit du an valides Response vom Server kommst.

    Ich schlage dir vor:

    Leg dir ein neues leeres Command-Line Projekt an, schreib ein simples PHP Skript und leg es auf deinem lokalen Webserver ab
    und mache Experimente damit. Fange mit NSJSONSerializer an. Auf dem PHP-Skrpt kannst du die $_POST ausgeben lassen.
    Aus macfreakz wurde Apfelbeisser …
  • @gritsch: Danke das habe ich auch schon versucht, da kommt leider auch ein JSON Fehler

    @apfelbeisser:
    Du hast das Problem erkannt, mir ist es in Objective-C echt nicht klar, was ich machen muss ;-)
    Die Syntax bringt mich noch mal um ;-)

    Die Anlage scheint nur ein korrektes Object zurück zu geben, wenn ich sie über PHP abfrage. Da funktioniert alles wunderbar.

    Wie baust du eine Json-Abfrage auf?
    Hast du ein Snippet für mich?
  • Mit Bordmitteln von Apple schnell geschrieben:

    Quellcode

    1. // create dictionary
    2. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    3. [dict setValue:@"proc" forKey:@"..."];
    4. ...
    5. // convert to json data
    6. NSError *error = nil;
    7. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
    8. if (!jsonData)
    9. {
    10. NSLog(@"error: %@", [error localizedDescription]);
    11. return 1;
    12. }
    13. // 3) get json representation in string
    14. NSString *jsonAsString = [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
    15. NSLog(@"Json representation: %@", jsonAsString);
    Alles anzeigen


    Dann kannst du diesen JSON String am "rpc=" hängen und dem Request geben. (so wie du im PHP Skript
    gemacht hast, ... hast du bei Obj-C bei Version 1) und Version 3) aber gar nicht gemacht. )

    Aber wie gesagt:

    Dieses Beispiel wird dir nichts bringen, wenn du nicht genau weisst, was die Zeilen machen.
    Daher back to roots: Lies was einführendes wie z.B. wie man mit NSString arbeitet, und und und ... falls du kein
    Buch zum ObjC hast, dann sofort kaufen, wenn du ernsthaft Obj-c programmieren willst. Fange nicht gleich an
    ein iOS Projekt zu starten, sondern mit simplen Command-Line Anwendungen. So gibst du das Fokus
    auf das wesentliche Problem.
    Aus macfreakz wurde Apfelbeisser …
  • Aber ist das im Prinzip nicht dass, was ich in Version1 probiert habe?

    Ich hab mal versucht es in mein Projekt ein zu bauen.

    Jetzt bekomme ich allerdings nicht mal mehr einen JSON-Fehler zurück :-(

    Quellcode

    1. // create dictionary
    2. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    3. [dict setValue:@"1.0" forKey:@"version"];
    4. [dict setValue:@"GetPlantOverview" forKey:@"proc"];
    5. [dict setValue:@"1" forKey:@"id"];
    6. [dict setValue:@"JSON" forKey:@"format"];
    7. // convert to json data
    8. NSError *error = nil;
    9. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
    10. if (!jsonData)
    11. {
    12. NSLog(@"error: %@", [error localizedDescription]);
    13. // return 1;
    14. }
    15. // 3) get json representation in string
    16. NSString *jsonAsString = [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
    17. NSLog(@"Json representation: %@", jsonAsString);
    18. NSString *test = [NSString stringWithFormat:@"http://xxx.xxx.xxx.xxx/rpc?RPC=%@",jsonAsString];
    19. NSLog(@"TEST: %@", test);
    20. // self.responseData = [NSMutableData data];
    21. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:test]];
    22. // [[NSURLConnection alloc] initWithRequest:request delegate:self];
    23. NSHTTPURLResponse * response = nil;
    24. NSError *theError;
    25. NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &theError ];
    26. NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
    27. NSLog(@"Return String:%@", returnString);
    Alles anzeigen
  • Jetzt machst du plötzlich einen GET Request. Warum denn?

    Ich wiederhole mich: dir ist einfach zu viel nicht klar und daher fange besser nicht mit solchen Herausfoerderungen an, sondern mit Grundlagen, die dich wirklich nach vorne bringen.
    Aus macfreakz wurde Apfelbeisser …
  • Na ja ich suche mir halt die Schnipselchen zusammen ...

    Learning by Doing ... ich bin nicht der Typ für reine Theorie ... und es ist auch nicht so, dass das ein Monsterprojekt werden soll...

    Im Prinzip ist die Abfrage schon alles was ich erreichen will.
    Kannst du mir sagen, was ich nun falsch gemacht habe?
  • Du schickst ja einen GET Request an den Server. Im PHP-Skript machst du aber einen POST Request.

    Damit du einen POST Request machst, sollte die Methode auf POST gesetzt sein und dein JSON im HTTP Body liegen statt im URL (wie du in der Version 1+2+3 gemacht hast)

    Quellcode

    1. [request setHTTPMethod:@"POST"];
    2. [request setHTTPBody:deinJSONHier]; // hier rpc={blah:foobar}...
    Aus macfreakz wurde Apfelbeisser …
  • Siehst du Syntax und ich stehen auf Kriegsfuß ;-)

    Ich habs mal so probiert. Allerdings war ich so weit schon mal ... ich denke, dass ich den String in den HttpBody bringen müsste, aber da bekomm ich einen Fehler.

    Und wenn ich das so ausführe bekomme ich wieder nen JSON-Fehler

    Quellcode

    1. // create dictionary
    2. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    3. [dict setValue:@"1.0" forKey:@"version"];
    4. [dict setValue:@"GetPlantOverview" forKey:@"proc"];
    5. [dict setValue:@"1" forKey:@"id"];
    6. [dict setValue:@"JSON" forKey:@"format"];
    7. // convert to json data
    8. NSError *error = nil;
    9. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
    10. if (!jsonData)
    11. {
    12. NSLog(@"error: %@", [error localizedDescription]);
    13. // return 1;
    14. }
    15. // 3) get json representation in string
    16. NSString *jsonAsString = [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
    17. NSLog(@"Json representation: %@", jsonAsString);
    18. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://xxx.xxx.xxx.xxx/rpc="]];
    19. [request setHTTPMethod:@"POST"];
    20. [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    21. [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    22. [request setValue:@"json" forHTTPHeaderField:@"Data-Type"];
    23. [request setValue:[NSString stringWithFormat:@"%d", [jsonData length]] forHTTPHeaderField:@"Content-Length"];
    24. [request setHTTPBody: jsonData];
    25. [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:true];
    26. self.responseData = [NSMutableData data];
    Alles anzeigen
  • @wolf_10de

    Quellcode

    1. 2012-08-21 15:00:07.425 json_demo1[3886:c07] -JSONValue failed. Error trace is: (
    2. "Error Domain=org.brautaset.JSON.ErrorDomain Code=3 \"Unrecognised leading character\" UserInfo=0x6c4d2b0 {NSLocalizedDescription=Unrecognised leading character}"
    3. )


    @Apfelbeisser

    ??? ich versteh nicht was du meinst, wie muss ich das dann mitgeben?