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

标签 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 服务器返回一些数据时,肯定不会使用相同的代码进行相同的调用吗?

在此先感谢您为消除我的误解提供的任何帮助。

最佳答案

你通常做的是添加一个 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/

相关文章:

ios - UIRefreshControl 卡在最后一个拖动步骤

iphone - 如何将 AVAsset 旋转到纵向模式?

javascript - iOS、CocoonJS 和 Facebook 的严重问题

ios - 显示最近帖子的最佳方式 - Objective C

ios7 - AVAssetWriter 始终处于 AVAssetWriterStatusFailed 状态

html - 带进度条和音量控制的ios7 html5音频标签

ios - CGFloat Equatable 因相同值而失败

iphone - 在播放声音的同时录制音频

ios - 使用带回调的音频文件初始化将 MP3 转换为 AAC

iphone - 返回时弹出 ViewController 不会调用 viewWillAppear