benjaminmayo / merchantkit

A modern In-App Purchases management framework for iOS.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to send purchase details to commitPurchaseTask?

ramanocs1145 opened this issue · comments

Hi @benjaminmayo ,

I can't form Purchase instance need to send buying a product as you mentioned like below,

Kindly suggest me or give more details.

let task = merchant.commitPurchaseTask(for: purchase)
task.onCompletion = { result in 
    switch result {
        case .succeeded(_):
            print("purchase completed")
        case .failed(let error):
            print("\(error)")
    }
}

task.start()

Use the Merchant.availablePurchasesTask() to get a set of purchases. Then, to buy the product, you pass the Purchase to the Merchant.commitPurchaseTask(for: purchase). You can also refer to the example project to see how to use a ProductInterfaceController to achieve the same result, probably more elegantly than managing tasks individually.

Yes I have seen it. But I have custom UI so I need to use ProductInterfaceController?

If don't want to use ProductInterfaceController means then I must get available purchase from MerchantDelegate

func merchant(_ merchant: Merchant, didChangeStatesFor products: Set)?

case .product(let product):
                let state = self.productInterfaceController.state(for: product)
            
                switch state {
                    case .purchasable(let purchase):
                        self.productInterfaceController.commit(purchase)
                    default:
                        self.tableView.deselectRow(at: indexPath, animated: true)
                }

You don't have to use ProductInterfaceController but it will probably make your life easier. You can use its callbacks to fetch products and coordinate updates to the UI.

If you want to use task-based approach, you shouldn't be running UI from the MerchantDelegate. Just fetch products with the AvailablePurchasesTask, then get a purchase out of the onCompletion handler and send that purchase to a CommitPurchaseTask to start the buying process.

@benjaminmayo Kindly tell me, I'm in right way?

Because I can't get purchase out of the onCompletion handler.

fileprivate func buyAProduct() {

        print("availablePurchasesTask \(String(describing: self.merchant?.availablePurchasesTask()))")

        if let aAvailablePurchasesTask: AvailablePurchasesTask = self.merchant?.availablePurchasesTask() {

            print("availablePurchasesTask \(aAvailablePurchasesTask.products)")

            if let aMerchantTaskCompletion: MerchantTaskCompletion = aAvailablePurchasesTask.onCompletion {

                print("aMerchantTaskCompletion \(String(describing: aMerchantTaskCompletion))")

                  let task = self.merchant?.commitPurchaseTask(for: <#T##Purchase#>)
            }
        }
    }

You want something like this. You need to chain the results of the tasks. You don't have to do it in this tight loop; you could request available purchases at view load and make a commit task later when the user selects something to buy.

let product = Product(...) // the product you are interested in 
let task = merchant.availablePurchasesTask()
task.onCompletion = { result in
    switch result {
        case .success(let purchases):
            guard let purchase = purchases.purchase(for: product) else { return // handle this case }
            
            let task = merchant.commitPurchaseTask(for: purchase)
            task.onCompletion = { result in
                 // handle purchase result
            }
                    
           task.start()
       case .failure(let error):
           // handle error
    }
}
        
task.start()