通过 POST 和 JSON 从 NSURLSession 取回数据

Getting data back from an NSURLSession via POST with JSON

由于 NSURLConnection 已弃用,我需要转到 NSURLSession。我有一个 URL 和一些我需要输入的数据 JSON。那么返回的结果应该是JSON。我看到的是这样的:

NSError *error;

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:@"[JSON SERVER"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:60.0];

[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];

[request setHTTPMethod:@"POST"];
NSDictionary *mapData = [[NSDictionary alloc] initWithObjectsAndKeys: @"TEST IOS", @"name",
                     @"IOS TYPE", @"typemap",
                     nil];
NSData *postData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
[request setHTTPBody:postData];


NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

}];

[postDataTask resume];

这是正确的方法吗?

我的要求是: 1.把我的键值对变成JSON。 2. 将 URL 和 JSON 传递给可重用函数。 3.获取返回的JSON数据。 4.解析返回的JSON数据

  1. 实例化 NSURLSessionNSMutableURLRequest 对象:

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setHTTPMethod:@"POST"];
    [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
    
  2. 把你的键值对变成JSON:

    // choose the right type for your value.
    NSDictionary *postDict = @{@"key1": value1, @"key2": value2};
    NSData *postData = [NSJSONSerialization dataWithJSONObject:postDict options:0 error:nil];
    
  3. 用 URL 和 JSON 让你的 POST:

    [request setURL:[NSURL URLWithString:@"JSON SERVER"];
    [request setHTTPBody:postData];
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
    }];
    [postDataTask resume];
    
  4. 解析返回的JSON数据上面的completionHandler中:

    if (!error) {                        
        NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    } else {
        // error code here
    }
    

    responseDict是解析后的数据。例如,如果服务器 returns

    {
        "message":"Your messsage",
        "data1":value1,
        "data2":value2
    }
    

    您可以使用

    轻松获取data1的值
     [responseDict objectForKey:@"data1"];
    

如果你想用不同的URL或JSON制作另一个POST,只需重复步骤2-4的流程即可。

希望我的回答对您有所帮助。

让您的方法的调用者提供一个完成处理程序来处理数据 returned 并更新 UI 以指示完成。

您可以复制SDK中找到的模式,如下:

- (void)makeRequest:(NSString *)param completion:(void (^)(NSDictionary *, NSError *))completion;

这样实现:

// in the same scope
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

- (void)makeRequest:(NSString *)param
         completion:(void (^)(NSDictionary *, NSError *))completion {

    // your OP code goes here, e.g.
    NSError *error;
    NSMutableURLRequest *request = // maybe the param is the url for this request
   // use the already initialized session
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request 
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        // call the completion handler in EVERY code path, so the caller is never left waiting
        if (!error) {
            // convert the NSData response to a dictionary
            NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
            if (error) {
                // there was a parse error...maybe log it here, too
                completion(nil, error);
            } else {
                // success!
                completion(dictionary, nil);
            }
        } else {
            // error from the session...maybe log it here, too
            completion(nil, error);
        }
    }];
    [postDataTask resume];
}

调用此方法的代码如下所示:

// update the UI here to say "I'm busy making a request"
// call your function, which you've given a completion handler
[self makeRequest:@"https://..." completion:^(NSDictionary *someResult, NSError *error) {
    // here, update the UI to say "Not busy anymore"
    if (!error) {
        // update the model, which should cause views that depend on the model to update
        // e.g. [self.someUITableView reloadData];
    } else {
        // handle the error
    }
}];

注意几件事:(1) return 类型是 void,调用者不希望从该方法中 returned 任何内容,并且在调用它时不进行赋值.数据“returned”作为参数提供给完成处理程序,稍后调用,在 asnych 请求完成后,(2) 完成处理程序的签名与调用方在完成块中声明的完全匹配^(NSDictionary *, NSError *),这只是一个建议,典型的网络请求。