J'ai deux abonnements à renouvellement automatique, mensuel et annuel (iOS). Je peux effectuer un achat lorsque j'utilise un nouvel utilisateur du bac à sable. Cependant, je dois entrer mon mot de passe trois fois. Voici comment cela se passe :
- Tapez sur un abonnement
- Saisir le mot de passe
- Invitation à saisir à nouveau le mot de passe
- obtenir l'erreur "cannot connect to iTunes Store" (Impossible de se connecter à l'iTunes Store)
- essayez à nouveau et entrez le mot de passe
- l'achat réussit.
Si l'opération réussit, je suis maintenant abonné et mon interface utilisateur est mise à jour via un listener dans appDelegate qui envoie une notification à laquelle je m'abonne. Mais lorsque j'essaie de passer d'un abonnement mensuel à un abonnement annuel, ou vice versa, je reçois toujours l'erreur "Cannot connect to iTunes Store". Pas de mise à jour de l'interface utilisateur. Voici le flux :
- Tapez sur l'autre abonnement
- Invitation à saisir le mot de passe iTunes
- Recevoir la boîte de dialogue "confirmer l'achat" qui indique que je modifie mon abonnement
- Tapez sur continuer
- Recevoir l'alerte "Vous êtes prêt".
- Annuler l'alerte
- Recevoir l'erreur "Cannot connect to iTunes Store" (Impossible de se connecter à l'iTunes Store)
- Mon auditeur n'a pas été appelé, l'interface utilisateur n'a pas été mise à jour, etc.
Mais si je rejette l'erreur et que j'appuie à nouveau sur l'abonnement, je reçois une alerte indiquant que je suis déjà abonné à ce plan, bien que l'erreur ait été déclenchée et que mon auditeur n'ait pas pris en compte le changement.
J'utilise firebase. J'ai suivi le quickstart et les instructions spécifiques à Firebase dans les docs de RevenueCat. Tous mes journaux de débogage semblent être corrects, pas de statut non-200, pas d'identifiant de produit invalide. Voici quelques extraits de code :
AppDelegate :
Purchases.debugLogsEnabled = true
Purchases.configure(withAPIKey: Constants.revenueCatKey)
Purchases.shared.delegate = self
FirebaseApp.configure()
authHandle = Auth.auth().addStateDidChangeListener() { (auth, user) in
if let uid = user?.uid {
Purchases.shared.identify(uid, { (info, error) in
if let e = error {
print("sign in error: \(e.localizedDescription)")
} else {
print("User \(uid) signed in")
}
})
}
...
}
}
extension AppDelegate: PurchasesDelegate {
func purchases(_ purchases: Purchases, didReceiveUpdated purchaserInfo: PurchaserInfo) {
if self.currentUser != nil {
if purchaserInfo.activeSubscriptions.contains(Constants.audiomeshSubscriptions.monthly) {
guard let myRef = DataService.instance.REF_PRIVATE else { return }
myRef.updateData(["plan" : "paidMonthly"]) { err in
if let err = err {
print("error updating user-private with new subscription: \(err)")
} else {
NotificationCenter.default.post(name: Notification.Name(rawValue: "purchaserInfoUpdated"), object: nil)
}
}
}
else if purchaserInfo.activeSubscriptions.contains(Constants.audiomeshSubscriptions.yearly) {
//do the same for yearly subscription
}
else {
//handle non-paying users here
}
}
}
}
UpgradeController (l'interface utilisateur pour les achats) :
@objc func purchaseButtonSelected(sender: AudiomeshButton) {
let buttonTag = sender.tag
guard let option = options?[buttonTag] else { return }
let product:SKProduct = option.product
Purchases.shared.makePurchase(product, { (transaction, purchaserInfo, error) in
if let error = error {
print("error making purchase: \(error)")
} else {
print("Purchase Successful")
}
})
}