Wie kann ich überprüfen, ob Apple Music auf dem Gerät des Benutzers installiert ist?

9

Ich mache eine Musik-App mit Swift. Mit der App können Benutzer Musik über ihr Apple Music-Abonnement über ihre Apple Music-App abspielen. Ich kann überprüfen, ob der Benutzer ein Apple Music-Abonnement hat über:

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")
    }

}

Es gibt jedoch Szenarien, in denen jemand aus irgendeinem Grund ein Apple Music-Abonnement hat, die Apple Music-App jedoch nicht auf sein Gerät heruntergeladen hat. Wenn der Benutzer das Abonnement hat, aber nicht das Gerät, möchte ich diesen Fall im Wesentlichen so behandeln, als ob er überhaupt kein Abonnement hat, dh wir können keine Musik über Apple Music abspielen.

Daher suche ich nach Möglichkeiten, um zu überprüfen, ob sich Apple Music auf dem Gerät des Benutzers befindet. Ich finde diese Antwort: Überprüfen Sie, ob eine App mit Swift in Kombination mit dieser Ressource installiert wurde, um das URL-Schema von Apple Music zu finden, und schließen Sie, dass ich überprüfen kann, ob ein Benutzer sowohl ein Apple Music-Abonnement als auch die Apple Music-App auf seinem Gerät installiert hat, und zwar über:

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")
    }

}

Das Problem ist, dass auch nach dem Löschen von Apple Music von meinem Gerät der erste Fall, dh der, der gedruckt user has Apple Music subscription and has the apple music app installedwird, immer noch aufgerufen wird. Ich glaube, ich habe das richtige URL-Schema, weil beim Wechsel "music://"zum "musi://"zweiten Fall, dh dem, der gedruckt user does not have subscription or doesn't have apple music installedwird, aufgerufen wird.

Beim Versuch, URL(string: "music://")mit über gelöschter Apple Music zu öffnen UIApplication.shared.open(URL(string: "music://")!), wird folgende Warnung angezeigt:

Geben Sie hier die Bildbeschreibung ein

Warum sagt das Gerät, dass ich URL(string: "music://")auch nach dem Löschen von Apple Music öffnen kann ? Kann das URLgeöffnet werden, aber das Ergebnis ist einfach die Darstellung der obigen Warnung? Ist dies der richtige Weg, um zu bestätigen, dass der Benutzer Apple Music auf seinem Gerät installiert hat? Gibt es überhaupt eine Möglichkeit zu bestätigen, dass der Benutzer Apple Music auf seinem Gerät installiert hat? Wenn Apple Benutzern die Möglichkeit gibt, die Apple Music-App zu löschen, sollten sie Entwicklern auch die Möglichkeit geben, zu überprüfen, ob die App installiert ist.

David Chopin
quelle
Ich habe selbst nie mit Apple-Musik gearbeitet, aber ich glaube, Apple behandelt dieses URL-Schema auf besondere Weise, da es sich um ein eigenes Produkt handelt. Wenn Sie also auf dieses URL-Schema klicken, schlagen sie dem Benutzer vor, die App herunterzuladen, anstatt zurückzukehren falsch. Haben Sie versucht, ein gültiges URL-Schema zu identifizieren, das tatsächlich ein echtes Album in Apple Music öffnet oder ein tatsächliches Lied abspielt? Bsp. : URL(string: "music://trackID=3214534"). Möglicherweise wird dieses explizite URL-Schema wie gewohnt behandelt, aber keine app restoreWarnung ausgelöst .
Starsky
Ich habe versucht , eine Reihe von URLs mit gültigem Apple - Musiktitel und Künstler - IDs, der tiefen Verbindung mit Apple Musik scheint nicht: URL(string: "music://trackId=1377813289")!, URL(string: "music://track=1377813289"), URL(string: "music://artist=562555")!, URL(string: "music://artistId=562555")!. Die einzige Möglichkeit, eine tiefe Verbindung herzustellen, ist über so etwas URL(string: "https://music.apple.com/us/artist/562555")!, aber dies hilft offensichtlich nicht, da dies HTTP ist.
David Chopin
Haben Sie "music: //" in info.plist mit LSApplicationQueriesSchemes auf die weiße Liste gesetzt? Wenn nicht, soll canOpenUrl falsch handeln.
Karthick Ramesh
1
Leider ändert das Whitelisting des Schemas in meiner info.plist das Verhalten überhaupt nicht. Mein Problem ist, dass UIApplication.shared.canOpenURL(URL(string: "music://")!)es immer wieder zurückkommt true, auch wenn die Apple Music App gelöscht wird. Ich brauche es, um zurückzukehren, falsewenn die App gelöscht wird. Das Whitelisting des URL-Schemas behebt dieses Problem nicht (ich habe es versucht).
David Chopin
Hast du eine bessere Lösung dafür gefunden?
Martin Mlostek

Antworten:

3

Die beste Lösung, die ich habe, obwohl ich davon ausgehe, dass es etwas Besseres gibt, besteht darin, MPMusicPlayer.prepareToPlay(completionHandler:)zu überprüfen, ob beim Abspielen eines Titels ein Fehler vorliegt:

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")
    }

}

Ich bin mir nicht sicher, wie dies für jemanden gelten könnte, der Apple Music in seiner App für etwas anderes als das Abspielen von Titeln verwendet, aber dies scheint definitiv als Scheck zu funktionieren, wenn Sie einen Scheck spielen möchten. Immer wenn ich von diesem Fehler betroffen bin, erstelle ich einfach eine Warnung, in der der Person mitgeteilt wird, dass sie ein Apple Music-Abonnement hat, die App jedoch nicht installiert ist.

Trotzdem wäre es großartig, ohne einen Completion-Handler prüfen zu können, da dies die Integration der booleschen Prüfung in bedingte Anweisungen (via if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }) ermöglichen würde.

David Chopin
quelle
Nun, diese Lösung sucht nach Fehlern, ist aber etwas hackig und erfordert die Ausführung des folgenden Codes in einem Completion-Handler. Es ist besser, auf einfache Weise zu überprüfen, ob es Teil des MusicKit-Frameworks ist oder nicht, ob die App selbst installiert ist.
David Chopin
Aber ja, diese Antwort ist eine Problemumgehung, bei der Fehler bei der Vorbereitung der Wiedergabe eines Titels verwendet werden. Ein Entwickler muss möglicherweise wissen, ob Apple Music installiert ist, ohne einen Titel abzuspielen.
David Chopin
1
Ist dies immer noch die beste Lösung, die Sie gefunden haben?
Martin Mlostek
Leider ja
David Chopin
0

Glücklicherweise bietet Apple eine Methode an, die false zurückgibt, wenn keine auf dem Gerät installierte App für die Verarbeitung des URL-Schemas registriert ist oder wenn Sie das Schema der URL nicht in Ihrer Info.plist-Datei deklariert haben. sonst wahr.

func canOpenURL(_ url: URL) -> Bool

Im Folgenden poste ich die URL-Schemata

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

Fügen Sie diejenigen, die Sie weiter verwenden werden, in Ihre info.plist-Datei ein.

Verwenden Sie danach 'canOpenURL', um weitere Informationen zu erhalten. Überprüfen Sie die Apple-Dokumente

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

Zeeshan Ahmed
quelle
Das URL-Schema von Apple Music kehrt immer wieder zurück, truewenn es weitergeleitet wird canOpenUrl. Das ist das Hauptproblem, das ich mit dieser Frage ansprechen möchte.
David Chopin
Haben Sie in LSApplicationQueriesSchemes 'Musik-App' angegeben?
Zeeshan Ahmed
Überprüfen Sie die Antwort erneut. Ich habe sie aktualisiert.
Zeeshan Ahmed
Per Karthick Rameshs Kommentar habe ich zuvor versucht, URL-Schemata auf die Whitelist zu setzen, ohne das Verhalten zu ändern
David Chopin,
0

Eine mögliche Lösung ist die folgende: Einrichten eines Entwicklertokens über die Apple Music API (Wird verwendet, um Apple Music REST-Endpunkte abzufragen). Senden Sie eine Anfrage an die folgende StoreKit-Funktion ( Dokumentation ):

requestUserToken(forDeveloperToken:completionHandler:)

Wenn Ihr Entwicklertoken gültig ist und der zurückgegebene Benutzertokenwert immer noch null / null ist, ist der Gerätebenutzer kein Abonnent des Apple Music-Dienstes. Ein Fehler, der mit dem HTTP-Statuscode generiert wird, ist 401 (nicht autorisiert). Dies erfordert weiterhin, dass Sie einen Fehler überprüfen, jedoch nicht versuchen, einen bestimmten Titel abzuspielen (insbesondere aus irgendeinem Grund, wenn die ID des Inhalts-Tracks, gegen den Sie prüfen, ungültig wird oder geändert wird).

Für die Ausgabe eines Kontos, das auf dem Gerät angemeldet ist und über ein Abonnement verfügt, jedoch nicht die heruntergeladene Musik-App: Behandeln Sie den Fehler, wenn Sie versuchen, bestimmte Inhalte abzuspielen, und geben Sie entweder Informationen an den Benutzer weiter oder verwenden Sie Inhalte, für die alternativ kein Apple Music-Abonnement erforderlich ist wenn ein Fehler auftritt.

SierraMike
quelle
1
Ja, ich weiß also bereits, wie ich überprüfen kann, ob ein Benutzer ein Abonnement hat . Meine Antwort oben bezieht sich auf die tatsächliche Fehlerbehandlung. Die Lösung, nach der ich suche, ist genau, ob Sie feststellen können, ob der Benutzer die Apple Music App auf dem Gerät installiert hat, ohne versuchen zu müssen, einen Titel abzuspielen.
David Chopin
0

Ja, wir können die meisten Anwendungen anhand der folgenden Schritte überprüfen:

  1. Verwenden Sie die Deep URL oder das URL-Schema für die jeweilige Anwendung, die Sie öffnen möchten, und fügen Sie diese in info.plist ein
  2. Verwenden Sie dieselbe URL und rufen Sie diese Methode auf
    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
quelle
Dies ist nicht das Problem, sondern die UIApplication.shared.canOpenUrl(URL(string: “music://”)!)immer wiederkehrende Frage true, auch wenn die App nicht installiert ist.
David Chopin