web-dev-qa-db-fra.com

iOS: comment détecter si un utilisateur est abonné à un abonnement renouvelable automatiquement

Espérons que le titre soit explicite. J'essaie de faire quelque chose comme ça:

checkIfUserIsSubscribedToProduct(productID, transactionID: "some-unique-transaction-string", completion: { error, status in
    if error == nil {
        if status ==  .Subscribed {
            // do something fun
        }
    }
 }

existe-t-il quelque chose comme le code hypothétique que j'ai fourni? J'ai l'impression de prendre des pilules folles

Modifier

Dans des questions similaires, je continue de voir une réponse générique de "oh tu dois valider le reçu" mais aucune explication sur la façon, ou même ce qu'est un reçu. Quelqu'un pourrait-il me dire comment "valider le reçu"? J'ai essayé ce tutoriel mais ne semble pas fonctionner.

Modifier - Pour la prime

Veuillez résoudre la situation suivante: Un utilisateur s'abonne à mon abonnement auto-renouvelable et obtient plus de contenu numérique à cause de cela - cool, mis en œuvre. Mais comment puis-je vérifier si cet abonnement est toujours valide (c'est-à-dire qu'il n'a pas annulé son abonnement) chaque fois qu'il ouvre l'application? Quelle est la solution la plus simple pour vérifier cela? Y a-t-il quelque chose comme le code hypothétique que j'ai fourni dans ma question? Veuillez m'expliquer cela et fournir d'autres détails sur le sujet qui pourraient être utiles.

32
rigdonmr

Je sais que tout le monde était très inquiet pour moi et comment je faisais à ce sujet - n'ayez crainte, résolu mon problème. Le problème principal était que j'ai essayé les ordures et le code obsolète dans ce lien , mais cela ne fonctionnait pas, j'ai donc abandonné. Ensuite, j'y suis revenu et l'ai implémenté avec Alamofire et cela fonctionne très bien. Voici la solution de code:

Swift 3:

let receiptURL = Bundle.main.appStoreReceiptURL
let receipt = NSData(contentsOf: receiptURL!)
let requestContents: [String: Any] = [
    "receipt-data": receipt!.base64EncodedString(options: []),
    "password": "your iTunes Connect shared secret"
]

let appleServer = receiptURL?.lastPathComponent == "sandboxReceipt" ? "sandbox" : "buy"

let stringURL = "https://\(appleServer).iTunes.Apple.com/verifyReceipt"

print("Loading user receipt: \(stringURL)...")

Alamofire.request(stringURL, method: .post, parameters: requestContents, encoding: JSONEncoding.default)
    .responseJSON { response in
        if let value = response.result.value as? NSDictionary {
            print(value)
        } else {
            print("Receiving receipt from App Store failed: \(response.result)")
        }
}
24
rigdonmr

Qu'essayez-vous de réaliser en particulier? Voulez-vous rechercher un ID Apple ID spécifique?

Je doute fortement que cela soit possible via le SDK. En vous référant à Est-il possible d'obtenir l'utilisateur Apple ID via le SDK? vous pouvez voir que vous ne pouvez même pas demander l'ID directement mais plutôt les services attachés à il.

Ce qui fonctionnerait, c'est de mettre en cache toutes les transactions sur votre propre serveur et de rechercher sa base de données localement, mais cela nécessiterait que l'application demande l'identifiant de l'utilisateur Apple ID afin que l'application puisse mettre à jour l'état de l'abonnement à chaque lancement en tant que il peut vérifier l'IAP de l'ID associé à l'appareil.

Cependant, l'utilisateur peut simplement taper ce qu'il veut - et il est peu probable que cela passe par le processus d'examen des applications d'Apple.

1
user2875404

J'utilise MKSoreKit https://github.com/MugunthKumar/MKStoreKit pour les abonnements à renouvellement automatique.Mais c'est dans Objective C que vous pouvez vérifier le code de la bibliothèque pour la solution.Je l'utilise dans mon code et ça marche bien.

en utilisant la méthode ci-dessous, vous pouvez facilement vérifier l'état de l'abonnement.

if([MKStoreManager isProductPurchased:productIdentifier]) {
 //unlock it
}

Il obtient le Apple id de l'appareil et je pense que c'est spécifique à l'utilisateur

1
Rishabh

Comme certains commentaires l'ont souligné, ces réponses présentent quelques défauts.

  1. Appeler /verifyReceipt du client n'est pas sécurisé.
  2. La comparaison des dates d'expiration avec l'horloge de l'appareil peut être usurpée en modifiant l'heure (toujours un hack amusant à essayer après avoir annulé un essai gratuit :))

Il existe d'autres didacticiels sur la façon de configurer un serveur pour gérer la vérification de réception, mais ce n'est qu'une partie du problème. Faire une demande réseau pour décompresser et valider un reçu à chaque lancement d'application peut entraîner des problèmes, il devrait donc y avoir aussi une mise en cache pour que tout fonctionne correctement.

RevenueCat SDK fournit une bonne solution prête à l'emploi pour cela.

Quelques raisons pour lesquelles j'aime cette approche:

  • Valide la réception côté serveur (sans me demander de configurer un serveur)
  • Recherche un abonnement "actif" avec un horodatage du serveur afin de ne pas pouvoir être usurpé en modifiant l'horloge de l'appareil
  • Met le résultat en cache pour qu'il soit super rapide et fonctionne hors ligne

Il y a plus de détails dans cette question: https://stackoverflow.com/a/55404121/3166209

Cela fonctionne, c'est une fonction simple que vous pouvez appeler aussi souvent que nécessaire et qui reviendra de manière synchrone dans la plupart des cas (car elle est mise en cache).

subscriptionStatus { (subscribed) in
    if subscribed {
        // Show that great pro content
    }
}
0
enc_life