NSURLSessionUploadTask作为单独的方法,但将数据返回给调用

时间:2014-01-26 03:46:34

标签: ios objective-c ios7 nsurlsession

毫无疑问,人们会在下面羞愧地摇头,但我很感激你的帮助。

我似乎在整个程序中对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服务器返回一些数据时,其他人肯定不会使用相同的代码进行相同的调用吗?

提前感谢您提供的任何帮助,以解决我的误解。

2 个答案:

答案 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 /模型等。