方法BOOL从块内返回

我正在尝试将Beeblex的新应用内购买validation添加到我的应用,但是我正在努力从一个块内传递一个返回值。

这里是我现在的代码,正如你所看到的,我设置一个BOOL值,然后在validation块内设置BOOL,并在最后返回它。 不过最后的返回在块结束前被调用,所以我需要的是从块内返回BOOL?

- (BOOL)verifyTransaction:(SKPaymentTransaction *)transaction { if (![BBXIAPTransaction canValidateTransactions]) { return YES; // There is no connectivity to reach the server } BOOL __block toReturn = YES; BBXIAPTransaction *bbxTransaction = [[BBXIAPTransaction alloc] initWithTransaction:transaction]; bbxTransaction.useSandbox = YES; [bbxTransaction validateWithCompletionBlock:^(NSError *error) { if (bbxTransaction.transactionVerified) { if (bbxTransaction.transactionIsDuplicate) { // The transaction is valid, but duplicate - it has already been sent to Beeblex in the past. NSLog(@"Transaction is a duplicate!"); [FlurryAnalytics logEvent:@"Transaction duplicate!"]; toReturn = NO; } else { // The transaction has been successfully validated and is unique NSLog(@"Transaction valid data:%@",bbxTransaction.validatedTransactionData); [FlurryAnalytics logEvent:@"Transaction verified"]; toReturn = YES; } } else { // Check whether this is a validation error, or if something went wrong with Beeblex if (bbxTransaction.hasConfigurationError || bbxTransaction.hasServerError || bbxTransaction.hasClientError) { // The error was not caused by a problem with the data, but is most likely due to some transient networking issues NSLog(@"Transaction error caused by network, not data"); [FlurryAnalytics logEvent:@"Transaction network error"]; toReturn = YES; } else { // The transaction supplied to the validation service was not valid according to Apple NSLog(@"Transaction not valid according to Apple"); [FlurryAnalytics logEvent:@"Transaction invalid!!"]; toReturn = NO; } } }]; NSLog(@"toReturn: %@",toReturn ? @"Yes" : @"No"); return toReturn; } 

如果我简单地把return = NO; 在块内部,我得到不兼容的块指针types的编译器警告,并且控制可能会达到非空块的结束。

Beeblex开发者在这里。 -validateWithCompletionBlock内部的代码:在asynchronous执行(在后台,它需要与我们的服务器交谈,所以当我们等待互联网做它的事情时,没有任何一点阻止你的应用程序)。

因此,您需要重新考虑validation收据的方法。 现在你,一般工作stream程是:

  1. 完成购买
  2. 打电话给Beeblex
  3. 等待回应
  4. 检查布尔值

但#3立即返回,所以这将永远不会工作。 你应该考虑做这样的事情:

  1. 完成购买
  2. 显示“Please wait …”视图,或者类似的build议用户解锁他们购买的任何东西。
  3. 打电话给Beeblex
  4. 在块内部,确定validation是否成功, 然后从那里解锁内容。
  5. 坐着闲置,直到被街区叫喊

这是一个快速而肮脏的例子。 我没有编译它,所以它可能有一些错误,但它应该给你的想法背后的预期使用模式。

 - (void) showWaitView { // Display a wait view } - (void) hideWaitView { // Hide the wait view } - (void) completeValidationWithValidateReceiptData:(NSDictionary *) receipt isRecoverableError(BOOL) isRecoverableError { [self hideWaitView]; if (receipt) { // Unlock the content, tell the user } else { if (isRecoverableError) { // Probably a network error of some kind. Tell user they need to be connected, // and ask them to do it again. } else { // Keep the content locked, tell the user something went wrong } } } - (void) validateReceipt:(SKPaymentTransaction *) transaction { if (![BBXIAPTransaction canValidateTransactions]) { [self completeValidationWithValidateReceiptData:Nil isRecoverableError:YES]; return; } BBXIAPTransaction *bbxTransaction = [[BBXIAPTransaction alloc] initWithTransaction:transaction]; bbxTransaction.useSandbox = YES; [bbxTransaction validateWithCompletionBlock:^(NSError *error) { if (bbxTransaction.transactionVerified) { if (bbxTransaction.transactionIsDuplicate) { // The transaction is valid, but duplicate - it has already been sent to Beeblex in the past. [FlurryAnalytics logEvent:@"Transaction duplicate!"]; [self completeValidationWithValidateReceiptData:Nil isRecoverableError:NO]; } else { // The transaction has been successfully validated and is unique [FlurryAnalytics logEvent:@"Transaction verified"]; [self completeValidationWithValidateReceiptData:bbxTransaction.validatedTransactionData isRecoverableError:NO]; } } else { // Check whether this is a validation error, or if something went wrong with Beeblex if (bbxTransaction.hasConfigurationError || bbxTransaction.hasServerError || bbxTransaction.hasClientError) { // The error was not caused by a problem with the data, but is most likely due to some transient networking issues [FlurryAnalytics logEvent:@"Transaction network error"]; [self completeValidationWithValidateReceiptData:Nil isRecoverableError:YES]; } else { // The transaction supplied to the validation service was not valid according to Apple [FlurryAnalytics logEvent:@"Transaction invalid!!"]; [self completeValidationWithValidateReceiptData:Nil isRecoverableError:NO]; } } }]; } 

<3块

 - (void)verifyTransaction:(SKPaymentTransaction *)transaction completionHandler:(void (^)(BOOL flag))completionHandler { if (![BBXIAPTransaction canValidateTransactions]) { completionHandler(YES); // There is no connectivity to reach the server } BBXIAPTransaction *bbxTransaction = [[BBXIAPTransaction alloc] initWithTransaction:transaction]; bbxTransaction.useSandbox = YES; [bbxTransaction validateWithCompletionBlock:^(NSError *error) { if (bbxTransaction.transactionVerified) { if (bbxTransaction.transactionIsDuplicate) { // The transaction is valid, but duplicate - it has already been sent to Beeblex in the past. NSLog(@"Transaction is a duplicate!"); [FlurryAnalytics logEvent:@"Transaction duplicate!"]; completionHandler(NO); } else { // The transaction has been successfully validated and is unique NSLog(@"Transaction valid data:%@",bbxTransaction.validatedTransactionData); [FlurryAnalytics logEvent:@"Transaction verified"]; completionHandler(YES); } } else { // Check whether this is a validation error, or if something went wrong with Beeblex if (bbxTransaction.hasConfigurationError || bbxTransaction.hasServerError || bbxTransaction.hasClientError) { // The error was not caused by a problem with the data, but is most likely due to some transient networking issues NSLog(@"Transaction error caused by network, not data"); [FlurryAnalytics logEvent:@"Transaction network error"]; completionHandler(YES); } else { // The transaction supplied to the validation service was not valid according to Apple NSLog(@"Transaction not valid according to Apple"); [FlurryAnalytics logEvent:@"Transaction invalid!!"]; completionHandler(NO); } } }]; } 

然后使用

 [instance verifyTransaction:transaction completionHandler:^(BOOL flag) { if (flag) { // YOUR CODE HERE } }]; 

代替

 if ([instance verifyTransaction:transaction]) { // YOUR CODE HERE }