Search code examples
swiftswiftuistorekit

Implementation StoreKit 2 Swiftui


Hi in this view I have to load the purchases present on storekit, on the try await self.puchase(products) line I have the following error: alue of type 'SettingsForm' has no member 'purchase' how do I fix it and load the products on startup of the view?

Settings code:

import SwiftUI
import Foundation
import Backend
import StoreKit


@available(iOS 15.0, *)
@available(iOS 15.0, *)
struct SettingsForm : View {
    @State var selectedRegion: Int = 0
    @State var alwaysOriginalTitle: Bool = false
    @State
    private var products: [Product] = []
    @Environment(\.presentationMode) var presentationMode
    let productIds = ["premium"]

    private func loadProducts() async throws {
        self.products = try await Product.products(for: productIds)
        print(self.products)
    }
    
    var countries: [String] {
        
        get {
            var countries: [String] = []
            for code in NSLocale.isoCountryCodes {
                let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
                let name = NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id)!
                countries.append(name)
            }
            return countries
        }
    }
    
    func debugInfoView(title: String, info: String) -> some View {
        HStack {
            Text(title)
            Spacer()
            Text(info).font(.body).foregroundColor(.secondary)
        }
    }
    
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Abbonamenti"),
                        footer: Text(""),
                        content: {
                  
                    ForEach(self.products) { (products) in
                        Button {
                            Task {
                                do {
                                 try await self.purchase(products)
                                 } catch {
                                 print(error)
                                 }
                                
                            }
                        } label: {
                            Text("\(products.displayPrice) - \(products.displayName)")
                        }
                    }
                    
                })
                Section(header: Text("Region preferences"),
                        footer: Text("Region is used to display a more accurate movies list"),
                        content: {
                    Toggle(isOn: $alwaysOriginalTitle) {
                        Text("Always show original title")
                    }
                    Picker(selection: $selectedRegion,
                           label: Text("Region"),
                           content: {
                        ForEach(0 ..< self.countries.count) {
                            Text(self.countries[$0]).tag($0)
                        }
                    })
                })
                Section(header: Text("App data"), footer: Text("None of those action are working yet ;)"), content: {
                    Text("Export my data")
                    Text("Backup to iCloud")
                    Text("Restore from iCloud")
                    Text("Reset application data").foregroundColor(.red)
                })
                
                Section(header: Text("Debug info")) {
                    debugInfoView(title: "Movies in state",
                                  info: "\(store.state.moviesState.movies.count)")
                    debugInfoView(title: "Archived state size",
                                  info: "\(store.state.sizeOfArchivedState())")
                    
                }
            }
            .onAppear{
                if let index = NSLocale.isoCountryCodes.firstIndex(of: AppUserDefaults.region) {
                    self.selectedRegion = index
                }
                self.alwaysOriginalTitle = AppUserDefaults.alwaysOriginalTitle
            }
            .navigationBarItems(
                leading: Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }, label: {
                    Text("Cancel").foregroundColor(.red)
                }),
                trailing: Button(action: {
                    AppUserDefaults.region = NSLocale.isoCountryCodes[self.selectedRegion]
                    AppUserDefaults.alwaysOriginalTitle = self.alwaysOriginalTitle
                    self.presentationMode.wrappedValue.dismiss()
                }, label: {
                    
                    Text("Save")
                }))
            .navigationBarTitle(Text("Settings"))
        }
    }
}

#if DEBUG
struct SettingsForm_Previews : PreviewProvider {
    @available(iOS 14.0, *)
    static var previews: some View {
        if #available(iOS 15.0, *) {
            SettingsForm()
        } else {
            // Fallback on earlier versions
        }
    }
}
#endif

Solution

  • In StoreKit2, to purchase a Product, use…

    let purchaseResult = try await product.purchase()