Can not set button states from within in-app purchase routines

When I first wrote my simple program using in-app purchase (I did not rewrite this app from C to Swift) when the user selects a purchase from the view controller this calls a simple purchase routine. If there are purchases it will update the state of the view controller's buyButton to allow a purchase. It also updates the productTitle and productDescription.

This used to work, but with the newer Xcode I am not allowed to change the state of the button from within the thread: "Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread."

How do I enable the button then? Is using dispatch_async the correct solution?

Below is the routine that is called from the paymentQueue:

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

    NSArray *products = response.products;

    NSLog(@"in productsRequest");

    myProduct = products;

    if (products.count != 0)

    {         _product = products[0];

//THIS IS WHAT IS CAUSING THE ISSUE *******         buyButton.enabled = YES;

        _productTitle.text = _product.localizedTitle;

        _productDescription.text = _product.localizedDescription;     }

    else{

        _productTitle.text = @"Product not found";     }

    products = response.invalidProductIdentifiers;

    for (SKProduct *product in products)     {         NSLog(@"Product not found: %@", product);     } }

Should I be doing something like this for the UI changes:

dispatch_async(dispatch_get_main_queue(), ^{

            self->buyButton.enabled = YES;

            self->_productTitle.text = self->_product.localizedTitle;

            self->_productDescription.text = self->_product.localizedDescription;

        });

Replies

Yes, you should dispatch to the main queue.