2015-11-06 4 views
0

У меня есть кнопка для импорта контактов из адресной книги пользователя. Когда они нажимают кнопку в первый раз, мой код возвращает bool, указывающий, предоставил ли пользователь разрешение или нет. Если разрешение предоставлено, контакты импортируются, и я выполняю segue в виде таблицы. Если разрешение не предоставлено, контакты не импортируются, и я выполняю один и тот же сеанс в пустое представление таблицы. Вот что у меня есть:Предупреждение о доступе к адресной книге пользователя не прекращается.

func myImportThenSegueFunction() { 
    if userHasAuthorizedAddressBookAccess() == true { 
     // Import contacts and perform segue 
    } else { 
     // Just perform segue 
    } 
} 

func userHasAuthorizedAddressBookAccess() -> Bool { 
    switch ABAddressBookGetAuthorizationStatus() { 
    case .Authorized: 
     return true 
    case .NotDetermined: 
     var userDidAuthorize: Bool! 
     ABAddressBookRequestAccessWithCompletion(nil) { (granted: Bool, error: CFError!) in 
      if granted { 
       userDidAuthorize = true 
      } else { 
       userDidAuthorize = false 
      } 
     } 
     return userDidAuthorize 
    case .Restricted: 
     return false 
    case .Denied: 
     return false 
    } 
} 

Проблема заключается в том, что, когда кнопка прослушиваются, разрешение на доступ настройки предупреждений на короткое время отображается в то время как в фоновом режиме вид выполняет SEGUE до того, как пользователь либо разрешен или запрещен доступ в предупреждение. Затем приложение сразу же падает, заявив, что .NotDetermined вернуло nil, что означает, что переменная userDidAuthorize вернулась, прежде чем пользователь сможет сделать выбор, чтобы установить userDidAuthorize в блок if/else в ABAddressBookRequestAccessWithCompletion(nil).

Мой вопрос: почему код выполняет return в случае .NotDetermined до того, как пользователь установит переменную userDidAuthorize, чтобы вернуть правильный bool через подсказку? Я видел некоторые хаки, чтобы завершить выполнение с задержкой по времени, и я знаю, что эта функциональность устарела. Как я могу заставить это работать правильно?

ответ

0

Потому что ABAddressBookRequestAccessWithCompletion является асинхронным и немедленно возвращается. Он должен быть таким, как это обычно используется из основного потока и не может блокироваться, пока пользователь запрашивает разрешение.

Вам необходимо изменить способ использования этого, чтобы принять это, вызвав блок завершения со статусом, как только вы его знаете, а не сразу возвратите его.