我有一个按钮,可以从用户的地址簿中导入联系人。当他们第一次点击按钮时,我的代码返回一个bool,指示用户是否已授予权限。如果授予了权限,则会导入联系人,然后执行segue到表视图。如果未授予权限,则不会导入联系人,并且我会对空表视图执行相同的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
返回,之后用户甚至可以选择在{/ 1}中设置userDidAuthorize
{ {1}}。
我的问题是为什么在用户设置变量ABAddressBookRequestAccessWithCompletion(nil)
以通过警报提示返回正确的bool之前,代码在return
的情况下执行.NotDetermined
?我已经看到一些黑客将时间延迟包裹在执行中,我知道这个功能已被弃用。我怎样才能让它正常工作?
答案 0 :(得分:0)
因为ABAddressBookRequestAccessWithCompletion
是异步的并且立即返回。它需要像这样,因为它通常在主线程中使用,并且在用户被要求许可时无法阻止。
你需要改变你使用它的方式来接受它,通过一旦你知道它就调用一个具有状态的完成块,而不是立即返回状态。