Come verificare se Apple Music è installato sul dispositivo dell'utente?


9

Sto realizzando un'app musicale con swift. L'app consente agli utenti di riprodurre musica tramite l'abbonamento Apple Music tramite l'app Apple Music. Sono in grado di verificare se l'utente ha un abbonamento Apple Music tramite:

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

}

Tuttavia: ci sono scenari in cui qualcuno, per qualche motivo, avrà un abbonamento Apple Music ma non avrà l'app Apple Music scaricata sul proprio dispositivo. Se l'utente ha l'abbonamento ma non il dispositivo, voglio essenzialmente trattare quel caso come se non avesse alcun abbonamento, cioè non possiamo riprodurre musica tramite Apple Music.

Quindi, cerco modi per aggiungere un controllo per verificare se Apple Music si trova sul dispositivo dell'utente. Trovo questa risposta: Controllare se un app è installato utilizzando Swift combinato con questa risorsa per la ricerca di schema URL di Apple di musica e concludere posso controllare se un utente ha sia un abbonamento di Apple di musica e l'applicazione Apple Music installato sul proprio dispositivo tramite:

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

}

Il problema è, anche dopo aver eliminato Apple Music dal mio dispositivo, il primo caso, ovvero quello che stampa user has Apple Music subscription and has the apple music app installedviene ancora chiamato. Credo di avere lo schema url corretto perché quando si cambia "music://"in "musi://", il secondo caso, cioè quello che stampa user does not have subscription or doesn't have apple music installedviene chiamato.

Quando provo ad aprire URL(string: "music://")con Apple Music cancellato tramite UIApplication.shared.open(URL(string: "music://")!), sono colpito dal seguente avviso:

inserisci qui la descrizione dell'immagine

Quindi perché il dispositivo dice che posso aprire URL(string: "music://")anche dopo l'eliminazione di Apple Music? È in URLgrado di essere aperto, ma il risultato è semplicemente la presentazione dell'avviso di cui sopra? È questo il modo corretto per confermare che l'utente ha installato Apple Music sul proprio dispositivo? Esiste un modo per confermare che l'utente ha installato Apple Music sul proprio dispositivo? Se Apple offre agli utenti la possibilità di eliminare l'app Apple Music, dovrebbero anche consentire agli sviluppatori di verificare se l'app è installata.


Non ho mai lavorato con Apple Music da solo, ma credo che Apple tratti questo schema di url in un modo speciale, dal momento che è il loro prodotto, quindi ogni volta che colpisci quello schema di url, propongono meglio all'utente di scaricare l'app, piuttosto che tornare falsa. Hai provato a identificare uno schema url valido che avrebbe effettivamente aperto un vero album in Apple Music o suonato un brano vero? Es URL(string: "music://trackID=3214534"). : Forse questo esplicito schema di url verrebbe trattato in un modo normale, ma non innescherebbe un app restoreavviso.
Starsky,

Ho provato un certo numero di URL utilizzando validi traccia e artista gli ID di Apple di musica che non sembrano avere un collegamento profondo con la musica di Apple: URL(string: "music://trackId=1377813289")!, URL(string: "music://track=1377813289"), URL(string: "music://artist=562555")!, URL(string: "music://artistId=562555")!. L'unico modo in cui sono stato in grado di collegare in profondità è tramite qualcosa di simile URL(string: "https://music.apple.com/us/artist/562555")!, ma questo ovviamente non aiuta in quanto questo è HTTP.
David Chopin,

hai elencato "music: //" in info.plist con LSApplicationQueriesSchemes ?. In caso contrario, si suppone che CanOpenUrl non funzioni correttamente.
Karthick Ramesh,

1
Sfortunatamente, la whitelisting dello schema nella mia info.plist non cambia affatto il comportamento. Il mio problema è che UIApplication.shared.canOpenURL(URL(string: "music://")!)ritorna truesempre, anche se l'app Apple Music viene eliminata. Ho bisogno che ritorni falsequando l'app viene eliminata. La whitelisting dello schema URL non risolverà questo problema (l'ho provato).
David Chopin,

hai trovato una soluzione migliore per quello?
Martin Mlostek,

Risposte:


3

La migliore soluzione che ho, anche se mi aspetto che ci sia qualcosa di meglio là fuori, è usare MPMusicPlayer.prepareToPlay(completionHandler:)per verificare se c'è un errore quando si tenta di riprodurre una traccia:

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

}

Non sono sicuro di come questo possa applicarsi a chiunque utilizzi Apple Music all'interno della propria app per qualcosa di diverso dalla riproduzione di brani, ma questo sembra sicuramente funzionare come un controllo quando stai per eseguire un controllo. Ogni volta che vengo colpito da quell'errore, creo semplicemente un avviso che dice alla persona che hanno un abbonamento Apple Music ma non ha l'app installata.

Tuttavia, sarebbe bello poter controllare senza qualche gestore di completamento in quanto ciò consentirebbe l'integrazione del controllo booleano in istruzioni condizionali (via if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }).


Bene, questa soluzione funziona controllando la presenza di errori, ma è un po 'confusa e richiede l'esecuzione del codice seguente in un gestore di completamento. È meglio avere un modo per controllare semplicemente, che faccia parte o meno del framework MusicKit, se l'app stessa è installata.
David Chopin,

Ma sì, questa risposta è una soluzione alternativa che utilizza errori quando si prepara a riprodurre una traccia. Uno sviluppatore potrebbe aver bisogno di sapere se Apple Music è installato senza riprodurre una traccia.
David Chopin,

1
è ancora la soluzione migliore che hai trovato?
Martin Mlostek,

Sfortunatamente sì
David Chopin il

0

Fortunatamente Apple ti fornisce un metodo che restituisce false se nessuna app installata sul dispositivo è registrata per gestire lo schema dell'URL o se non hai dichiarato lo schema dell'URL nel tuo file Info.plist; altrimenti vero.

func canOpenURL(_ url: URL) -> Bool

Di seguito sto pubblicando gli schemi url

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

Aggiungi quelli che utilizzerai ulteriormente nel tuo file info.plist.

Dopo questo uso 'canOpenURL' per verificare ulteriori informazioni, controlla i documenti Apple

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


Lo schema URL di Apple Music ritorna sempre truequando lo si passacanOpenUrl . Questo è il problema principale che voglio affrontare con questa domanda.
David Chopin,

hai specificato "App musicale" in LSApplicationQueriesSchemes?
Zeeshan Ahmed,

controlla di nuovo la risposta, l'ho aggiornata.
Zeeshan Ahmed,

Per il commento di Karthick Ramesh, in precedenza avevo provato a autorizzare schemi URL senza cambiare il comportamento
David Chopin

0

Una possibile soluzione è la seguente: Configura un token per sviluppatori tramite l'API di Apple Music (utilizzata in modo da poter eseguire query sugli endpoint REST di Apple Music). Invia una richiesta alla seguente funzione StoreKit ( Documentazione ):

requestUserToken(forDeveloperToken:completionHandler:)

Se il token sviluppatore è valido e il valore del token utente restituito è ancora nullo / nullo, l'utente del dispositivo non è un abbonato del servizio Apple Music. Un errore generato con il codice di stato HTTP è 401 (non autorizzato). Ciò richiede comunque la verifica di un errore, tuttavia non è necessario provare a riprodurre una traccia specifica (soprattutto per qualche motivo se l'ID della traccia di contenuto su cui si verifica il controllo diventa non valido o modificato).

Per il rilascio dell'account connesso al dispositivo e con un abbonamento ma non con l'app Music scaricata: gestisci l'errore nel tentativo di riprodurre contenuti specifici e fornire informazioni all'utente o utilizzare contenuti che non richiedono un abbonamento Apple Music in alternativa quando si verifica un errore.


1
Sì, quindi so già come verificare se un utente ha un abbonamento . La mia risposta fornita sopra riguarda l'effettiva gestione degli errori. La soluzione che sto cercando è rigorosamente se puoi dire se l'utente ha l'app Apple Music installata sul dispositivo senza dover provare a riprodurre un brano.
David Chopin,

0

Sì, possiamo verificare la maggior parte delle applicazioni seguendo questi passaggi:

  1. Usa l' URL profondo o lo schema URL per la particolare applicazione che desideri aprire, aggiungila in info.plist
  2. Usa lo stesso URL e chiama questo metodo
    func canOpenURL(_ url: URL) -> Bool
    let url = URL(string: "music://")

    UIApplication.shared.open(url!) { (result) in
       if result {
          // The URL was delivered successfully!
       }
    }

Questo non è il problema, la domanda sottolineata che UIApplication.shared.canOpenUrl(URL(string: “music://”)!)ritorna sempre true, anche se l'app non è installata.
David Chopin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.