I'm trying to follow Apple tutorial on StoreKit 2 and for some reason I'm getting "Expression is 'async' but is not marked with await. insert 'await'". It works if I add await, however the method is not async and in Apple tutorial the await is not used.
The issue is this line (this works in Apple tutorial but not in my code):
let transaction = try self.checkVerified(result)
This works in my example (however checkVerified is not async):
let transaction = try await self.checkVerified(result)
Here is the code example:
import SpriteKit
import StoreKit
typealias Transaction = StoreKit.Transaction
class SceneMenu: SKScene {
private var storeProducts = [Product]()
private var updateListenerTask: Task<Void, Error>? = nil
override init(size: CGSize) {
super.init(size: size)
let btnBuy = SKLabelNode(text: "Buy Now")
btnBuy.name = "btn_buy"
btnBuy.fontSize = 20
btnBuy.fontColor = SKColor.blue
btnBuy.fontName = "Avenir"
btnBuy.position = CGPoint(x: size.width / 2, y: size.height / 2)
addChild(btnBuy)
updateListenerTask = listenForTransactions()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let action = atPoint(location)
if action.name == "btn_buy" {
print("btn_buy")
Task {
await requestProducts()
for product in storeProducts {
print(product.displayName)
}
await buy()
}
}
}
}
func requestProducts() async {
do {
let productIds = ["com.product.ticket-5", "com.product.ticket-10"]
storeProducts = try await Product.products(for: productIds)
} catch {
print("Failed product request: \(error)")
}
}
enum StoreError: Error {
case failedVerification
}
func purchase(_ product: Product) async throws -> Transaction? {
let result = try await product.purchase()
switch result {
case .success(let verification):
let transaction = try checkVerified(verification)
await transaction.finish()
return transaction
case .userCancelled, .pending:
return nil
default:
return nil
}
}
func buy() async {
let product = storeProducts[0]
do {
if try await purchase(product) != nil {
print("buying1")
}
} catch {
print("Failed purchase for \(product.displayName): \(error)")
}
}
deinit {
updateListenerTask?.cancel()
}
func listenForTransactions() -> Task<Void,Error> {
return Task.detached {
for await result in Transaction.updates {
do {
let transaction = try self.checkVerified(result)
print("buying2")
await transaction.finish()
} catch {
print("Transaction failed verification")
}
}
}
}
func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
switch result {
case .unverified:
throw StoreError.failedVerification
case .verified(let safe):
return safe
}
}
}