0

I want to load product data of an IAP into the UI of my app(it will be shown in SwiftUI View, but the app, in general, is build using UIKit)

I have a function where I call the products function of the Purchases class. It returns a SKProduct. I added an extra safety layer using result builders. When it fails, I will show an error alert(I have never had it fail yet). This function is part of a class containing all interactions with the Purchases class:

    func retrieve(_ id: ProductID, completed: @escaping(Result<SKProduct, LCError>) -> Void) {
        Purchases.shared.products([id.rawValue]) { products in
            guard !products.isEmpty else {
                completed(.failure(.unableToRetrieveProduct))
                return
            }
            
            let skProduct = products[0]
            completed(.success(skProduct))
        }
    }

The ProductID is a custom enum containing all the product id's for easy access and preventing spelling mistakes.

I call that function in a small wrapper function in my ViewModel. I then switch on the result. The .failure case is not perfect, I should throw an error, but for now, it does the job. It never failed when I tested my app:

    func getTipItem(for id: ProductID, title: String ) -> TipItem {
        var price: NSDecimalNumber = 1.0
        var priceSymbol: String = ""
        PurchaseService().retrieve(id) {  result in
            switch result {
            case .success(let product):
                price = product.price
                priceSymbol = product.priceLocale.currencySymbol ?? "Err$"
            case .failure(let error):
                 price = 1.0
                priceSymbol = error.localizedDescription
            }
        }
        return TipItem(title: title, price: price, currencySymbol: priceSymbol)
    }

struct TipItem: View {
    let title: String
    let price: NSDecimalNumber
    let currencySymbol: String
    var body: some View {
        HStack {
            Text(title)
            Spacer()
            Text("\(currencySymbol)\(price)")
        }.foregroundColor(Color(.label))
    }
}

However, the problem is that when my view is loaded, no currency symbol is loaded, and the price is just 1(or 1.0000etc). I know that it's not falling back into the .faillure case because I have added a prefix to the default currency symbol, Err, to know when something is wrong.

Here are the debug logs:

2021-02-16 22:59:14.854771+0100 Learn Chemistry[10847:629632] [Purchases] - DEBUG: Requesting products with identifiers: {(
    "tip_small_099"
)}
2021-02-16 22:59:14.955628+0100 Learn Chemistry[10847:629814] [Purchases] - DEBUG: Products request finished
2021-02-16 22:59:14.955751+0100 Learn Chemistry[10847:629814] [Purchases] - DEBUG: Valid Products:
2021-02-16 22:59:14.955819+0100 Learn Chemistry[10847:629814] [Purchases] - DEBUG: tip_small_099 - <SKProduct: 0x2814ca160>
2021-02-16 22:59:14.955899+0100 Learn Chemistry[10847:629814] [Purchases] - DEBUG: Invalid Product Identifiers - (
)

This problem occurs only when the view is loaded the first time. When I go back to a previous screen, and back to the view where I show the products, it correctly shows it.

How can I make the correct data also show the first time the view is loaded? or is it a bug in the RC framework?

Thank you!

BSM

BSM
  • 87
  • 2
  • 12
  • The `priceLocale` you're accessing is on the SKProduct, so maybe there's some issue with your sandbox account? https://developer.apple.com/documentation/storekit/skproduct/1506145-pricelocale RevenueCat has a `localizedPriceString` helper but it can't change the data Apple sends back in the SKProduct: https://sdk.revenuecat.com/ios/Classes/RCPackage.html#/c:objc(cs)RCPackage(py)localizedPriceString – enc_life Feb 17 '21 at 16:02
  • maybe, but after reloading the view, it does show the correct price. So I don't know what goes wrong. I can buy test IAP's, so don't think its the sandbox account – BSM Feb 17 '21 at 16:12

0 Answers0