Reputation: 21
I implemented in-app Purchases and I am using SwiftyStoreKit. Everything works fine but want to check if the user has already purchased the product. I want when the user goes in the inappropriate page to show a button. If its bought then to shows "Open" if not "theprice". I can't quite understand how I can achieve that.
The viewDidLoad() :
let inAppPurchaseId = "iD"
let sharedSecret = "shared secret"
override func viewDidLoad() {
super.viewDidLoad()
SwiftyStoreKit.retrieveProductsInfo([inAppPurchaseId]) { result in
if let product = result.retrievedProducts.first {
let priceString = product.localizedPrice!
print("Product: \(product.localizedDescription), price: \(priceString)")
self.buyBtn.setTitle("Buy guides for "+"\(priceString)", for: .normal)
self.verifyPurchase(with: self.inAppPurchaseId, sharedSecret: self.sharedSecret)
}
else if let invalidProductId = result.invalidProductIDs.first {
print("Invalid product identifier: \(invalidProductId)")
}
else {
print("Error: \(String(describing: result.error))")
}
}
}
Here is the receipt verification and thee purchaseProduct function.
func purchaseProduct(with id: String) {
SwiftyStoreKit.retrieveProductsInfo([id]) { result in
if let product = result.retrievedProducts.first {
SwiftyStoreKit.purchaseProduct(product, quantity: 1, atomically: true) { result in
switch result {
case .success(let product):
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
self.buyBtn.setTitle("Open", for: .normal)
print("Purchase Success: \(product.productId)")
case .error(let error):
switch error.code {
case .unknown: print("Unknown error. Please contact support")
case .clientInvalid: print("Not allowed to make the payment")
case .paymentCancelled: break
case .paymentInvalid: print("The purchase identifier was invalid")
case .paymentNotAllowed: print("The device is not allowed to make the payment")
case .storeProductNotAvailable: print("The product is not available in the current storefront")
case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
default: print((error as NSError).localizedDescription)
}
}
}
}
}
}
func verifyPurchase(with id: String, sharedSecret: String) {
let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: sharedSecret)
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
switch result {
case .success(let receipt):
let productId = id
// Verify the purchase of Consumable or NonConsumable
let purchaseResult = SwiftyStoreKit.verifyPurchase(
productId: productId,
inReceipt: receipt)
switch purchaseResult {
case .purchased(let receiptItem):
print("\(productId) is purchased: \(receiptItem)")
case .notPurchased:
self.purchaseProduct(with: self.inAppPurchaseId)
print("The user has never purchased \(productId)")
}
case .error(let error):
print("Receipt verification failed: \(error)")
}
}
}
I want check when the view loads what title the button should have and if the product has been bought.
Upvotes: 2
Views: 2632
Reputation: 2386
You need to save that the product is purchased or not. Example UserDefaults (not encrypted) but you can use KeychainWrapper. Try with UserDefaults.standard.bool first instead of KeychainWrapper.
For the price/open Button use fullPurchase and change the title and logic.
You have 2 cases:
case .purchased(let receiptItem):
case .notPurchased:
var fullPurchase: Bool? { get { if let fullPurchasedFromKeychain = KeychainWrapper.standard.bool(forKey: FullAccessOlder) { return fullPurchasedFromKeychain } } return false } set { KeychainWrapper.standard.set(newValue!, forKey: FullAccessOlder) }
func verifyPurchase(with id: String, sharedSecret: String) {
let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: sharedSecret)
SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
switch result {
case .success(let receipt):
let productId = id
// Verify the purchase of Consumable or NonConsumable
let purchaseResult = SwiftyStoreKit.verifyPurchase(
productId: productId,
inReceipt: receipt)
switch purchaseResult {
case .purchased(let receiptItem):
print("\(productId) is purchased: \(receiptItem)")
self.fullPurchase = true
case .notPurchased:
self.purchaseProduct(with: self.inAppPurchaseId)
print("The user has never purchased \(productId)")
self.fullPurchase = false
}
case .error(let error):
print("Receipt verification failed: \(error)")
}
}
}
Information about consumable products is added to the receipt when they’re paid for and remains in the receipt until you finish the transaction. After you finish the transaction, this information is removed the next time the receipt is updated—for example, the next time the user makes a purchase.
Upvotes: 2