Comment vérifier si Apple Music est installé sur l'appareil de l'utilisateur?

9

Je fais une application musicale avec swift. L'application permet aux utilisateurs de jouer de la musique via leur abonnement Apple Music via leur application Apple Music. Je peux vérifier si l'utilisateur a un abonnement Apple Music via:

SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
        print("user has Apple Music subscription")
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
        print("user does not have subscription")
    }

}

Cependant: il y a des scénarios où quelqu'un aura, pour une raison quelconque, un abonnement Apple Music mais sans que l'application Apple Music soit téléchargée sur son appareil. Si l'utilisateur a l'abonnement mais pas l'appareil, je veux essentiellement traiter ce cas comme s'il n'avait pas d'abonnement du tout, c'est-à-dire que nous ne pouvons pas jouer de la musique via Apple Music.

Donc, je vais chercher des moyens d'ajouter une vérification pour savoir si Apple Music est sur l'appareil de l'utilisateur. Je trouve cette réponse: Vérifiez si une application est installée à l'aide de Swift combinée à cette ressource pour trouver le schéma d'URL d'Apple Music et conclure que je peux vérifier si un utilisateur a à la fois un abonnement Apple Music et l'application Apple Music installés sur leur appareil via:

SKCloudServiceController()requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && UIApplication.shared.canOpenURL(URL(string: "music://")!) {
        print("user has Apple Music subscription and has the apple music app installed")
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) || !UIApplication.shared.canOpenURL(URL(string: "music://")!) {
        print("user does not have subscription or doesn't have apple music installed")
    }

}

Le problème est, même après avoir supprimé Apple Music de mon appareil, le premier cas, c'est-à-dire celui qui imprime user has Apple Music subscription and has the apple music app installedest toujours appelé. Je crois que j'ai le bon schéma d'URL car lors du passage "music://"à "musi://", le deuxième cas, c'est-à-dire celui qui imprime user does not have subscription or doesn't have apple music installedest appelé.

Lorsque j'essaie d'ouvrir URL(string: "music://")avec Apple Music supprimé via UIApplication.shared.open(URL(string: "music://")!), je reçois l'alerte suivante:

entrez la description de l'image ici

Alors, pourquoi l'appareil dit-il que je peux ouvrir URL(string: "music://")même après la suppression d'Apple Music? Est-il URLcapable d'être ouvert, mais le résultat est simplement la présentation de l'alerte ci-dessus? Est-ce la bonne façon de confirmer que l'utilisateur a installé Apple Music sur son appareil? Existe-t-il même un moyen de confirmer que l'utilisateur a installé Apple Music sur son appareil? Si Apple donne aux utilisateurs la possibilité de supprimer l'application Apple Music, ils devraient également donner aux développeurs la possibilité de vérifier si l'application est installée.

David Chopin
la source
Je n'ai jamais travaillé avec Apple Music moi-même, mais je crois qu'Apple traite ce schéma d'URL d'une manière spéciale, car il s'agit de son propre produit, donc chaque fois que vous cliquez sur ce schéma d'URL, il est préférable de proposer à l'utilisateur de télécharger l'application, plutôt que de revenir faux. Avez-vous essayé d'identifier un schéma d'URL valide qui ouvrirait réellement un véritable album dans Apple Music ou jouerait une chanson réelle? Ex URL(string: "music://trackID=3214534"). : . Peut-être que ce schéma d'URL explicite serait traité de la manière habituelle, mais ne déclencherait pas d' app restorealerte.
Starsky
J'ai essayé un certain nombre d'URL à l' aide d' Apple valides musique ID de piste et artistes qui ne semblent pas un lien profond avec de la musique d' Apple: URL(string: "music://trackId=1377813289")!, URL(string: "music://track=1377813289"), URL(string: "music://artist=562555")!, URL(string: "music://artistId=562555")!. La seule façon dont j'ai pu établir un lien profond est via quelque chose comme URL(string: "https://music.apple.com/us/artist/562555")!, mais cela n'aide évidemment pas car c'est HTTP.
David Chopin
avez-vous mis en liste blanche "musique: //" dans info.plist avec LSApplicationQueriesSchemes ?. Sinon, canOpenUrl est censé se comporter mal.
Karthick Ramesh
1
Malheureusement, la liste blanche du schéma dans mon info.plist ne change pas du tout le comportement. Mon problème est qu'il UIApplication.shared.canOpenURL(URL(string: "music://")!)revient truetout le temps, même si l'application Apple Music est supprimée. J'en ai besoin pour revenir falselorsque l'application est supprimée. La liste blanche du schéma d'URL ne résoudra pas ce problème (je l'ai essayé).
David Chopin
avez-vous trouvé une meilleure solution pour cela?
Martin Mlostek

Réponses:

3

La meilleure solution que j'ai, bien que j'attende quelque chose de mieux, est MPMusicPlayer.prepareToPlay(completionHandler:)de vérifier s'il y a une erreur lors de la lecture d'une piste:

SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
        print("user has Apple Music subscription")
        MPMusicPlayerController.systemMusicPlayer.setQueue(with: ["1108845248"])
        systemMusicPlayer.prepareToPlay { (error) in
            if error != nil && error!.localizedDescription == "The operation couldn’t be completed. (MPCPlayerRequestErrorDomain error 1.)" {
                //It would appear that the user does not have the Apple Music App installed
            }
        }
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
        print("user does not have subscription")
    }

}

Je ne sais pas comment cela pourrait s'appliquer à quiconque utilise Apple Music dans son application pour autre chose que la lecture de pistes, mais cela semble définitivement fonctionner comme un chèque lorsque vous êtes sur le point de jouer un chèque. Chaque fois que je suis frappé par cette erreur, je crée simplement une alerte indiquant à la personne qu'elle a un abonnement Apple Music mais que l'application n'est pas installée.

Néanmoins, ce serait formidable de pouvoir vérifier sans un gestionnaire de complétion car cela permettrait au contrôle booléen d'être intégré dans les instructions conditionnelles (via if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }).

David Chopin
la source
Eh bien, cette solution fonctionne en vérifiant les erreurs, mais c'est un peu hacky et nécessite l'exécution du code suivant dans un gestionnaire d'achèvement. Il est préférable d'avoir un moyen de vérifier simplement si cela fait partie du framework MusicKit ou non, si l'application elle-même est installée.
David Chopin
Mais oui, cette réponse est une solution de contournement qui utilise des erreurs lors de la préparation de la lecture d'une piste. Un développeur peut avoir besoin de savoir si Apple Music est installé sans lire de piste.
David Chopin
1
est-ce toujours la meilleure solution que vous ayez trouvée?
Martin Mlostek
Malheureusement, oui
David Chopin
0

Heureusement, Apple vous fournit une méthode qui renvoie false si aucune application installée sur l'appareil n'est enregistrée pour gérer le schéma de l'URL, ou si vous n'avez pas déclaré le schéma de l'URL dans votre fichier Info.plist; sinon, c'est vrai.

func canOpenURL(_ url: URL) -> Bool

Je publie les schémas d'URL

Open = music://
Open = musics://
Open = audio-player-event://

Ajoutez ceux que vous utiliserez davantage dans votre fichier info.plist.

Après cette utilisation, 'canOpenURL' pour vérifier pour plus d'informations, consultez les documents Apple

https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl

Zeeshan Ahmed
la source
Le schéma d'URL d'Apple Music revient toujours truelors de son passage canOpenUrl. C'est le principal problème que je veux aborder avec cette question.
David Chopin
avez-vous spécifié 'Music app' dans LSApplicationQueriesSchemes?
Zeeshan Ahmed
vérifier à nouveau la réponse, je l'ai mise à jour.
Zeeshan Ahmed
Selon le commentaire de Karthick Ramesh, j'ai déjà essayé de mettre des listes d'URL en liste blanche sans changement de comportement
David Chopin
0

Une solution possible consiste à: configurer un jeton de développeur via l'API Apple Music (utilisé pour interroger les points de terminaison REST Apple Music). Envoyez une demande à la fonction StoreKit suivante ( Documentation ):

requestUserToken(forDeveloperToken:completionHandler:)

Si votre jeton de développeur est valide et que la valeur de jeton utilisateur renvoyée est toujours nulle / nulle, l'utilisateur de l'appareil n'est pas abonné au service Apple Music. Une erreur générée avec le code d'état HTTP est 401 (non autorisé). Cela nécessite toujours que vous vérifiiez une erreur, mais ne nécessite pas d'essayer de lire une piste spécifique (Surtout pour une raison quelconque si l'ID de la piste de contenu contre laquelle vous vérifiez devient invalide ou modifié).

Pour le problème de compte connecté à l'appareil et disposant d'un abonnement mais pas de l'application Musique téléchargée: gérer l'erreur lors de la tentative de lecture d'un contenu spécifique et fournir des informations à l'utilisateur ou utiliser du contenu qui ne nécessite pas d'abonnement Apple Music comme alternative lorsqu'une erreur se produit.

SierraMike
la source
1
Oui, donc je sais déjà comment vérifier si un utilisateur a un abonnement . Ma réponse fournie ci-dessus concerne la gestion réelle des erreurs. La solution que je recherche est strictement de savoir si vous pouvez savoir si l'utilisateur a installé l'application Apple Music sur l'appareil sans avoir à essayer de lire une piste.
David Chopin
0

Oui, nous pouvons vérifier la plupart des applications en suivant ces étapes:

  1. Utilisez l' URL profonde ou le schéma d'URL pour l'application particulière que vous souhaitez ouvrir, ajoutez-la à info.plist
  2. Utilisez la même URL et appelez cette méthode
    func canOpenURL(_ url: URL) -> Bool
    let url = URL(string: "music://")

    UIApplication.shared.open(url!) { (result) in
       if result {
          // The URL was delivered successfully!
       }
    }
Srinivasan CP
la source
Ce n'est pas le problème, la question décrite qui UIApplication.shared.canOpenUrl(URL(string: “music://”)!)revient toujours true, même si l'application n'est pas installée.
David Chopin