[英]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.