1

I am having difficulty in the logic for making a consumable purchase. Basically I am not sure how to proceed with this function:

private var item: Purchases.Package? {
    Items.shared.item
}
Purchases.shared.products(["com.item.id"]) { products in
    guard let item = products.first else { return }
    Purchases.shared.purchaseProduct(item) { transaction, purchaserInfo, error, cancelled in
    // enable some stuff in the app
    }
}
public class Items: ObservableObject {
    public static let shared = Items()
    
    @Published public var item: Purchases.Package?
    
    init() {
        Purchases.shared.products(["com.item.id"]) { products in
            self.item = products.first
        }
    }
}

If I try to initialise like above, it complains that it is a SKProduct?, and cannot be assigned to Purchases.Package?.

fankibiber
  • 729
  • 1
  • 6
  • 19

1 Answers1

3

It looks like you're fetching an Apple SKProduct and trying to assign it to a RevenueCat Package.

You can call the .purchase() method directly with the SKProduct.

// when your paywall is displayed (or earlier to preload)
var consumableProduct : SKProduct?
Purchases.shared.products(["com.item.id"]) { (products) in
    consumableProduct = products.first
}

// when the user taps the 'Buy' button
guard let product = consumableProduct else {
    return print("Error: No product exists")
}
Purchases.shared.purchaseProduct(product) { (transaction, purchaserInfo, error, userCancelled) in
    // handle purchase
}

Recommended Approach

It's recommended to use RevenueCat Offerings/Packages since you wouldn't need to hardcode specific product IDs (e.g. "com.item.id") in your app and you can update things remotely.

// Offerings are automatically pre-loaded by RevenueCat so
// this should read very quickly from cache
var offering : Purchases.Offering?
Purchases.shared.offerings { (offerings, error) in
    // Add any error handling here
    
    offering = offerings?.current
}

// when the user taps the 'Buy' button

// this assumes your paywall only has one item to purchase.
// you may have a dynamic tableview of items and use `indexPath.row` instead of `first`.
guard let package = offering?.availablePackages.first else {
    print("No available package")
    return
}
Purchases.shared.purchasePackage(package) { (trans, info, error, cancelled) in
    // handle purchase
}
enc_life
  • 4,973
  • 1
  • 15
  • 27
  • Thank you! I should have tried `SKProduct`... About the offerings, since this is a consumable, how would I integrate it to offerings? Instead of "Monthly", just do a "Custom" one? – fankibiber Oct 16 '20 at 17:15
  • For the _Packages_ you'll do custom identifiers. Offerings are always custom Ids. The setup really depends on your paywall, but maybe you add all of your consumable products as custom packages, and have one "consumable" Offering. – enc_life Oct 17 '20 at 17:29