Strong password overlay on UITextField

更新到iOS14.2後自動建議密碼擋住TextField了啦!

--

從遠百信義A13往Apple旗艦店拍的視角-這天在遠百信義A13逛逛,晚上在遠百信義A13美食街吃晚餐的時候突然大停電,慶幸自己沒在電梯裡。

2020/12/25更新

這個問題在iOS14.3/Xcode12.3已經解決囉!不用再寫這麼多行了!

— — —

以下為2020/11/12的發文

好久沒發文,最近iOS更新到iOS14.2,公司立刻接到客戶的哀號,我們的金融App登入時輸入密碼的地方變得怪怪的,出現幾種狀況:

1.輸入密碼的欄位無法切換英數字鍵盤。

切換成英文的小地球不見了

2.鍵盤處直接一片空白。

鍵盤消失了

3.被Strong Password覆蓋TextField欄位造成無法輸入。

Strong Password擋住了TextField無法自行輸入

Google爬文發現郵局的App也有這個問題。

郵局的App也有同樣的狀況(非我任職公司的app)

測試了一下公司的app,發現是只要有寫textField.isSecureTextEntry = true 讓輸入文字變成隱碼的地方就會出現上列三種狀況。

以往的自動建議密碼是一隻鑰匙的圖示。

iOS13台灣銀行的登入畫面

升級至iOS14.2後自動建議密碼變成這樣。

點選密碼輸入欄位顯示此訊息

奇怪的是上圖訊息只跳出一下下,並非每次點選密碼的TextField欄位都會出現,然後鍵盤處就變成一片空白了。

Enabling Password AutoFill on a Text Input View似乎是iOS12之後才出現的功能,爬文看到當初iOS11升級到iOS12時也是有出現問題。

但這次iOS14.2我認為是自動高強度密碼的訊息擋住了鍵盤但又無法正常顯示訊息才造成一片空白,總之Strong Password與有寫secureTextEntry的TextField發生了衝突,所以要避免上述的狀況,必須先關閉Strong Password的功能。

設定->密碼與帳號->自動填寫密碼

其實只要關閉自動填寫密碼功能就可以解決了,但是有些懶得想密碼的人(例如我)又很依賴這個功能,要如何不關閉這個功能但又能讓密碼正常輸入呢?

於是乎我又想到要從程式裡去關閉自動填寫密碼的功能了,邊研究邊爬文了兩天,終於在stackoverflow挖掘到一個方法。

這個文章也是iOS11升級到iOS12時大家針對自動填寫密碼的問題討論,我發現到可以用繞過自動填寫密碼的方法去避免被Strong Password覆蓋TextField欄位的問題,我在文章中看到了關鍵字:Way Around to bypass Auto-fill Suggestion. 可以用TextField Delegate裡面的textField(_:shouldChangeCharactersIn:replacementString:) 方法去繞過自動填充密碼。

關鍵字Way Around to bypass Auto-fill Suggestion.

原本造成密碼輸入欄位有問題的程式碼如下:

改寫成這樣:

關鍵在於這一段:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {if (textField == userNo && !userNo.isSecureTextEntry) {
userNo.isSecureTextEntry = true
}
if (textField == password && !password.isSecureTextEntry) {
password.isSecureTextEntry = true
}
return true
}

判斷需要用到隱碼的TextField再去寫入isSecureTextEntry = true即可繞過自動填入密碼的Strong Password,避免輸入密碼的欄位異常的問題。

上面的程式碼是用來測試的,回頭寫在公司的app也成功解決問題了!

明天可以跟客戶交差了覺得開心:)。

2020/11/15更新

隔天仔細測試過後,發現上述方法還是有bug(崩潰~~~)

還以為正常依序輸入身分證、帳號、密碼後就沒事了,結果!打太快不小心打錯密碼(常有的事吧?!)跳出Alert訊息顯示密碼錯誤請重新輸入後,再點擊密碼欄位要修改的時候,又出現了:

Strong Password擋住了TextField無法自行輸入

原來是因為這段:

if (textField == userNo && !userNo.isSecureTextEntry) {
userNo.isSecureTextEntry = true
}

secure text entry已經設定為true了啊又啟動了AutoFill的Strong Password,所以無法重複修改編輯,有想過輸入完畢在EndEditing或是ShouldReturn的TextFieldDelegate裡面再設定secure text entry為false,可是這樣剛剛輸入的隱碼全又變成明碼了(鬼打牆?!),本來高高興興的以為自己解決了問題還跟同事分享,沒想到只解決一半而已(哭),把這壞消息跟同事說之後,跟同事一起研究該怎麼對付這個魔王,結果前輩不愧是前輩啊終於想出辦法了。

總覺得這個方法不是最好的辦法,但至少先解決了目前的問題:

這個方法的構想是,先將TextField的輸入值存在變數中以供後續使用,然後再設定secure text entry為false去關閉AutoFill的Strong Password功能後以”●”符號取代隱碼,讓TextField的欄位就好像還是隱碼一樣(騙騙大家眼睛),然後每次點選TextField的欄位把障眼法”●”清空再重新輸入(反正你也不記得你打錯的密碼是哪個字了吧?!)這樣TextField的欄位就不會再被AutoFill的Strong Password遮住了。

就是這樣啦,希望Apple官方快點解決這個問題,附上stackoverflow別人家的發問,跟我遇到一樣的問題但似乎還沒有解決,放在這看看之後有沒有人有更好的辦法(拉板凳的概念)。

如果有看到文章的大家有更好的做法也請不吝嗇與我討論喲,感謝大家。

--

--

Julia Wang
彼得潘的 Swift iOS / Flutter App 開發教室

Learning Programming , Hiking , Travels , Tour , Exploring nature 『你必須要很努力,才能看起來毫不費力』