Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios SecRequestSharedWebCredential凭据包含';未保存密码';?_Ios_Objective C_Keychain - Fatal编程技术网

Ios SecRequestSharedWebCredential凭据包含';未保存密码';?

Ios SecRequestSharedWebCredential凭据包含';未保存密码';?,ios,objective-c,keychain,Ios,Objective C,Keychain,我们通过函数检索任何保存的密码: SecRequestSharedWebCredential(NULL, NULL, ^(CFArrayRef credentials, CFErrorRef error) { if (!error && CFArrayGetCount(credentials)) { CFDictionaryRef credential = CFArrayGetValueAtIndex(credentials, 0); if

我们通过函数检索任何保存的密码:

SecRequestSharedWebCredential(NULL, NULL, ^(CFArrayRef credentials, CFErrorRef error) {
    if (!error && CFArrayGetCount(credentials)) {
        CFDictionaryRef credential = CFArrayGetValueAtIndex(credentials, 0);
        if (credential > 0) {
            CFDictionaryRef credential = CFArrayGetValueAtIndex(credentials, 0);
            NSString *username = CFDictionaryGetValue(credential, kSecAttrAccount);
            NSString *password = CFDictionaryGetValue(credential, kSecSharedPassword);
            dispatch_async(dispatch_get_main_queue(), ^{
                //Updates the UI here.
            });
        }
    }
});
问题在于,在IOS 9.3.3 iPhone 6 A1524上,我们会得到一个名为“密码未保存”的提示。没有错误消息表明未找到密码。因为数组>0,所以它使用条目完成表单

为什么会这样?我们认为,如果您的授权域下没有存储密码,则不会出现提示

有什么建议吗


谢谢。

我正在我的Auth view控制器的
viewDidLoad()
中检查这一点。代码与上面的稍有不同,是从其他几个SO答案中收集到的

Swift 3:

SecRequestSharedWebCredential(Configuration.webBaseFQDN作为CFString,nil,{(凭证,错误)在
如果let error=error{
打印(“错误:凭证”)
打印(错误)
}
guard let credentials=凭据,CFArrayGetCount(凭据)>0其他{
//找不到共享的web凭据。
返回
}
guard CFArrayGetCount(凭证)=1{
//应该只有一个凭证。
返回
}
let Unfectredential=CFArrayGetValueAtIndex(凭据,0)
let credential=unsafeBitCast(unsecfectedential,to:CFDictionary.self)
让unsafeEmail=CFDictionaryGetValue(凭证,非托管.passUnretained(kSecAttrAccount).toOpaque())
让email=unsafeBitCast(unsafeEmail,to:CFString.self)作为字符串
让unsafePassword=CFDictionaryGetValue(凭证,非托管.passUnretained(kSecSharedPassword).toOpaque())
让password=unsafeBitCast(unsafePassword,to:CFString.self)作为字符串
如果self.isValidEmail(电子邮件)和self.isValidPassword(密码){
self.usedSharedWebCredentials=true
self.doSignIn(电子邮件:电子邮件,密码:密码)
}
})
最后对
isValidEmail(:)
isValidPassword(:)
的额外检查处理
SecRequeestSharedWebCredential()
在第一个凭证(电子邮件)中返回“密码未保存”的情况

希望有人能解释为什么会发生这种情况,但如果没有,至少有一种方法可以阻止这种情况


我还想补充一点,我在iOS 10.2.1之前就看到过这个问题,我遇到了同样的问题,我想补充一点,“密码未保存”中的空格不是真正的空格。不知道为什么,从
CFString
转换时可能会出现一些奇怪的情况

无论哪种方式,由于仍然在ObjC中,而且他们的安全框架仍然非常重于CoreFoundation,所以我想发布我为共享Web凭据包装器编写的全部Swift 5代码会很好

它有很好的错误管理逻辑(可以调整,因为您可能没有相同的ErrorBuilderAPI)。关于奇怪的空格,当从Xcode复制到StackOverflow时,它们会变成实空格,因此字符串扩展中有额外的逻辑

从我所看到的来看,网上没有比这更好的了

//
//斯威夫特
//由阿尔贝托·德·博尔托利于2019年7月26日创作。
//
进口基金会
公共类型别名用户名=字符串
公共类型别名密码=字符串
公共结构凭据{
公共let用户名:username
公共let密码:密码
}
公共枚举GetCredentialsResult{
案例成功(证书)
案件取消
案例失败(错误)
}
公共枚举SaveCredentialsResult{
案例成功
案例失败(错误)
}
协议证书存储库{
func getCredentials(完成:@escaping(GetCredentialsResult)->Void)
func saveCredentials(credentials:credentials,completion:@escaping(SaveCredentialsResult)->Void)
}
//
//SharedWebCredentialsController.swift
//由阿尔贝托·德·博尔托利于2019年7月26日创作。
//
类SharedWebCredentialsController{
let域:字符串
初始化(域:字符串){
self.domain=域
}
}
扩展SharedWebCredentialsController:CredentialsRepository{
func getCredentials(完成:@escaping(GetCredentialsResult)->Void){
SecRequestSharedWebCredential(域为CFString,.none){cfArrayCredentials,cfError in
开关(cfArrayCredentials,cfError){
case(u,.some(let cfError)):
将UnderlineError=NSError(域:CFErrorGetDomain(cfError))设为字符串,
代码:CFErrorGetCode(cfError),
用户信息:(CFErrorCopyUserInfo(cfError)作为字典)
let error=ErrorBuilder.error(用于代码:.sharedWebCredentialsFetchFailure,underyingError:underyingError)
DispatchQueue.main.async{
完成(.failure(error))
}
案例(.some(让cfArrayCredentials)为:
如果让credentials=cfArrayCredentials为?[[String:String]],credentials.count>0,
让entry=credentials.first,
//let domain=entry[kSecAttrServer作为字符串]
让username=entry[kSecAttrAccount as String],
let password=entry[kSecSharedPassword作为字符串]{
DispatchQueue.main.async{
如果username.isValidUsername(){
完成(.success(凭据(用户名:用户名,密码:密码)))
}
否则{
let error=ErrorBuilder.error(用于代码:.sharedWebCredentialsFetchFailure,UnderlineError:nil)
完成(.failure(error))
}
}
}
否则{
DispatchQueue.main.async{
完成(已取消)
}
}
案例(.none,.none):
DispatchQueue.main.async{
有限公司