Web 服务完成后的完成块? [英] Completion block after web service finishes?

查看:56
本文介绍了Web 服务完成后的完成块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在名为 WebServices 的类中实现了 RESTful API.我从应用程序中的其他类调用此类中的方法,并希望在成功完成 Web 服务后执行操作.我有一个完成块作为方法头的一部分,但不确定我是否正确使用它们,因为应用程序似乎从未到达方法调用的完成部分.这就是我调用我的方法的方式:

I have an implementation of a RESTful API in a class called WebServices. I call methods in this class from other classes within my app and would like to perform actions upon successful completion of a web service. I have a completion block as a part of my method headers, but am not sure if I am using them correctly as the app never seems to reach inside the completion part of the method call. This is how I am calling my method:

  [services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) {

        NSLog(@">>> COMPLETE! <<<");

        [self.loadingView removeFromSuperview];
    }];

我调用的方法如下所示:

And the method I am calling looks like this:

- (void)callUnregisterForPushNotifications:(NSString *)accessToken
                               pushToken:(NSString *)pushToken
                         completionBlock:(void (^)(NSMutableArray *resultsArray))completion{

    NSLog(@"UNREGISTER FOR PUSH CALLED!");

    NSLog(@"PUSH TOKEN %@", pushToken);

    NSString *appendUrl = @"alerts/unregisterpush/";

    NSLog(@"APPEND URL %@",appendUrl);

    NSURL *unregisterUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", BaseURLString, appendUrl]];
    NSLog(@"UNREGISTER URL: %@",unregisterUrl);

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:unregisterUrl
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:30.0];

    [request setHTTPMethod:@"PUT"];

    NSString *appendToken = [NSString stringWithFormat:@"Bearer %@", accessToken];
    NSLog(@"TOKEN: %@",appendToken);

    [request addValue:appendToken forHTTPHeaderField:@"Authorization"];
    [request addValue:@"application/json, text/plain, */*" forHTTPHeaderField:@"Accept"];
    [request addValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];


    NSString *postString = [NSString stringWithFormat:@"{\"Guid\":\"%@\"}",pushToken];
    NSLog(@"POST STRING: %@",postString);
    [request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

    NSLog(@"REQUEST %@",request);

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS RESPONSE: %@", response);
                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS ERROR: %@", error);
                                                              NSLog(@"UNREGISTER PUSH NOTIFICATIONS DATA: %@", data);

                               NSData *_data = data;// ... whatever
                               NSMutableString *_string = [NSMutableString stringWithString:@""];
                               for (int i = 0; i < _data.length; i++) {
                                   unsigned char _byte;
                                   [_data getBytes:&_byte range:NSMakeRange(i, 1)];
                                   if (_byte >= 32 && _byte < 127) {
                                       [_string appendFormat:@"%c", _byte];
                                   } else {
                                       [_string appendFormat:@"[%d]", _byte];
                                   }
                               }
                               NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string);

                               id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                               if (!obj) {
                                    //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error);

                               } else {
                                    //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj);

                                   //self.accessToken = [obj valueForKey:@"access_token"];
                                   //NSLog(@"ACCESS TOKEN: %@",self.accessToken);
                               }

                           }];
}

任何建议/意见将不胜感激,提前致谢!

Any advice / input would be appreciated, thanks in advance!

推荐答案

在 else 块中,您应该像这样调用完成处理程序:

In your else block you should call the completion handler like so:

// [code omitted for brevity]

                       NSLog(@"UNREGISTER PUSH RESPONSE: %@", _string);

                       id obj= [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                       if (!obj) {
                            //NSLog(@"REGISTER PUSH NOTIFICATIONS ERROR: %@", error);

                       } else {
                            completionHandler(resultsArray); // add this line to actually call the completion block passed in
                            //NSLog(@"REGISTER PUSH NOTIFICATIONS DATA: %@", obj);

                           //self.accessToken = [obj valueForKey:@"access_token"];
                           //NSLog(@"ACCESS TOKEN: %@",self.accessToken);
                       }


                   }];

还要确保传入实际数组而不是我传入的 resultsArray 参数.

Also make sure to pass in the actual array instead of the resultsArray parameter I passed.

您基本上要做的是传入一个不知道何时执行的函数(或块")(在任何异步任务完成后,您必须自己执行此操作).所以你从你的调用方法传入了块:

What you are basically doing is passing in a function (or "block") which does not know when to execute (you'll have to do that yourself after any asynchronous tasks have finished). So you passed in the block from your calling method:

[services callUnregisterForPushNotifications:savedAccessToken pushToken:savedPushToken completionBlock:^(NSMutableArray *resultsArray) {

        NSLog(@">>> COMPLETE! <<<");

        [self.loadingView removeFromSuperview];
    }];

包含在花括号中的代码块被传递给函数 callUnregisterForPushNotifications:pushToken:completionHandler: 并分配给 completionHandler 参数,该参数现在包含最初调用方法时传入的代码.接收 completionHandler 块的方法负责在异步任务(网络请求)完成后调用它(如您在我发布的第一个片段中所见).

The block of code contained in the curly braces is passed on to the function callUnregisterForPushNotifications:pushToken:completionHandler: and assigned to the completionHandler parameter which now contains the block of code you passed in when initially calling the method. The method that receives the completionHandler block is responsible for calling it once the asynchronous tasks (network requests) are finished (as you can see in the first snippet I posted).

completionHandler(resultsArray);

这样,一旦您的请求完成(else 块),您就可以执行传入的完成块.这实际上意味着执行我之前传入的代码块因为现在我们有了网络操作的数据."

That way, once your request has finished (the else block) you are ready to execute the completion block that was passed in. That will effectively mean "Execute the block of code I passed in earlier because now we have the data from the network operation."

这篇关于Web 服务完成后的完成块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆