2016-03-01 82 views
1

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

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

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

     [self.loadingView removeFromSuperview]; 
    }]; 

而且方法我打电话看起来像这样:

- (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); 
           } 

          }]; 
} 

任何意见/输入,将不胜感激,在此先感谢!

+0

哪部分没被调用?它不会执行“注销被触发!”块,还是不做“>>> COMPLETE!<<<”块,还是它不做? – Stonz2

+0

请注意,NSURLConnection已被弃用。您应该转而使用NSURLSession。 – Joride

回答

3

在你else块你应该调用完成处理,像这样:

// [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参数我传递来传递。

你基本上正在做的是传递一个函数(或“块”),它不知道何时执行(任何异步任务完成后你都必须自己做)。所以,你在该块通过从您的调用方法:

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

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

     [self.loadingView removeFromSuperview]; 
    }]; 

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

completionHandler(resultsArray); 

这样一来,一旦你的请求已经完成(在else块),你就可以执行中传递结束块。这将有效地意味着“执行我传入较早因为现在的代码块我们有来自网络运营的数据。“