Posting JSON data to server

一曲冷凌霜 提交于 2019-12-08 13:57:47

I always use this method in my apps to perform API calls. This is the post method. It is asynchronous so you can specify a callback to be called when the server answer.

-(void)placePostRequestWithURL:(NSString *)action withData:(NSDictionary *)dataToSend withHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *error))ourBlock {
    NSString *urlString = [NSString stringWithFormat:@"%@", action];
    NSLog(@"%@", urlString);

    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    NSError *error;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataToSend options:0 error:&error];

    NSString *jsonString;
    if (! jsonData) {
        NSLog(@"Got an error: %@", error);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

        NSData *requestData = [NSData dataWithBytes:[jsonString UTF8String] length:[jsonString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

        [request setHTTPMethod:@"POST"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [request setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
        [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[requestData length]] forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody: requestData];

        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:ourBlock];
    }
}

You can easily call it:

- (void) login:(NSDictionary *)data
                    calledBy:(id)calledBy
                 withSuccess:(SEL)successCallback
                  andFailure:(SEL)failureCallback{
    [self placePostRequestWithURL:@"yourActionUrl"
                  withData:data
               withHandler:^(NSURLResponse *response, NSData *rawData, NSError *error) {
                   NSString *string = [[NSString alloc] initWithData:rawData
                                                            encoding:NSUTF8StringEncoding];

                   NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                   NSInteger code = [httpResponse statusCode];
                   NSLog(@"%ld", (long)code);

                   if (!(code >= 200 && code < 300)) {
                       NSLog(@"ERROR (%ld): %@", (long)code, string);
                       [calledBy performSelector:failureCallback withObject:string];
                   } else {
                       NSLog(@"OK");

                       NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:
                                               string, @"id",
                                               nil];
                       [calledBy performSelector:successCallback withObject:result];
                   }
               }];
}

And finally, you invocation:

NSDictionary *dataToSend = [NSDictionary dictionaryWithObjectsAndKeys:
_textFieldUserName.text, @"username", 
_textFieldPasssword.text, @"password", nil];

[self login:dataToSend 
    calledBy:self 
    withSuccess:@selector(loginDidEnd:) 
    andFailure:@selector(loginFailure:)];

Don't forget to define your callbacks:

- (void)loginDidEnd:(id)result{
    NSLog(@"loginDidEnd:");
    // Do your actions
}

- (void)loginFailure:(id)result{
    NSLog(@"loginFailure:");
    // Do your actions
}

First you create an NSString* that is supposed to contain JSON data. This doesn't work in general if the username and password contain any unusual characters. For example, I make sure that I have a quotation mark in my password to make sure that stupid software crashes.

You turn that string into an NSData* using ASCII encoding. So if my username contains any characters that are not in the ASCII character set, what you get is nonsense.

You then use the parser to turn this into a dictionary or array, but store the result into an NSData. Chances are that the parse fails and you get nil, otherwise you get an NSDictionary* or an NSArray*, but most definitely not an NSData*.

Here's how you do it properly: You create a dictionary, and then turn it into NSData.

NSDictionary* dict = @{ @"username": _textFieldUserName.text, 
                        @"password": _textFieldPasssword.text };
NSError* error; 
NSData* data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];

That's it.

try this:

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:@"My URL"];
        if (!request) NSLog(@"Error creating the URL Request");

        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:@"text/json" forHTTPHeaderField:@"Content-Type"];
        NSLog(@"will create connection");

        // Send a synchronous request
        NSURLResponse * response = nil;
        NSError * NSURLRequestError = nil;
        NSData * responseData = [NSURLConnection sendSynchronousRequest:request
                                              returningResponse:&response
                                               error:&NSURLRequestError];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!