views:

1495

answers:

1

Hi, I know barely nothing about JSON and I need to send a request to a server and read the data coming from it, using the iPhone only.

I have tried to use the jason-framework to do that, but after readin the documentations I was not able to figure out how to construct the object and send it on the request. So I decided to adapted another code I saw here on SO.

The Object I need is this:

{ "code" : xxx }

Here I have a problem. This xxx is a NSData, so I suspect that I have to convert this data to a string, then use this string to build an object and send this on the request.

the server response is also a JSON object, in the form

{ "answer" : "yyy" } where yyy is a number between 10000 and 99999

this is the code I have so far.

- (NSString *)checkData:(NSData) theData {
    NSString *jsonObjectString = [self encode:(uint8_t *)theData length:theData.length];      
    NSString *completeString = [NSString stringWithFormat:@"http://www.server.com/check?myData=%@", jsonObjectString];                               
    NSURL *urlForValidation = [NSURL URLWithString:completeString];               
    NSMutableURLRequest *validationRequest = [[NSMutableURLRequest alloc] initWithURL:urlForValidation];                          
    [validationRequest setHTTPMethod:@"POST"];             
    NSData *responseData = [NSURLConnection sendSynchronousRequest:validationRequest returningResponse:nil error:nil];  
    [validationRequest release];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding: NSUTF8StringEncoding];
    NSInteger response = [responseString integerValue];
    NSLog(@"%@", responseString);
    [responseString release];
    return responseString;
}


- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length {
    static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    NSMutableData *data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t *output = (uint8_t *)data.mutableBytes;

    for (NSInteger i = 0; i < length; i += 3) {
        NSInteger value = 0;
        for (NSInteger j = i; j < (i + 3); j++) {
      value <<= 8;

      if (j < length) {
       value |= (0xFF & input[j]);
      }
     }

     NSInteger index = (i / 3) * 4;
     output[index + 0] = table[(value >> 18) & 0x3F];
     output[index + 1] =                    table[(value >> 12) & 0x3F];
     output[index + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
     output[index + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
    }

    ret

    urn [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
}

all this code gives me is errors. Or BAD URL or java exception.

What is wrong with this code?

If you guys prefer to give another solution using the json-framework please tell me how to encode the object using that pair ("code", "my NSData here converted to string")...

thanks for any help.

+2  A: 

JSON framework supports converting Arrays, Dictionaries, Strings, Numbers, and Booleans. So what you want to do is convert your data to one of these formats. Since your data is NSData easiest way is to convert it with:

NSString* stringData = [[NSString alloc] initWithData:yourData
                                             encoding:NSUTF8StringEncoding];

Depending on what's in the buffer (and if your server can handle it) you may want to Base64 encode the result (check http://www.cocoadev.com/index.pl?BaseSixtyFour if you don't have a converter handy). You could even go straight from NSData to a Base64-encoded string.

Now create a dictionary with one item with key code and value stringData (from last step):

NSDictionary* jsonDictionary = [NSDictionary dictionaryWithObject:stringData
                                                           forKey:@"code"];

This can be easily converted to JSON. Just import JSON.h in your code header, then use:

NSString* jsonString = [jsonDictionary JSONRepresentation];

Dump it out and you'll see your JSON string -- something like: { "code" : "{yourstringdata}"; }. Easiest way to send this over to your server is to use the ASIHTTPRequest library with a POST method.

Once you get the result back from the server the JSON framework can parse it back into a dictionary and then you can get out the data you need:

NSDictionary* responseDict = [yourJSONResponseStringFromServer JSONValue];
NSNumber* answerNum = (NSNumber *) [responseDict objectForKey:@"answer"];
int answer = [answerNum intValue];
Ramin
Thanks!!!!!! that's it! the ASIHTTPRequest library documentation is pretty incomplete and superficial (not your fault), but I managed to make it work using your instructions. Perfect! You are D man!
Digital Robot
Glad it worked for you. Don't give up on ASIHTTPRequest. It's pretty straightforward once you get the hang of it. Only thing is, don't forget to provide setDidFinishSelector/setDidFailSelector methods and set the delegate so you get notified when networking fails. Way too many cell dead-zones out there.
Ramin