I am working on some IAPs using this tutorial.
Firstly I fetch the products with this:
-(void)fetchAvailableProductsFirstLoad:(BOOL)firstTimeLoading {
[[IAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) { ...
The helper runs the following:
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
@synchronized(self) {
// 1
_completionHandler = [completionHandler copy];
// 2
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
}
When the products are returned or failed the following is called:
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
NSLog(@"Error: %@",error);
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
Issue
The issue we have is when the user starts a fetch or products twice. For example the fetch products is called on the viewDidLoad, but if the user has a bad/slow connection and navigates away and then back to the controller. The initial fetch is not cancelled therefore there are two running.
I believe the issue is when the second is returned and the pointer has changed/does not exist/corrupt.
The EXC_BAD_ACCESS code 2 error occurs on the relevant line:
_completionHandler(YES, skProducts);
OR
_completionHandler(NO, nil);
-(void)cancelProductRequest { [_productsRequest cancel]; _productsRequest = nil; }
which cancels the current request if they navigate away from that controller to save there ever being multiple requests. – Soundless