I'm trying to add Beeblex's new In App Purchase verification to my app, however i'm struggling passing a return value from within a block.
Here's the code I have now, and as you can see I set a BOOL value, then within the verification block I set the BOOL and return it at the end. However the return at the end is called before the block finishes, so what I need is to return the BOOL from within the block?
- (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;
}
If I simply put return = NO;
inside the block, I get compiler warnings of Incompatible block pointer types, and control may reach end of non-void block.
Best Answer
Beeblex developer here. The code inside -validateWithCompletionBlock: execute asynchronously (in the background, it needs to talk to our servers, so there's no point blocking your app completely while we wait for the Internet to do its thing).
Therefore, you need to rethink your approach to validating your receipts. Right now you, general workflow is:
But #3 returns right away, so this will never work. You should consider doing something like this:
Here's a quick-and-dirty example. I didn't compile it, so it probably has a few bugs, but it should give you the idea behind the intended usage pattern.