Different way to write IAP buttons

I would like some advice on how i can write better code to load and present the in app purchases in my app. Currently I am presenting in app purchases like so

                Button(action: {
                    let _ = IAPManager.shared.purchase(product: self.products.items[0]);
                    if UserDefaults.standard.bool(forKey: "seOn") == true {self.soundEffectsM.playSound(sound: "ShotGun", type: "wav")}
                }) {
                    ZStack {
                    VStack {
                    Text("Shotgun")
                    Text("Double Points")
                        .font(Font.system(size: 15, design: .monospaced))
                    }.shadow(color: Color.black, radius: 0, y: 1)
                            .shadow(color: Color.gray, radius: 0, y: 1)
                            .shadow(radius: 10)
                            .frame(minWidth: 0, maxWidth: .infinity)
                            .foregroundColor(.yellow)
                            .padding(.all, 5)
                            .font(Font.system(size: 25, design: .monospaced))
                            .background(Color.black.opacity(0.5))
                            .background(LinearGradient(gradient: Gradient(colors: [Color.black, Color.green, Color.black]), startPoint: .topLeading, endPoint: .bottomTrailing))
                            .clipShape(Capsule())
                    Image(systemName: "checkmark.circle")
                        .resizable()
                        .renderingMode(.template)
                        .frame(width: 50, height: 50)
                        .foregroundColor(.green)
                        .opacity(UserDefaults.standard.bool(forKey: "shotgunPurchased") ? 1 : 0)
                }
                }.shadow(color: Color.black, radius: 0, y: 3).shadow(color: Color.gray, radius: 0, y: 1)
                .shadow(color: (Color.black).opacity(0.6), radius: 5, x: 5, y: 5)
                .padding([.leading, .trailing], 55)
                .padding(2)
                .allowsHitTesting(UserDefaults.standard.bool(forKey: "shotgunPurchased") == false)

This is so I can customise the button like remove hit testing and add a tick to it when that item is purchased. So far works fine when calling to Storekit file but i get fatal error ‘index out of range’ when trying to connect to app store. So i have written it another way so it will successfully load from the app store

ForEach((0 ..< self.products.items.count), id: \.self) { column in
                    Button(action: {
                        let _ = IAPManager.shared.purchase(product: self.products.items[column]); self.soundEffectsM.playSound(sound: "ShellGrab", type: "wav")
                    }) {
                        Text(self.products.items[column].localizedDescription)
                            .font(Font.system(size: 25, design: .monospaced))
                            .shadow(color: Color.black, radius: 0, y: 1)
                            .shadow(color: Color.gray, radius: 0, y: 1)
                            .shadow(radius: 10)
                            .frame(minWidth: 0, maxWidth: .infinity)
                            .foregroundColor(.yellow)
                            .background(Color.black.opacity(0.5))
                            .background(LinearGradient(gradient: Gradient(colors: [Color.black, Color.green, Color.black]), startPoint: .topLeading, endPoint: .bottomTrailing))
                            .clipShape(Capsule())
                    }.padding(5)
                }

but this way I am unable to customise each item. Such as remove hit testing. Any advice on how i can write either of these two ways better?

Have you tried doing it in storyboard and then running the backend separately?

No I haven’t tried that. How would I do that please?

If you have main.storyboard, go in there and create the button. Then hook up the button to the bottom set of code with an @IBAction and whatever else such as text changes in the viewDidLoad.

I don’t have storyboard but thank you for the advice. I have committed to using the ForEach method for the moment.

1 Like

Do you have any idea of how I can pull the local price for an in app purchase? I can’t seem to figure out how.

I haven’t stated a direct price within the app I am developing. On the app store I simply put the tier price in my local currency and it should show the correct price to the user in their local currency when they click to purchase.

1 Like