2017-08-30 25 views
2

ユーザーの連絡先にアクセスしたいと考えています.Appleが提供している連絡先とContactsUIフレームワークを使用する予定です。Swiftの連絡先へのアクセスを要求する3

まず、ユーザーの連絡先にアクセスする許可を求める必要がありますが、問題が発生しています。

func requestForAccess(completionHandler: (accessGranted: Bool) -> Void) { 
    let authorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts) 

    switch authorizationStatus { 
    case .Authorized: 
     completionHandler(accessGranted: true) 

    case .Denied, .NotDetermined: 
     self.contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (access, accessError) -> Void in 
      if access { 
       completionHandler(accessGranted: access) 
      } 
      else { 
       if authorizationStatus == CNAuthorizationStatus.Denied { 
        dispatch_async(dispatch_get_main_queue(), {() -> Void in 
         let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings." 
         self.showMessage(message) 
        }) 
       } 
      } 
     }) 

    default: 
     completionHandler(accessGranted: false) 
    } 
} 

が、私はそうのようスウィフト3に変換しようとしたが、それでもエラーを考え出すています:スウィフト2では、1はそのように許可を求めることができます。

func requestForAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) { 
    let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts) 

    switch authorizationStatus { 
    case .authorized: 
     completionHandler(true) 

    case .denied, .notDetermined: 
     self.contactStore.requestAccess(for: CNEntityType.contacts, completionHandler: { (access, accessError) -> Void in 
      if access { 
       completionHandler(access) 
      } 
      else { 
       if authorizationStatus == CNAuthorizationStatus.denied { 
        DispatchQueue.async(group: DispatchQueue.main, execute: {() -> Void in //error here 
         let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings." 
         self.showMessage(message) 
        }) 
       } 
      } 
     }) 

    default: 
     completionHandler(false) 
    } 
} 

誰もがこの問題を解決しようとする助けることができる:;「あなたの代わりに、この型の値を使用することを意味したインスタンスメンバー 『非同期は』タイプ 『DispatchQueue』で使用することはできません?」エラーがありますか?どんな助けも非常に高く評価されます。ありがとうございました。

乾杯、 テオ

+0

ます。https:// stackoverflowの連絡先へのアクセスは、アプリが正常に動作するため、真に必要不可欠である場合

は、あなたがそれらにそれらをあなたのアプリから直接設定に行くのオプションを与える警告を表示することができます。 com/questions/37801370/how-do-i-dispatch-sync-dispatch-async-dispatch-after-swift-3 – dan

+0

どのエラーが表示されていますか? – GIJOW

+1

"まだエラーが出ています"という質問はありません。 「エラー」とは何か、またどの行にあるのかを明確に述べてください。また、誰もStack Overflowの前にSwift 3で連絡先アクセスを許可する方法について議論したことはありませんか?尋ねる前に検索してみてください。帯域幅を節約する。 – matt

答えて

9

代わり

DispatchQueue.async(group: DispatchQueue.main, execute: { ... } 

のところで

DispatchQueue.main.async { ... } 

を行う権限が以前に拒否された場合は、再度認証を要求するにはポイントがありませんこれは、OSがエンドユーザに「許可アクセス」UIを提示しないためです。ユーザーが以前にアクセスを拒否していない場合にのみ実行されます。

func requestAccess(completionHandler: @escaping (_ accessGranted: Bool) -> Void) { 
    switch CNContactStore.authorizationStatus(for: .contacts) { 
    case .authorized: 
     completionHandler(true) 
    case .denied: 
     showSettingsAlert(completionHandler) 
    case .restricted, .notDetermined: 
     store.requestAccess(for: .contacts) { granted, error in 
      if granted { 
       completionHandler(true) 
      } else { 
       DispatchQueue.main.async { 
        self.showSettingsAlert(completionHandler) 
       } 
      } 
     } 
    } 
} 

private func showSettingsAlert(_ completionHandler: @escaping (_ accessGranted: Bool) -> Void) { 
    let alert = UIAlertController(title: nil, message: "This app requires access to Contacts to proceed. Would you like to open settings and grant permission to contacts?", preferredStyle: .alert) 
    alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in 
     completionHandler(false) 
     UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!) 
    }) 
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in 
     completionHandler(false) 
    }) 
    present(alert, animated: true) 
} 
+0

ありがとう!私が持っていた機能全体を削除してこれを置き換えることをお勧めしますか?その上にshowFunctionsAlert()を追加します。 –

+0

私はあなたの質問に従うか分からない。しかし、これはアクセスを要求するだけでなく、拒否された場合に警告を表示するので、他に何が必要なのか分かりません。 – Rob

+0

ところで、元の例のように、私は閉じたパラメータを取るために私の答えを微調整しました。私の元の例では、ビューが表示されたときに認可を要求していましたが、ユーザーが実際にアクセスする必要があるまでこの質問を延期する方がよいでしょう(ビューが表示されたときかもしれませんが、 ;あなたがそれをできるだけ遅く遅らせると、ユーザーはあなたのアプリに関わっている可能性が高くなり、許可を得る可能性が高くなります。 – Rob

関連する問題