毫无疑问,人们会对以下内容感到羞愧地摇头,但我将不胜感激。
我似乎在整个程序中使用几乎相同的结构对 NSURLSessionUploadTask
进行了相同的调用。因此,我试图使它成为一个我可以从程序中的任何地方调用的方法,并在它完成后,将 NSDictionary
返回给调用它的调用。
目前我有以下内容:
-(NSDictionary *)serverRequest:(NSString *)requestURL withDictionary:(NSDictionary *)sendDict {
NSURL *homeURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/%@",baseURL, requestURL]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setCachePolicy:NSURLCacheStorageAllowedInMemoryOnly];
NSData *sentData = [NSJSONSerialization dataWithJSONObject:sendDict options:0 error:nil];
NSURLSessionUploadTask *uploadTask = [_session uploadTaskWithRequest:request fromData:sentData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if ([returnedData[@"code"] isEqualToString:@"OK"])
{
dispatch_async(dispatch_get_main_queue(), ^{
return returnedData;
});
}
}];
[uploadTask resume];
}
所以我传入我想调用的 URL,然后将 NSDictionary 发送到服务器。服务器回复一个 JSON 响应,然后我将其转换为 returnedData。我只是希望将这些数据传回调用它的调用......类似于:
NSDictionary *mydata = @{@"email": userRegisterTextFieldEmailAddress.text};
NSDictionary *passedBackData = [self serverRequest:@"checkUserName" withDictionary:mydata];
当我尝试这个时,它不会构建,因为 dispatch_async
不是正确的格式等等。我已经尝试阅读这个,不敢相信这是一个难题?其他人每次想要从 Web 服务器返回一些数据时,肯定不会使用相同的代码进行相同的调用吗?
在此先感谢您为消除我的误解提供的任何帮助。
最佳答案
你通常做的是添加一个 completion
block 参数到您的方法,它指定您在收到响应后要执行的操作。因此,向您的方法添加一个 block 参数并添加调用该 block 的代码,例如:
- (void) serverRequest:(NSString *)requestURL withDictionary:(NSDictionary *)sendDict completion:(void (^)(id responseObject, NSError *error))completion
{
NSURL *homeURL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%@/%@", baseURL, requestURL]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setCachePolicy:NSURLCacheStorageAllowedInMemoryOnly];
NSData *sentData = [NSJSONSerialization dataWithJSONObject:sendDict options:0 error:nil];
NSURLSessionUploadTask *uploadTask = [_session uploadTaskWithRequest:request fromData:sentData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// report any network-related errors
if (!data) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, error);
});
}
return;
}
// report any errors parsing the JSON
NSError *parseError = nil;
returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (!returnedData) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, parseError);
});
}
return;
}
// if everything is ok, then just return the JSON object
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(returnedData, nil);
});
}
}];
[uploadTask resume];
}
然后您将其称为 serverRequest
方法,精确指定您想要对接收到的数据执行的操作:
[self serverRequest:url withDictionary:dictionary completion:^(id responseObject, NSError *error) {
if (responseObject) {
// do what you want with the response object here
} else {
NSLog(@"%s: serverRequest error: %@", __FUNCTION__, error);
}
}];
显然,您可以根据需要更改它,但希望这能说明这个想法。例如,如果您知道 responseObject
总是会是 NSDictionary
,然后我会更改对 id responseObject
的引用与 NSDictionary *responseObject
.
但我们的想法是,您应该只提供一个将响应数据和/或错误作为参数的 block 。这样,调用此方法的代码就可以指定异步网络请求完成时应该发生什么。
关于ios - NSURLSessionUploadTask 作为单独的方法,但将数据返回给调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21359418/