通过 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数据
实例化 NSURLSession
和 NSMutableURLRequest
对象:
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"];
把你的键值对变成JSON:
// choose the right type for your value.
NSDictionary *postDict = @{@"key1": value1, @"key2": value2};
NSData *postData = [NSJSONSerialization dataWithJSONObject:postDict options:0 error:nil];
用 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];
解析返回的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 *)
,这只是一个建议,典型的网络请求。
由于 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数据
实例化
NSURLSession
和NSMutableURLRequest
对象: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"];
把你的键值对变成JSON:
// choose the right type for your value. NSDictionary *postDict = @{@"key1": value1, @"key2": value2}; NSData *postData = [NSJSONSerialization dataWithJSONObject:postDict options:0 error:nil];
用 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];
解析返回的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 *)
,这只是一个建议,典型的网络请求。