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