SKProductsRequest not working in iOS 11 Simulators
Asked Answered
F

3

10

Purchasing in an iOS simulator is a well known "no, it's not possible". However, retrieving SKProduct information by providing product identifiers to a SKProductsRequest used to work before iOS 11.

In the SKProductsRequestDelegate I'm getting the following error: Error Domain=SSErrorDomain Code=0 "Cannot connect to iTunes Store" From what I found out, this can happen either when the product identifiers are wrong, or the Apple Sandbox servers are down. However this is not the case since products are loaded fine on iOS 10..

My implementation of product fetching is pretty much the same as in the Apple guides

Is anyone else experiencing this or found a solution?

The products are loading fine when the app is running on a physical device. I'm using Xcode 9.0.

Filet answered 19/9, 2017 at 14:51 Comment(0)
A
5

Same here. If you repeat the request when it fails, just try again. After the umpteenth repetition it will finally return the products. It may take 10, 50 or even more than 100 repetitions.

So this is how my code looks now:

- (void)inquireProducts {
    _availableProducts = [NSMutableArray arrayWithCapacity:0];
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"productIds" withExtension:@"plist"];
    knownProductIdentifiers = [NSArray arrayWithContentsOfURL:url];
    if (knownProductIdentifiers && knownProductIdentifiers.count) {
        // Keep a strong reference to the product request
        productsRequest = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithArray:knownProductIdentifiers]];
        productsRequest.delegate = self;
        [productsRequest start];
    }
}

#pragma mark SKProductsRequestDelegate method

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    for (SKProduct *product in response.products) {
        [_availableProducts addObject:product];
    }
    productsRequest = nil;
    [[NSNotificationCenter defaultCenter] postNotificationName:IAPPurchaseNotification object:self];
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    if (request == productsRequest) {
        static int count = 0;
        NSLog(@"Request %@ failed on %d. attempt with error: %@", request, ++count, error);
        productsRequest = nil;
        // try again until we succeed
        [self inquireProducts];
    }
}
Ascomycete answered 24/9, 2017 at 11:6 Comment(5)
Thanks for the suggestion @vilmoskörte! That could be a way around it, although in case of an actual problem I believe we would endlessly retry. But for debug it's a good a idea. I've sent a DTS to Apple yesterday and got a response quite fast, telling me that it looks like a bug (at least they didn't say since iOS 11 you're not supposed to fetch products in simulators) So I sent them Bug Report. Let's hope they will fix this soon. :)Filet
Yes, it will endlessly retry. To prevent this, one could of course use the counter to set a limit by inserting something like if (count == 200) return; into the last method.Andromada
Running into this same issue. Seems to work unrelated to number of requests. Just seems to not work in general. This is causing all of my unit tests for my subscriptions to fail. Not fun. Anyone get any feedback on whether this is being worked on?Isopleth
Confirmed with an Apple Engineer that this is a problem they are looking at. Good news is they are looking at it, hopefully to fix. Bad news, they say it isn't/wasn't supposed to work in the simulator and just be happy it worked at all before. So... yeah.Isopleth
My experience is that after a few and sometimes also after very many repetitions of the request finally productsRequest:request didReceiveResponse: will be invoked.Andromada
M
0

It's an apple issue. I also had similar problem. After trying a lot, i recall the product request method for 10 times and i got response in second try. It works on iOS 9 and 11 only. Not for iOS 10. And once you get your products, you will surly get it in first time later. It works on both device and simulator. My implementation is like :

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{

 int tried=(int)[[NSUserDefaults standardUserDefaults] integerForKey:@"try"];
[[NSUserDefaults standardUserDefaults] setInteger:tried+1 forKey:@"try"];
[[NSUserDefaults standardUserDefaults] synchronize];

if([[GameState shared].availableInApps count]==0&&(int)[[NSUserDefaults standardUserDefaults] integerForKey:@"try"]>10)
{
    [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(retry_product) userInfo:nil repeats:NO];
}
Milesmilesian answered 5/11, 2017 at 6:20 Comment(0)
V
0

Similar question and this answer helped me: https://mcmap.net/q/322054/-requesting-an-in-app-purchase-in-ios-13-fails

BTW: testing with real device solved the problem completely

Ventricle answered 14/5, 2021 at 9:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.