There is a problem in the implementation of the LAInAppHelper
in the tutorial that you linked: the helper treats your application as non-concurrent.
Here is what is going on: the shared instance of LAInAppHelper
has a sharedInstance
, which owns _completionHandler
(among other things).
The requestProductsWithCompletionHandler:
method assigns _completionHandler
a copy of the block that has been passed in. This is OK for the first request, but if another request is "in flight", the completion block of that other request will be released by ARC due to this reassignment. If the tab to which you switch starts a concurrent request, the initial request will come back to a released block, causing an undefined behavior, and possibly a crash.
To fix this problem, you need to split the class in two - one part holding items common to all requests (namely, _productIdentifiers
and _purchasedProductIdentifiers
) and the request-specific ones (_productsRequest
and _completionHandler
).
The instance of the first class (let's call it LAInAppHelper
) remains shared; instances of the second class (let's call it LAInAppHelperRequest
) are created per-request inside the requestProductsWithCompletionHandler:
method.
-(id)initWithHelper:(LAInAppHelper*)helper
andCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
if (self = [super init]) {
_completionHandler = [completionHandler copy];
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:helper.productIdentifiers]; // You will need to make productIdentifiers a property
_productsRequest.delegate = self;
[_productsRequest start];
}
return self;
}
You will need to create a block that wraps the _completionHandler
, too, like this:
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
__block LAInAppHelperRequest *req = [[LAInAppHelperRequest alloc] initWithHelper:self andCompletionHandler:^(BOOL success, NSArray *products) {
completionHandler(success, products);
req = nil;
}];
}