方法BOOL从块内部返回

时间:2012-07-24 14:14:14

标签: objective-c ios xcode cocoa-touch objective-c-blocks

我正在尝试将Beeblex的新应用内购买验证添加到我的应用中,但是我很难在块内传递返回值。

这是我现在的代码,你可以看到我设置了一个BOOL值,然后在验证块中设置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;放在块中,我会得到不兼容块指针类型的编译器警告,并且控件可能会到达非空块的末尾。

2 个答案:

答案 0 :(得分:4)

Beeblex开发者在这里。 -validateWithCompletionBlock中的代码:异步执行(在后台,它需要与我们的服务器通信,因此在我们等待Internet执行其操作时,没有必要完全阻止您的应用程序。)

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

  1. 完成购买
  2. 致电Beeblex
  3. 等待回复
  4. 检查布尔值
  5. 但#3马上回来,所以这永远不会奏效。你应该考虑做这样的事情:

    1. 完成购买
    2. 显示“请稍候......”视图或类似内容,建议用户解锁他们购买的任何内容。
    3. 致电Beeblex
    4. 在块中,确定验证是否成功,然后用于解锁内容。
    5. 坐空闲直到阻止
    6. 这是一个快速而肮脏的例子。我没有编译它,所以它可能有一些错误,但它应该给你想法背后的想法。

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

答案 1 :(得分:3)

< 3 blocks

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