Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ios

swift

iphone

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.

like image 442
Lifeplus Avatar asked Oct 08 '19 12:10

Lifeplus


1 Answers

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:

keyboard no longer shown

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:

usingSharedWebCredential

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.

like image 63
Stephan Schlecht Avatar answered Nov 06 '22 20:11

Stephan Schlecht