“Would you like to save this password ” dialog blocks keyboard from appearing

别等时光非礼了梦想. 提交于 2021-02-07 12:52:52

问题


I have problem with "Would you like to save this password" dialog. When it pop-up and user go to home screen and back to app, dialog disappears and he is not able to raise keyboard when to touch in to textfield. Its only "working" like this on iOS 13. On iOS 12 it is working OK, because when user come back to app, dialog is still there. Then he can save password or tap not now and start typing. Any ideas how to solve this? Its probably some kind of iOS 13 bug.


回答1:


Problem

As OP writes: if you have associated domains enabled, autofill feature is used in iOS 13, then you get a UIAlertController which asks you to save or update the password, see https://developer.apple.com/videos/play/wwdc2017/206/ for more information.

The problem with iOS 13 is that if the user puts applications in the background before tapping either the 'Update Password' or the 'Not Now' button, the keyboard for text fields is no longer shown after switching back to the foreground, see here:

Since it is a system dialog of the operating system you can't dismiss it programmatically before going background.

So until this is fixed by Apple one can either:

  • workaround with SecRequestSharedWebCredential / SecAddSharedWebCredential
  • or do without the feature
  • or ignore the edge case

Workaround

A workaround could be:

  • don't use new autofill on iOS 13
  • use SecRequestSharedWebCredential / SecAddSharedWebCredential instead

It could look like this then:

Don't use Autofill

So that the new autofill is not used, the textContentType should not be set, therefore no:

userTextField.textContentType = .username
passwordTextField.textContentType = .password

Also don't set isSecureTextEntry to true. This means in practice that you need your own mechanism, to hide the entry for the password textfield. For suggestions see e.g. iOS 11 disable password autofill accessory view option?

SecRequestSharedWebCredential

On the login page one could use in viewDidLoad:

if #available(iOS 13, *) {
    requestCredentials()
} else {
    userTextField.textContentType = .username
    passwordTextField.textContentType = .password
}

private func requestCredentials() {
    SecRequestSharedWebCredential("software7.com" as CFString, nil, {
        credentials, error -> Void in
        guard error == nil else { return }
        guard let credentials = credentials, CFArrayGetCount(credentials) > 0 else { return }
        let unsafeCredential = CFArrayGetValueAtIndex(credentials, 0)
        let credential: CFDictionary = unsafeBitCast(unsafeCredential, to: CFDictionary.self)
        let dict: Dictionary<String, String> = credential as! Dictionary<String, String>
        let username = dict[kSecAttrAccount as String]
        let password = dict[kSecSharedPassword as String]

        DispatchQueue.main.async {
            self.userTextField.text = username;
            self.passwordTextField.text = password;
        }
    });
}

SecAddSharedWebCredential

In viewDidLoad of the second ViewController one could use:

if #available(iOS 13, *) {
    updateCredentials()
} else {
    //works automatically with autofill
}

private func updateCredentials() {
    SecAddSharedWebCredential("software7.com" as NSString as CFString,
                              self.userName as NSString as CFString,
                              self.password as NSString as CFString,
                              { error in if let error = error { print("error: \(error)") }
    })
}

This doesn't look as good as the autofill feature of iOS 13, but they allow you to continue using the keyboard when the user goes bg/fg by still offering autofill and shared credentials. Once the bug is fixed, this workaround can be removed.




回答2:


// If you need to show another view controller before saving the password
// you can simply zero out the content, save it inside the controller and
// restore it when it is displayed again
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.loginTextField.text = self.login;
    self.passwordTextField.text = self.password;
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    self.login = self.loginTextField.text;
    self.password = self.passwordTextField.text;
    self.loginTextField.text = nil;
    self.passwordTextField.text = nil;
}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    // System dialog "Save password...?" showed after this point
    // if .text of textField with contentType password is not nil

    // for save password manually use SecAddSharedWebCredential
}


来源:https://stackoverflow.com/questions/58286486/would-you-like-to-save-this-password-dialog-blocks-keyboard-from-appearing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!