Anonymous
Это как использовать Storekit2 [закрыто]
Сообщение
Anonymous » 16 фев 2025, 17:37
Я новичок в Storekit2. Это как использовать Storekit2? Я должным образом реализую покупки подписок.
Код: Выделить всё
import StoreKit
import AmplitudeSwift
class PurchaseManager: ObservableObject {
// A published property to hold available products
@Published var products: [Product] = []
// A published property to track the status of transactions
@Published var transactionState: String = "Idle"
// A set of product identifiers
private let productIdentifiers: Set = [
PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID,
PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_50_OFF,
PaymentHandler.sharedInstance.MONTHLY_PRODUCT_ID
]
// Shared instance to be used throughout the app
static let shared = PurchaseManager()
private init() {}
// MARK: - Fetch Products from App Store
func fetchProducts() async {
do {
let products = try await Product.products(for: productIdentifiers)
self.products = products
} catch {
print("Failed to fetch products: \(error.localizedDescription)")
}
}
// MARK: - Handle Purchase
func purchaseProduct(product: Product, source: String) async -> Bool {
do {
// Start the purchase
let result = try await product.purchase()
// Handle the result of the purchase
switch result {
case .success(let verificationResult):
switch verificationResult {
case .verified(let transaction):
self.transactionState = "Purchase Successful"
await transaction.finish()
return true
case .unverified(let transaction, let error):
self.transactionState = "Purchase Unverified: \(error.localizedDescription)"
await transaction.finish()
await showMessageWithTitle("Error!", "There was an error processing your purchase", .error)
return false
}
case .userCancelled:
self.transactionState = "User cancelled the purchase."
Amplitude.sharedInstance.track(
eventType: "payment_cancelled",
eventProperties: ["PlanId": product.id, "Source": source]
)
case .pending:
self.transactionState = "Purchase is pending."
await showMessageWithTitle("Error!", "There was an error processing your purchase", .error)
@unknown default:
self.transactionState = "Unknown purchase result."
await showMessageWithTitle("Error!", "There was an error processing your purchase", .error)
Amplitude.sharedInstance.track(
eventType: "payment_failed",
eventProperties: ["PlanId": product.id, "Source": source]
)
}
} catch {
self.transactionState = "Purchase failed: \(error.localizedDescription)"
await showMessageWithTitle("Error!", "There was an error processing your purchase", .error)
Amplitude.sharedInstance.track(
eventType: "payment_failed",
eventProperties: ["PlanId": product.id, "Source": source]
)
}
return false
}
// MARK: - Listen for Transaction Updates
func listenForTransactionUpdates() {
Task {
for await result in Transaction.updates {
switch result {
case .verified(let transaction):
self.transactionState = "Transaction verified: \(transaction.productID)"
await transaction.finish()
// Unlock the content associated with the transaction
case .unverified(let transaction, let error):
self.transactionState = "Unverified transaction: \(error.localizedDescription)"
await transaction.finish()
}
}
}
}
}
< /code>
Вот где я обрабатываю платеж < /p>
@MainActor func purchaseProduct(productId: String, plan: String, source: String, vc: UIViewController) async -> Bool {
self.loadingIndicator = ThreeBubblesLoadingView()
self.loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
vc.view.addSubview(self.loadingIndicator)
NSLayoutConstraint.activate([
self.loadingIndicator.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor),
self.loadingIndicator.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor)
])
DispatchQueue.main.async {
Amplitude.sharedInstance.track(
eventType: "payment_started",
eventProperties: ["Source": source]
)
}
Task {
await PurchaseManager.shared.fetchProducts()
let products = PurchaseManager.shared.products
if let selectProduct = products.first(where: { $0.id == productId }) {
let result = await PurchaseManager.shared.purchaseProduct(product: selectProduct, source: source)
if (result ) {
Amplitude.sharedInstance.track(
eventType: "payment_completed",
eventProperties: ["PlanId": productId, "Source": source]
)
self.loadingIndicator.removeFromSuperview()
return await self.purchase(
vc: vc,
productId: selectProduct.id,
product:selectProduct.id
)
}
}
return false
}
return false
}
< /code>
Я делаю что -то не так? Должен ли я называть покупку choundAseManager.shared.listenforransactionupdates () и где?
?
Подробнее здесь:
https://stackoverflow.com/questions/794 ... -storekit2
1739716622
Anonymous
Я новичок в Storekit2. Это как использовать Storekit2? Я должным образом реализую покупки подписок.[code]import StoreKit import AmplitudeSwift class PurchaseManager: ObservableObject { // A published property to hold available products @Published var products: [Product] = [] // A published property to track the status of transactions @Published var transactionState: String = "Idle" // A set of product identifiers private let productIdentifiers: Set = [ PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID, PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_50_OFF, PaymentHandler.sharedInstance.MONTHLY_PRODUCT_ID ] // Shared instance to be used throughout the app static let shared = PurchaseManager() private init() {} // MARK: - Fetch Products from App Store func fetchProducts() async { do { let products = try await Product.products(for: productIdentifiers) self.products = products } catch { print("Failed to fetch products: \(error.localizedDescription)") } } // MARK: - Handle Purchase func purchaseProduct(product: Product, source: String) async -> Bool { do { // Start the purchase let result = try await product.purchase() // Handle the result of the purchase switch result { case .success(let verificationResult): switch verificationResult { case .verified(let transaction): self.transactionState = "Purchase Successful" await transaction.finish() return true case .unverified(let transaction, let error): self.transactionState = "Purchase Unverified: \(error.localizedDescription)" await transaction.finish() await showMessageWithTitle("Error!", "There was an error processing your purchase", .error) return false } case .userCancelled: self.transactionState = "User cancelled the purchase." Amplitude.sharedInstance.track( eventType: "payment_cancelled", eventProperties: ["PlanId": product.id, "Source": source] ) case .pending: self.transactionState = "Purchase is pending." await showMessageWithTitle("Error!", "There was an error processing your purchase", .error) @unknown default: self.transactionState = "Unknown purchase result." await showMessageWithTitle("Error!", "There was an error processing your purchase", .error) Amplitude.sharedInstance.track( eventType: "payment_failed", eventProperties: ["PlanId": product.id, "Source": source] ) } } catch { self.transactionState = "Purchase failed: \(error.localizedDescription)" await showMessageWithTitle("Error!", "There was an error processing your purchase", .error) Amplitude.sharedInstance.track( eventType: "payment_failed", eventProperties: ["PlanId": product.id, "Source": source] ) } return false } // MARK: - Listen for Transaction Updates func listenForTransactionUpdates() { Task { for await result in Transaction.updates { switch result { case .verified(let transaction): self.transactionState = "Transaction verified: \(transaction.productID)" await transaction.finish() // Unlock the content associated with the transaction case .unverified(let transaction, let error): self.transactionState = "Unverified transaction: \(error.localizedDescription)" await transaction.finish() } } } } } < /code> Вот где я обрабатываю платеж < /p> @MainActor func purchaseProduct(productId: String, plan: String, source: String, vc: UIViewController) async -> Bool { self.loadingIndicator = ThreeBubblesLoadingView() self.loadingIndicator.translatesAutoresizingMaskIntoConstraints = false vc.view.addSubview(self.loadingIndicator) NSLayoutConstraint.activate([ self.loadingIndicator.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor), self.loadingIndicator.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor) ]) DispatchQueue.main.async { Amplitude.sharedInstance.track( eventType: "payment_started", eventProperties: ["Source": source] ) } Task { await PurchaseManager.shared.fetchProducts() let products = PurchaseManager.shared.products if let selectProduct = products.first(where: { $0.id == productId }) { let result = await PurchaseManager.shared.purchaseProduct(product: selectProduct, source: source) if (result ) { Amplitude.sharedInstance.track( eventType: "payment_completed", eventProperties: ["PlanId": productId, "Source": source] ) self.loadingIndicator.removeFromSuperview() return await self.purchase( vc: vc, productId: selectProduct.id, product:selectProduct.id ) } } return false } return false } < /code> Я делаю что -то не так? Должен ли я называть покупку choundAseManager.shared.listenforransactionupdates () [/code] и где? ? Подробнее здесь: [url]https://stackoverflow.com/questions/79443314/is-this-how-to-use-storekit2[/url]