毫无疑问,人们会在下面羞愧地摇头,但我很感激你的帮助。
我似乎在整个程序中对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服务器返回一些数据时,其他人肯定不会使用相同的代码进行相同的调用吗?
提前感谢您提供的任何帮助,以解决我的误解。
答案 0 :(得分:4)
您通常要做的是在方法中添加completion
块参数,该参数指定您在收到响应时要执行的操作。因此,在方法中添加一个块参数,并添加调用该块的代码,如:
- (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
的引用。
但是这个想法是你应该提供一个将响应数据和/或错误作为参数的块。这样,调用此方法的代码可以指定异步网络请求完成时应该发生的事情。
答案 1 :(得分:0)
所以这个电话是异步的,所以你不能那样做。我倾向于做的是等待方法自己返回然后获取主线程(就像你已经完成的那样),然后像这样更新UI /模型等。