Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

517
Vistas
Mostrar estructura después del pago Suscripciones renovables automáticamente (SwiftUI)

Tengo un código para suscripciones con renovación automática, cómo cerrar la ventana de suscripción después de pagar la suscripción y mostrar la estructura ContentView().

 import Foundation import StoreKit typealias FetchCompletionHandler = (([SKProduct]) -> Void) typealias PurchaseCompletionHandler = ((SKPaymentTransaction?) -> Void) class Store: NSObject, ObservableObject { @Published var allRecipes = [Recipe]() private let allProductIdentifiers = Set([ "PRODUCT_ID_APP_STORE_CONNECT"]) private var completedPurchases = [String]() { didSet { DispatchQueue.main.async { [weak self] in guard let self = self else { return } for index in self.allRecipes.indices { self.allRecipes[index].isLocked = !self.completedPurchases.contains(self.allRecipes[index].id) } } } } private var productsRequest: SKProductsRequest? private var fetchedProducts = [SKProduct]() private var fetchCompletionHandler: FetchCompletionHandler? private var purchaseCompletionHandler: PurchaseCompletionHandler? private let userDefaultsKey = "PRODUCT_ID_APP_STORE_CONNECT" override init() { super.init() startObservingPaymentQueue() fetchProducts { products in self.allRecipes = products.map { Recipe(product: $0) } } } func loadStorePurchases() { if let storePurchases = UserDefaults.standard.object(forKey: userDefaultsKey) as? [String] { self.completedPurchases = storePurchases } } private func startObservingPaymentQueue() { SKPaymentQueue.default().add(self) } private func fetchProducts(_ completion: @escaping FetchCompletionHandler) { guard self.productsRequest == nil else { return } fetchCompletionHandler = completion productsRequest = SKProductsRequest(productIdentifiers: allProductIdentifiers) productsRequest?.delegate = self productsRequest?.start() } private func buy(_ product: SKProduct, completion: @escaping PurchaseCompletionHandler) { purchaseCompletionHandler = completion let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) } } extension Store { func product(for identifier: String) -> SKProduct? { return fetchedProducts.first(where: { $0.productIdentifier == identifier }) } func purchaseProduct(_ product: SKProduct) { startObservingPaymentQueue() buy(product) { _ in } } func restorePurchases() { SKPaymentQueue.default().restoreCompletedTransactions() } } extension Store: SKPaymentTransactionObserver { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { var shouldFinishTransaction = false switch transaction.transactionState { case .purchased, .restored: completedPurchases.append(transaction.payment.productIdentifier) shouldFinishTransaction = true case .failed: shouldFinishTransaction = true case .deferred, .purchasing: break @unknown default: break } if shouldFinishTransaction { SKPaymentQueue.default().finishTransaction(transaction) DispatchQueue.main.async { self.purchaseCompletionHandler?(transaction) self.purchaseCompletionHandler = nil } } } if !completedPurchases.isEmpty { UserDefaults.standard.setValue(completedPurchases, forKey: userDefaultsKey) } } } extension Store: SKProductsRequestDelegate { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { let loadedProducts = response.products let invalidProducts = response.invalidProductIdentifiers guard !loadedProducts.isEmpty else { print("Cloud not load the products!") if !invalidProducts.isEmpty { print("Invalid Products found: \(invalidProducts)") } productsRequest = nil return } // Cache the fetched products fetchedProducts = loadedProducts // Notifi anyone waiting on the product load DispatchQueue.main.async { self.fetchCompletionHandler?(loadedProducts) self.fetchCompletionHandler = nil self.productsRequest = nil } } }

estructura Receta()

 import Foundation import StoreKit struct Recipe: Hashable { let id: String let title: String let description: String var isLocked: Bool var price: String? let locale: Locale let imageName: String lazy var formatter: NumberFormatter = { let nf = NumberFormatter() nf.numberStyle = .currency nf.locale = locale return nf }() init(product: SKProduct, isLocked: Bool = true) { self.id = product.productIdentifier self.title = product.localizedTitle self.description = product.localizedDescription self.isLocked = isLocked self.locale = product.priceLocale self.imageName = product.productIdentifier if isLocked { self.price = formatter.string(from: product.price) } } }

esta es mi estructura con pantalla de suscripción y botón de suscripción

 import SwiftUI import Foundation import StoreKit struct Te: View { @ObservedObject var store = Store() var body: some View { ZStack { // After paying for the subscription, the subscription window disappears and the ContentViev() structure appears ContentView() VStack { ZStack(alignment: .center) { Image("subs") .resizable() .overlay(Color.black.opacity(0.6)) .frame(height: 600) .blur(radius: 15) .padding(.top) VStack { Text("ALL ACCESS") .font(.system(size: 32)) .fontWeight(.bold) .foregroundColor(.white) .multilineTextAlignment(.center) .padding(.bottom, 1) Text("UNLOCK ALL ACCESS") .foregroundColor(.white) .font(.system(size: 14)) .multilineTextAlignment(.center) .padding(.horizontal,35) VStack(alignment: .leading) { HStack { Image(systemName: "checkmark.seal") .resizable() .scaledToFit() .frame(width: 25, height: 25) .foregroundColor(.white) Text("Ads") .foregroundColor(.white) } HStack { Image(systemName: "checkmark.seal") .resizable() .scaledToFit() .frame(width: 25, height: 25) .foregroundColor(.white) Text("Item") .foregroundColor(.white) } HStack { Image(systemName: "checkmark.seal") .resizable() .scaledToFit() .frame(width: 25, height: 25) .foregroundColor(.white) Text("New") .foregroundColor(.white) } }.padding(.top, 50) Button(action: { store.purchaseProduct(store.product(for: "PRODUCT_ID_APP_STORE_CONNECT")!) }, label: { Text("SUBSCRIBE") .fontWeight(.bold) .padding() .padding(.horizontal,45) .background(Color.blue.opacity(0.5)) .foregroundColor(Color.white) .cornerRadius(10) }) .padding(.top,45) .padding(.bottom, 25) }.padding(.top,5) } } } } }

Después de pagar la suscripción, la ventana de suscripción debería desaparecer y la estructura ContentView () se mostrará en su lugar. Si conoce las suscripciones con renovación automática, mire mi código, tal vez cometí un error en alguna parte. Gracias por cualquier ayuda

over 4 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda