Question

Subscription is not working on iOS while working on macOS

  • 5 January 2023
  • 3 replies
  • 43 views

Badge +3

I have sent my app to Apple review, they accepted the macOS version of the app, and rejected the iOS version. So I tried the subscription again within Xcode, and actually, it's running successfully with the macOS, while it is not on iOS (Simulator). The code to do the purchasing for macOS and iOS is nearly the same.

Please see attached:

Apple review

Screenshot of their test

Screenshot of my test (Xcode log)


3 replies

Userlevel 1
Badge +3

Hey Sami, 

I’m sorry to say that it looks like your images didn’t come through! You say that your subscriptions aren’t currently working on your iOS app - are you getting any errors when testing? 

Badge +3

Hello Kaitlin,

I've attached the images again, I hope I attached them correctly now. The screenshots show the rejection reason from Apple. After a successful purchase on the iPad, the user can't skip the paywall.

In addition, below is my implementation of the purchasing process using RevenueCat, would you please take a look at it, I don't know if I am doing it right.

import Foundation
import RevenueCat
import SwiftUI

class PurchaseManager: ObservableObject {

static let shared = PurchaseManager()

/* Set from the didSet method of customerInfo above, based on the entitlement set in Constants.swift */
@Published var offerrings: Offerings? = nil
@Published var subscriptionActive: Bool = false
@Published var showModal: Bool = true

init() {
refreshSubscription()
Task {
let offerrings = try await Purchases.shared.offerings()
await MainActor.run {
self.offerrings = offerrings
}
}
}

func restore() {
Purchases.shared.restorePurchases { customerInfo, error in
if error != nil {
return
}
self.processInfo(info: customerInfo)
}
}

public func refreshSubscription() {
Purchases.shared.getCustomerInfo { (info, _) in
self.processInfo(info: info)
}
}

func purchase(package: Package) {
Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in
if error != nil || userCancelled {
return
}
self.processInfo(info: customerInfo)
}
}

private func processInfo(info: CustomerInfo?) {
if info?.entitlements[Constant.entitlementId]?.isActive == true {
self.subscriptionActive = true
self.showModal = false
}
else {
self.subscriptionActive = false
self.showModal = true
}
}

}

And at the paywall, I call “purchase” function when user tries to Subscribe. The following is implementation of the subscription button:

struct iOSSubscriptionButton: View {

@Binding var showModal: Bool
@EnvironmentObject var purchaseManager: PurchaseManager
var annualSub : Package? {
purchaseManager.offerrings?.current?.availablePackages.first(where: { package in
package.storeProduct.productIdentifier == Constant.productId
})
}

var body: some View {
if purchaseManager.subscriptionActive {
Text(NSLocalizedString("SUBSCRIBED", comment: "Subscribed"))
.foregroundColor(.green)
} else {
Button(action: {
guard let annualSub = annualSub else {return}
purchaseManager.purchase(package: annualSub)
}, label: {
if let price = annualSub?.localizedPriceString {
VStack {
Text(NSLocalizedString("TRY", comment: "Try"))
}
}
else {
ProgressView()
}
})
.disabled(annualSub == nil)
}
}
}

Is my code correct?

Should I do something after the purchase done successfully?

If yes, how should I do that using a completion handler or something similar?

Userlevel 1
Badge +3

Your User View Model looks good and I was able to get an app up and working using your code. Regarding the paywall, it’s tough to give coding advice just by looking at a chunk that also ties to other parts of your app - my recommendation is to take a look at our Swift UI sample app and how the Paywall is implemented there: 

https://github.com/RevenueCat/purchases-ios/blob/main/Examples/MagicWeatherSwiftUI/Shared/Sources/Views/PaywallView.swift

Reply