views:

53

answers:

2

Currently I am loading my supported products from a plist and after that I send a SKProductsRequest to guarantee that my SKProducts are still valid.

So I set up the request, start it and get the response in:

  • (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

Now, so far all functions correctly. Problem: From calling the request until receiving the response it may last several seconds. Until that my app is already loaded and the user may be able to choose and buy a product.

But because no products have been received, the available products are not in sync with the validated products -> unlikely, but possible error.

So my idea is to wait until the data is loaded and only continue when the list is validated. (Just a few seconds waiting...). I have a singleton instance managing all products.

 + (MyClass *) sharedInstance
{
   if (!sharedInstance)
       sharedInstance = [MyClass new];
// Now wait until we have our data
    [condition lock];
    while (noEntriesYet)   // is yes at begin
       [condition wait];
    [condition unlock];
    return sharedInstance;
}

- productsRequest: didReceiveResponse:
{
[condition lock];

// I have my data

noEntriesYet = false;
[condition signal];
[condition unlock];
}

Problem: The app freezes. Everything works fine if didReceiveResponse is completed before the sharedInstance is queried. There are different threads, the lock is working if wait is reached during didReceiveResponse, everything fine. But if not, didReceiveResponse is never called even if the request was sent. The lock is released, everything looks ok. I have tried to send the product request in a separate NSThread, with NSOperationQueue...without avail.

  • Why ? What is happening ?
  • How to solve the problem ?
A: 

I think you would block your GUI during products loading. In this case user can't be able to change anything. For ex: I use a transparent view + uiactivityindicator for blocking an app during working with the app store.

Yakov
As the GUI works on the main run loop, the cause of the freezing is now known. Unfortunately I need the didReceiveResponse and the message runs *too* on the main thread, so initializing the shared instance with another thread and blocking the GUI until I have received is more complex. I did not try to work it out after my solution
Thorsten S.
A: 

Ok, I have the problem so far:

The notifications are sent always in the main run loop, so the run loop may not be stopped. As the shared instance is initialized in the main run loop, there is no way to circumvent it.

What I finally did: I added a flag to my shared instance indicating if the product list has arrived yet. Before you try to purchase a product, you must ask if it is loaded, else an UIAlertView pops up and informs you that the product list is not validated yet and you should try it again a short time later.

That works; to guarantee that you only get valid products, the product information can only be acquired from the shared instance.

Thorsten S.