2017-09-28 4 views
1

私はトップビューコントローラを選択するためのプレイリストのリストを表示するテーブルビューコントローラに設定したスプリットビューコントローラを持っています。最初にアプリケーションが読み込まれると、音楽アクセスの許可が求められます。 Yesと答えると許可されますが、テーブルビューにはプレイリストが表示されません。私は、アプリを殺してもう一度それを実行する必要があります。私は音楽ライブラリの許可を間違った場所に要求していますか?それは、トップビューコントローラのviewWillです。再生リストのクラスで、私が使用しているプレイリストを貼り付けて保存します(一部は一部が除外されているため)。コメントのswift初期表示コントローラの音楽許可をお願いします

 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() 
} 
+0

MPMediaLibraryのrequestAuthorizationブロックは[weak self]として実装されているため、selfはブロック内には存在しない可能性があります。 checkMediaAccessAndSetupメソッドがMPMediaLibraryでの認証を要求した後に呼び出されていますか? – Rendel

+0

メインスレッドで 'requestAuthorization'コールバックが呼び出されていないことが原因です。 –

+0

viewWillAppear内のDispatchQueue.main.async {}内でself.checkMediaAccessAndSetup()を試してみました(self?.checkMediaAccessAndSetup()は許可されません)。 。同じこと。 – EdZ

答えて

0

チーフの問題は、あなたが完全に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は何でもかまいません。どこでもあなたのアプリでは認証が必要な場合があります。

+0

パーフェクト!ありがとう、はい私はそれを得ていないが、私は今行う。 – EdZ

-1

おかげで、それは私に起こっていたマルチスレッドの手がかりを与え、チェックを続けるとリロードするクラスには、プレイリストがなかった場合、私は、タイマーコールでそれを修正することができましたテーブルデータあなたのコードで

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) 
    } 
} 
+0

私はこれに同意できません。この方法でタイマーを使うのはちょっと不気味です。プレイリストを表示するアプリがあり、そのようなハッキングの必要はありません。正しい順序でやり遂げるのは単なる問題です。おそらく問題はあなたが表示していない 'setupPlaylistStore'にあります。 – matt

+0

setupPlaylistStoreを追加しました。私は一種の同意だが、すべての許可が与えられる前にすべてが呼び出されているのを見ることができた。他の提案にも対応していますが、セットアップでは許可されていない(まだ)と言っています。 – EdZ

+0

"許可が付与される前にすべてが呼び出されていました"もちろん、あなたの仕事はその可能性にしっかりと対処し、許可が_付与されたときにすべてを再度呼び出すことです - 承認_being_に対する_response_(_timer_これがいつ起こったのか推測します)。 – matt

関連する問題