簡體   English   中英

快速詢問音樂權限以獲取初始視圖控制器

[英]swift ask music permission for initial view controller

我有一個拆分視圖控制器,其頂視圖控制器設置為表視圖控制器,該控制器用於顯示播放列表列表供選擇。 首次加載應用程序時,它會請求音樂訪問權限。 回答“是”確實會授予它權限,但表視圖不顯示任何播放列表。 我最終不得不殺死該應用程序並再次運行。 我是在錯誤的位置申請音樂庫許可嗎? 正是在該頂部視圖控制器的viewWillAppear中,並將我正在使用的播放列表(因為某些播放列表被篩選掉)存儲在一個播放列表中。

        override func viewWillAppear(_ animated: Bool) {
    self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
    super.viewWillAppear(animated)

    checkMediaAccessAndSetup()
}

func checkMediaAccessAndSetup() {
    let authorizationStatus = MPMediaLibrary.authorizationStatus()
    switch authorizationStatus {
    case .notDetermined:
        // Show the permission prompt.
        MPMediaLibrary.requestAuthorization({[weak self] (newAuthorizationStatus: MPMediaLibraryAuthorizationStatus) in
            // Try again after the prompt is dismissed.
            self?.checkMediaAccessAndSetup()
        })
    case .denied, .restricted:
        // Do not use MPMediaQuery.
        return
    default:
        // Proceed as usual.
        break
    }
    // Do stuff with MPMediaQuery
    self.setupPlaylistStore()
    tableView.reloadData()
}

您的代碼的主要問題是

  • 您完全無法解決在后台線程上調用requestAuthorization完成函數這一事實。 您需要跳出主線程才能在接口上工作。

  • 您已省略了所有重要的.authorized案例。 當你有工作要做,這取決於你的授權狀態,你必須現在就做,如果你被授權,但授權后,如果您沒有確定。

因此,這是進行一致性授權檢查的正確方案(其中f()是您可能總是想做的事情):

let status = MPMediaLibrary.authorizationStatus()
switch status {
case .authorized:
    f()
case .notDetermined:
    MPMediaLibrary.requestAuthorization() { status in
        if status == .authorized {
            DispatchQueue.main.async {
                f()
            }
        }
    }
// ...
}

如果將代碼抽象為實用工具方法,其中f可以是任意值,則可以在應用程序中可能需要授權的任何地方進行此操作-不僅僅是在啟動時。

感謝您的評論,它為我提供了正在進行的多線程的線索,並且如果類中沒有播放列表可以繼續檢查並重新加載表數據,我可以通過計時器調用對其進行修復。

override func viewWillAppear(_ animated: Bool) {
    self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
    super.viewWillAppear(animated)

    checkMediaAccess()
    self.setupPlaylistStore()
    tableView.reloadData()
    if store.allPlaylists.count < 1 {
        playlistTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector:     #selector(self.playlistTimerCall), userInfo: nil, repeats: true)
    }
}

@objc func playlistTimerCall() {
    self.setupPlaylistStore()
    if store.allPlaylists.count > 1 {
        tableView.reloadData()
        playlistTimer?.invalidate()
    }
}
func checkMediaAccess() {
    let authorizationStatus = MPMediaLibrary.authorizationStatus()
    switch authorizationStatus {
    case .notDetermined:
        // Show the permission prompt.
        MPMediaLibrary.requestAuthorization({[weak self] (newAuthorizationStatus: MPMediaLibraryAuthorizationStatus) in
            // Try again after the prompt is dismissed.
            self?.checkMediaAccess()
        })
    case .denied, .restricted:
        // Do not use MPMediaQuery.
        return
    default:
        // Proceed as usual.
        break
    }
}


func setupPlaylistStore() {

    // purge store
    store.clearAllPlaylists()

    // create a query of media items in playlist
    let myPlayListsQuery = MPMediaQuery.playlists()
    if myPlayListsQuery.collections != nil {
        playlists = myPlayListsQuery.collections!
    }

    // add playlists to MyPlaylist(s)
    if playlists.count > 0 {
        for index in 0...playlists.count - 1 {
            let playlist = playlists[index]
            store.addPlaylist(playlist: playlist as! MPMediaPlaylist)
        }
    }
    var toBeRemoved = [Int]()
    let defaults = UserDefaults.standard
    if defaults.bool(forKey: "exclude_smart_playlists") {
        //smart
        for index in 0...(playlists.count - 1) {
            let playlist = playlists[index]
            let theAttributes = playlist.value(forProperty: MPMediaPlaylistPropertyPlaylistAttributes) as! Int
            if theAttributes == 2 {
                toBeRemoved.append(index)
            }
        }
    }
    if defaults.bool(forKey: "exclude_folders") {
        //folders
        for index in 0...(playlists.count - 1) {
            let playlist = playlists[index]
            let isFolder = playlist.value(forProperty: "isFolder")
            let stringIsFolder = String("\(String(describing: isFolder))")
            if ((stringIsFolder.range(of: "1")) != nil) {
                toBeRemoved.append(index)
            }
        }
    }
    //sort from the last to the first so i don't reindex
    let reverseSortedPlaylists = toBeRemoved.sorted(by: >)

    // remove the unwanted playlists
    for list in reverseSortedPlaylists {
        store.removePlaylist(index: list)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM