#ios #swift
#iOS #swift
Вопрос:
Я использую Swift 2.3. И я создаю приложение, которое включает аутентификацию Firebase.
Прямо сейчас я хочу отправить resetpassword, а затем представить AlertController, заголовок и сообщение которого меняются в зависимости от введенного электронного письма. Я пытаюсь представить AlertController в ViewController при нажатии кнопки отправки:
@IBAction func sendButtonTapped(sender: UIButton) {
if txtEmail.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter an e-mail", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
} else {
FIRAuth.auth()?.sendPasswordResetWithEmail(txtEmail.text!, completion: { (error) in
var title = ""
var message = ""
if error != nil {
title = "Error"
message = (error?.localizedDescription)!
} else {
title = "Success!"
message = "Password reset email sent."
self.txtEmail.text = ""
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
})
}
}
И в результате поймали исключение. Попытался поставить точку останова, и все работает нормально, пока не дойдет до представления AlertController. В окне консоли у меня есть это:
2016-10-15 00:13:44.657 Doner[51377:4529688] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/Keyboard/UIKeyboardTaskQueue.m:386
2016-10-15 00:13:44.662 Doner[51377:4529688] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010b221d85 __exceptionPreprocess 165
1 libobjc.A.dylib 0x000000010d243deb objc_exception_throw 48
2 CoreFoundation 0x000000010b221bea [NSException raise:format:arguments:] 106
3 Foundation 0x000000010b673d5a -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] 198
4 UIKit 0x000000010c6c8a73 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] 165
5 UIKit 0x000000010bf36bc4 -[UIKeyboardImpl prepareForSelectionChange] 100
6 UIKit 0x000000010be0e149 -[UIFieldEditor setAttributedText:andSetCaretSelectionAfterText:] 146
7 UIKit 0x000000010be0de2c -[UIFieldEditor setText:andSetCaretSelectionAfterText:] 172
8 UIKit 0x000000010c693ece -[UITextField setText:] 344
9 Doner 0x000000010960fde4 _TFFC5Doner20ForgotViewController16sendButtonTappedFCSo8UIButtonT_U_FGSqCSo7NSError_T_ 772
10 Doner 0x000000010960c5a7 _TTRXFo_oGSqCSo7NSError__dT__XFo_iGSqS___iT__ 23
11 Doner 0x000000010960ed71 _TPA__TTRXFo_oGSqCSo7NSError__dT__XFo_iGSqS___iT__ 81
12 Doner 0x000000010960c5e0 _TTRXFo_iGSqCSo7NSError__iT__XFo_oGSqS___dT__ 32
13 Doner 0x000000010960c62c _TTRXFo_oGSqCSo7NSError__dT__XFdCb_dGSqS___dT__ 60
14 Doner 0x0000000109682964 __69-[FIRAuthBackendRPCImplementation postWithRequest:response:callback:]_block_invoke 944
15 Doner 0x0000000109765e78 __76-[GSDK_GTMSessionFetcher invokeFetchCallbacksOnCallbackQueueWithData:error:]_block_invoke 25
16 libdispatch.dylib 0x000000010dcb8d9d _dispatch_call_block_and_release 12
17 libdispatch.dylib 0x000000010dcd93eb _dispatch_client_callout 8
18 libdispatch.dylib 0x000000010dcbf82c _dispatch_queue_drain 2215
19 libdispatch.dylib 0x000000010dcbed4d _dispatch_queue_invoke 601
20 libdispatch.dylib 0x000000010dcc1996 _dispatch_root_queue_drain 1420
21 libdispatch.dylib 0x000000010dcc1405 _dispatch_worker_thread3 111
22 libsystem_pthread.dylib 0x000000010e02d4de _pthread_wqthread 1129
23 libsystem_pthread.dylib 0x000000010e02b341 start_wqthread 13
)
libc abi.dylib: terminating with uncaught exception of type NSException
Ответ №1:
Наиболее вероятно, что ваш аутентификационный вызов Firebase возвращается в потоке, который не является основным потоком. У меня были похожие проблемы со сторонними библиотеками, которые выполняют сетевые транзакции. Чтобы решить эту проблему, оберните свой код предупреждения отправкой в основной поток пользовательского интерфейса:
FIRAuth.auth()?.sendPasswordResetWithEmail(txtEmail.text!, completion: { (error) in
dispatch_async(dispatch_get_main_queue()) {
var title = ""
var message = ""
if error != nil {
title = "Error"
message = (error?.localizedDescription)!
} else {
title = "Success!"
message = "Password reset email sent."
self.txtEmail.text = ""
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
})