Jak sprawdzić, czy Apple Music jest zainstalowany na urządzeniu użytkownika?

9

Szybko tworzę aplikację muzyczną. Aplikacja pozwala użytkownikom odtwarzać muzykę w ramach subskrypcji Apple Music za pośrednictwem aplikacji Apple Music. Jestem w stanie sprawdzić, czy użytkownik ma subskrypcję Apple Music przez:

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

}

Jednak: istnieją scenariusze, w których ktoś z jakiegoś powodu będzie miał subskrypcję Apple Music, ale nie pobierze aplikacji Apple Music na swoje urządzenie. Jeśli użytkownik ma subskrypcję, ale nie ma urządzenia, chcę zasadniczo potraktować tę sprawę tak, jakby w ogóle nie miała subskrypcji, tzn. Nie możemy odtwarzać muzyki za pośrednictwem Apple Music.

Dlatego szukam sposobów na dodanie sprawdzenia, czy Apple Music jest na urządzeniu użytkownika. Uważam tę odpowiedź: Sprawdź, czy aplikacja jest zainstalowana przy użyciu Swift łączone z tego zasobu do znalezienia schematu URL Apple Music za i stwierdzić mogę sprawdzić, czy użytkownik ma zarówno subskrypcji Apple Music oraz aplikacji Apple Music zainstalowanego na swoim urządzeniu poprzez:

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

}

Problemem jest, nawet po usunięciu Apple Music z mojego urządzenia, pierwszy przypadek, tj. Ten, który drukuje, user has Apple Music subscription and has the apple music app installedjest nadal wywoływany. Wydaje mi się, że mam prawidłowy schemat adresu URL, ponieważ podczas zmiany "music://"na wywoływany jest "musi://"drugi przypadek, tj. Ten, który drukuje user does not have subscription or doesn't have apple music installed.

Podczas próby otwarcia za URL(string: "music://")pomocą Apple Music usuniętej za pośrednictwem UIApplication.shared.open(URL(string: "music://")!)pojawia się następujący alert:

wprowadź opis zdjęcia tutaj

Dlaczego więc urządzenie mówi, że mogę otworzyć URL(string: "music://")nawet po usunięciu Apple Music? Czy URLmożna otworzyć, ale wynikiem jest po prostu prezentacja powyższego ostrzeżenia? Czy to właściwy sposób na potwierdzenie, że użytkownik ma zainstalowaną aplikację Apple Music na swoim urządzeniu? Czy istnieje sposób na potwierdzenie, że użytkownik ma zainstalowaną aplikację Apple Music na swoim urządzeniu? Jeśli Apple daje użytkownikom opcję usunięcia aplikacji Apple Music, powinni także dać programistom możliwość sprawdzenia, czy aplikacja jest zainstalowana.

David Chopin
źródło
Nigdy nie pracowałem z muzyką Apple, ale uważam, że Apple traktuje ten schemat adresów URL w szczególny sposób, ponieważ jest to ich własny produkt, dlatego za każdym razem, gdy trafisz na ten schemat adresów URL, lepiej zaproponuj użytkownikowi pobranie aplikacji, niż powrót fałszywe. Czy próbowałeś znaleźć prawidłowy schemat adresu URL, który faktycznie otworzyłby prawdziwy album w Apple Music lub odtworzył prawdziwą piosenkę? Np URL(string: "music://trackID=3214534").: Być może ten wyraźny schemat adresów URL będzie traktowany w zwykły sposób, ale nie wywoła app restorealarmu.
Starsky
Próbowałem kilka adresów URL z zastosowaniem poprawnych utworów i wykonawców identyfikatory Apple Music, które nie wydają się do głębokiego linku z muzyką Apple: URL(string: "music://trackId=1377813289")!, URL(string: "music://track=1377813289"), URL(string: "music://artist=562555")!, URL(string: "music://artistId=562555")!. Jedynym sposobem, w jaki udało mi się uzyskać głębokie łącze, jest coś takiego URL(string: "https://music.apple.com/us/artist/562555")!, ale to oczywiście nie pomaga, ponieważ jest to HTTP.
David Chopin
czy masz „music: //” na białej liście w info.plist z LSApplicationQueriesSchemes ?. Jeśli nie, to canOpenUrl może źle zachowywać.
Karthick Ramesh
1
Niestety, dodanie białej listy do schematu w moim info.plist wcale nie zmienia zachowania. Mój problem polega na tym, że cały czas UIApplication.shared.canOpenURL(URL(string: "music://")!)wraca true, nawet jeśli aplikacja Apple Music zostanie usunięta. Potrzebuję go zwrócić falsepo usunięciu aplikacji. Dodanie białej listy do schematu URL nie rozwiąże tego problemu (próbowałem).
David Chopin
znalazłeś na to lepsze rozwiązanie?
Martin Mlostek,

Odpowiedzi:

3

Najlepszym rozwiązaniem, jakie mam, choć spodziewam się, że jest coś lepszego, jest zastosowanie MPMusicPlayer.prepareToPlay(completionHandler:) sprawdzenie, czy podczas próby odtworzenia utworu wystąpił błąd:

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

}

Nie jestem pewien, w jaki sposób może to odnosić się do każdego, kto korzysta z Apple Music w swojej aplikacji do celów innych niż odtwarzanie utworów, ale wydaje się to zdecydowanie działać jako czek, gdy masz zamiar zagrać czek. Za każdym razem, gdy trafia mi ten błąd, po prostu tworzę alert informujący osobę, która ma subskrypcję Apple Music, ale nie ma zainstalowanej aplikacji.

Byłoby jednak wspaniale móc sprawdzać bez jakiejkolwiek procedury obsługi zakończenia, ponieważ pozwoliłoby to zintegrować sprawdzenie logiczne z instrukcjami warunkowymi (via if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }).

David Chopin
źródło
To rozwiązanie działa na zasadzie sprawdzania błędów, ale jest nieco zhackowane i wymaga wykonania następującego kodu w module obsługi zakończenia. Lepiej jest mieć sposób na proste sprawdzenie, czy jest częścią ramy MusicKit, czy sama aplikacja jest zainstalowana.
David Chopin
Ale tak, ta odpowiedź jest obejściem, w którym wykorzystuje się błędy podczas przygotowywania do odtwarzania utworu. Deweloper może potrzebować wiedzieć, czy Apple Music jest zainstalowany bez odtwarzania utworu.
David Chopin
1
czy to wciąż najlepsze rozwiązanie, jakie znalazłeś?
Martin Mlostek
Niestety tak
David Chopin
0

Na szczęście Apple udostępnia metodę zwracającą wartość false, jeśli żadna aplikacja zainstalowana na urządzeniu nie jest zarejestrowana do obsługi schematu adresu URL lub jeśli nie zadeklarowałeś schematu adresu URL w pliku Info.plist; w przeciwnym razie prawda.

func canOpenURL(_ url: URL) -> Bool

Po opublikowaniu schematów URL

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

Dodaj te, których będziesz dalej używać, do pliku info.plist.

Po tym użyj „canOpenURL”, aby uzyskać więcej informacji, sprawdź dokumenty Apple

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

Zeeshan Ahmed
źródło
Schemat url Apple Music zawsze wraca truepo przejściu canOpenUrl. To jest główny problem, który chcę rozwiązać za pomocą tego pytania.
David Chopin
czy określiłeś „aplikację muzyczną” w LSApplicationQueriesSchemes?
Zeeshan Ahmed
sprawdź odpowiedź jeszcze raz zaktualizowałem ją.
Zeeshan Ahmed
Według komentarza Karthicka Ramesha wcześniej próbowałem schematów adresów URL na białej liście bez zmiany zachowania
David Chopin
0

Możliwym rozwiązaniem jest wykonanie następujących czynności: Skonfiguruj token programisty za pomocą interfejsu API Apple Music (używany, aby można było przesyłać zapytania do punktów końcowych REST Apple Music). Prześlij żądanie do następującej funkcji StoreKit ( Dokumentacja ):

requestUserToken(forDeveloperToken:completionHandler:)

Jeśli token dewelopera jest prawidłowy, a zwrócona wartość tokena użytkownika nadal wynosi zero / null, użytkownik urządzenia nie jest subskrybentem usługi Apple Music. Błąd generowany z kodem stanu HTTP to 401 (nieautoryzowany). Nadal wymaga to sprawdzenia błędu, jednak nie wymaga próby odtworzenia określonej ścieżki (szczególnie z jakiegoś powodu, jeśli ścieżka do treści, którą sprawdzasz, staje się niepoprawna lub zmieniona).

W przypadku konta zalogowanego na urządzeniu i posiadającego subskrypcję, ale nie pobrana aplikacja Muzyka: radzić sobie z błędem przy próbie odtworzenia określonej zawartości i albo podać informacje użytkownikowi, albo użyć treści, która nie wymaga subskrypcji Apple Music jako alternatywy kiedy wystąpi błąd.

SierraMike
źródło
1
Tak, więc już wiem, jak sprawdzić, czy użytkownik ma subskrypcję . Moja odpowiedź podana powyżej dotyczy rzeczywistej obsługi błędów. Rozwiązanie, którego szukam, polega wyłącznie na tym, czy możesz stwierdzić, czy użytkownik ma zainstalowaną aplikację Apple Music na urządzeniu, bez konieczności odtwarzania utworu.
David Chopin
0

Tak, możemy sprawdzić większość aplikacji, wykonując następujące kroki:

  1. Użyj głębokiego adresu URL lub schematu URL dla konkretnej aplikacji, którą chcesz otworzyć, dodaj ją do info.plist
  2. Użyj tego samego adresu URL i wywołaj tę metodę
    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
źródło
To nie jest problem, przedstawione pytanie UIApplication.shared.canOpenUrl(URL(string: “music://”)!)zawsze powraca true, nawet jeśli aplikacja nie jest zainstalowana.
David Chopin