I am doing a registration page for me iOS app. I know that my server side code is fine. When the user has successfully signed in the alert that it triggers crashes my app. If i remove the alert then my app is fine (I know this because
i use the console to print out 'success'). Please can someone advise on why my alert causes this crash?
.....
let task = session.dataTask(with: request) { (data, response, error) in
// When request is complete, run code below
if let jsonData = data{
do{
let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
print("jsonObject: \(jsonObject)")
guard
let myArray = jsonObject as? [String:Any] else{
print("error-2")
return
}
if let status = myArray["status"] as? Int{
// Communication with server successful
if(status == 200){
// Registration successful
if let message = myArray["message"] as? String{
self.displayAlertMessage(msg: message)
}
}
}
}catch let error{
print("print error: \(error)")
}
}else if let requestError = error{
print("error detail: \(requestError)")
}else{
print("unexpected error")
}
}
task.resume()
My alert function
// General Alert message function
func displayAlertMessage(msg: String){
let alert = UIAlertController.init(title: "Alert", message: msg, preferredStyle: .alert)
let userAction = UIAlertAction.init(title: "OK", style: .destructive, handler: nil)
alert.addAction(userAction)
present(alert, animated: true, completion: nil)
}
CONSOLE:
[MobileAssetError:29] Unable to copy asset information from https://mesu.apple.com/assets/ for asset type com.apple.MobileAsset.TextInput.SpellChecker
url: https://www.myDomaincom/myFolder/myphpFile.php?userEmail=e#gm.com&firstname=Tim&lastname=t&userPassword=bab
jsonObject: {
email = "e#gm.com";
firstname = Tim;
lastname = t;
message = "Registration success";
status = 200;
userId = 32;
}
2017-04-29 12:33:57.042 lmyApp[60847:11563379] *** Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.6.21/Keyboard/UIKeyboardTaskQueue.m:432
2017-04-29 12:33:57.057 myApp[60847:11563379] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000109891d4b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000106ba421e objc_exception_throw + 48
2 CoreFoundation 0x0000000109895e42 +[NSException raise:format:arguments:] + 98
3 Foundation 0x000000010673966d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x0000000107bc4b65 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] + 165
5 UIKit 0x0000000107335441 -[UIKeyboardImpl setDelegate:force:] + 1404
6 UIKit 0x0000000107755dde -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 981
7 UIKit 0x000000010775f5f8 -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 498
8 UIKit 0x0000000107227543 -[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:] + 1178
9 UIKit 0x000000010722928e -[UIViewController _presentViewController:withAnimationController:completion:] + 4971
10 UIKit 0x000000010722c26b -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 530
11 UIKit 0x000000010722bd51 -[UIViewController presentViewController:animated:completion:] + 179
12 lifesci-PubMed 0x00000001065b3fd2 _TFC14lifesci_PubMed22RegisterViewController19displayAlertMessagefT3msgSS_T_ + 834
13 lifesci-PubMed 0x00000001065b3378 _TFFC14lifesci_PubMed22RegisterViewController24submitRegistrationTappedFP_T_U_FTGSqV10Foundation4Data_GSqCSo11URLResponse_GSqPs5Error___T_ + 2088
14 lifesci-PubMed 0x00000001065b3bcb _TTRXFo_oGSqV10Foundation4Data_oGSqCSo11URLResponse_oGSqPs5Error____XFdCb_dGSqCSo6NSData_dGSqS1__dGSqCSo7NSError___ + 203
15 CFNetwork 0x0000000109cafccc __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 19
16 CFNetwork 0x0000000109caf578 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 308
17 Foundation 0x00000001066a69ad __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
18 Foundation 0x00000001066a668f -[NSBlockOperation main] + 101
19 Foundation 0x00000001066a4d8c -[__NSOperationInternal _start:] + 672
20 Foundation 0x00000001066a0ccf __NSOQSchedule_f + 201
21 libdispatch.dylib 0x000000010a7f50cd _dispatch_client_callout + 8
22 libdispatch.dylib 0x000000010a7d2e17 _dispatch_queue_serial_drain + 236
23 libdispatch.dylib 0x000000010a7d3b4b _dispatch_queue_invoke + 1073
24 libdispatch.dylib 0x000000010a7d6385 _dispatch_root_queue_drain + 720
25 libdispatch.dylib 0x000000010a7d6059 _dispatch_worker_thread3 + 123
26 libsystem_pthread.dylib 0x000000010aba4712 _pthread_wqthread + 1299
27 libsystem_pthread.dylib 0x000000010aba41ed start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Read the error reason, it implies the solution:
... may only be called from the main thread
DispatchQueue.main.async {
self.displayAlertMessage(msg: message)
}
[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.
Ans : thread that was not the main thread (from a callback in a network request). The solution is to dispatch your calls to present the view controllers to the main thread.present your alert in main thread,
DispatchQueue.main.async(execute: {() -> Void in
//Code that presents or dismisses a view controller here
self.present(alert, animated: true, completion: nil)
})
or else update your view in main thread in here
if let message = myArray["message"] as? String{
DispatchQueue.main.async(execute: {() -> Void in
//Code that presents or dismisses a view controller here
self.displayAlertMessage(msg: message)
})
}
First of all, you should display your alert message on main thread.
Also, it might be useful to capture a weak reference to your controller.
final class SomeController: UIViewController {
func sendRequest() {
let message = "your message"
DispatchQueue.main.async { [weak self] in
self?.displayAlertMessage(msg: message)
}
}
func displayAlertMessage(msg: String){
// present
}
}
Related
I have the user already Signed in Anonymously in my app through the following code:
Auth.auth().signInAnonymously { (result, error) in
if let error = error {
Auth.auth().handleFireAuthError(error: error, vc: self)
debugPrint(error)
}
}
Then at one point I require the user to sign up and I am using the following code to link the Anonymous account to a permanent account:
guard let email = userEmailTextField.text, email.isNotEmpty,
let password = userPasswordTextField.text, password.isNotEmpty else {
simpleAlert(title: "Error", msg: "Please fill out all fields.")
return
}
guard let confirmPass = userRepeatPasswordTextField.text , confirmPass == password else{
simpleAlert(title: "Error", msg: "Passwords do not match.")
return
}
guard let authUser = Auth.auth().currentUser else {
return
}
let credential = EmailAuthProvider.credential(withEmail: email, link: password)
authUser.link(with: credential) { (result, error) in
if let error = error {
debugPrint(error)
Auth.auth().handleFireAuthError(error: error, vc: self)
self.activityIndicator.stopAnimating()
return
}
guard let fireUser = result?.user else {return}
let artUser = User.init(id: fireUser.uid, email: email , stripeId:"")
//Upload to Firestore
self.createFirestoreUser(user: artUser)
}
But I get an error here. I put break point and this is where the execution stop authUser.link(with: credential) { (result, error) in
This is the error I am getting:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSURLComponents initWithString:]: nil URLString parameter'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23e39f0e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50ad79b2 objc_exception_throw + 48
2 Foundation 0x00007fff259659ca -[__NSConcreteURLComponents URL] + 0
3 Foundation 0x00007fff259673a8 +[NSURLComponents componentsWithString:] + 33
4 Silobee 0x000000010b144c52 +[FIRAuthWebUtils parseURL:] + 98
5 Silobee 0x000000010b16c638 __56-[FIRUser linkAndRetrieveDataWithCredential:completion:]_block_invoke_3 + 440
6 Silobee 0x000000010b16b084 __51-[FIRUser internalGetTokenForcingRefresh:callback:]_block_invoke + 340
7 Silobee 0x000000010b15df8c __65-[FIRSecureTokenService fetchAccessTokenForcingRefresh:callback:]_block_invoke + 156
8 Silobee 0x000000010b13fa7b __38-[FIRAuthSerialTaskQueue enqueueTask:]_block_invoke + 155
9 libdispatch.dylib 0x0000000110850f11 _dispatch_call_block_and_release + 12
10 libdispatch.dylib 0x0000000110851e8e _dispatch_client_callout + 8
11 libdispatch.dylib 0x00000001108586fd _dispatch_lane_serial_drain + 788
12 libdispatch.dylib 0x00000001108592c5 _dispatch_lane_invoke + 476
13 libdispatch.dylib 0x000000011085851c _dispatch_lane_serial_drain + 307
14 libdispatch.dylib 0x000000011085928f _dispatch_lane_invoke + 422
15 libdispatch.dylib 0x0000000110864b65 _dispatch_workloop_worker_thread + 719
16 libsystem_pthread.dylib 0x00007fff51b37a3d _pthread_wqthread + 290
17 libsystem_pthread.dylib 0x00007fff51b36b77 start_wqthread + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Just saw where my problem is! Instead of this:
let credential = EmailAuthProvider.credential(withEmail: email, link: password)
I had to write this:
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
One small details and stoped my code from working
I am building a UI to request access to CNContactStore and handle the case where a user has previously (and probably erroneously) denied access. When I detect that the current status is .denied, I present a UIAlertController that explains and offers to take them to the app Settings to allow access.
When store.requestAccess() is called while the current status is .denied, the app crashes and shows two errors: 1) "A promise was finished with a nil error." and 2) "A promise was finished incorrectly.". The call stacks are shown below.
I'm not adept at interpreting the call stacks but I think the error is coming from inside CNContactStore. It's not clear to me what I can do to prevent this error.
EDIT: I am not using promise chaining in my app at all.
EDIT2: Clarified above exactly where in my code the error occurs.
import UIKit
import Contacts
import ContactsUI
final class ContactsAppHelper {
static let shared = ContactsAppHelper()
var store = CNContactStore()
func checkAccessStatus(_ completionHandler: #escaping (_ accessGranted: Bool) -> Void) {
let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
switch authorizationStatus {
case .authorized:
completionHandler(true)
case .denied, .notDetermined:
store.requestAccess(for: .contacts, completionHandler: { (access, accessError) -> Void in
if access {
completionHandler(access)
}
else {
print("access denied")
DispatchQueue.main.sync {
self.showSettingsAlert(completionHandler)
}
}
})
default:
completionHandler(false)
}
}
private func showSettingsAlert(_ completionHandler: #escaping (_ accessGranted: Bool) -> Void) {
let msg = "This app requires access to Contacts to proceed. Would you like to open settings and grant permission?"
let alert = UIAlertController(title: nil, message: msg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in
completionHandler(false)
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
completionHandler(false)
})
let vc = UIApplication.getPresentedViewController()
vc!.present(alert, animated: true)
}
}
extension UIApplication{
class func getPresentedViewController() -> UIViewController? {
var presentViewController = UIApplication.shared.keyWindow?.rootViewController
while let pVC = presentViewController?.presentedViewController
{
presentViewController = pVC
}
return presentViewController
}
}
These are the call stacks that result:
2019-06-14 15:59:12.220116-0700 Sales Networker[805:28798] [Rx] A promise was finished with a nil error.
2019-06-14 15:59:12.226500-0700 Sales Networker[805:28798] [Rx] Call stack: (
0 ContactsFoundation 0x000000012242312a -[CNFuture finishWithError:] + 52
1 Contacts 0x000000010e0c2a82 __55-[CNDataMapperContactStore requestAccessForEntityType:]_block_invoke_2 + 187
2 Contacts 0x000000010e0ffc71 +[CNAuthorization requestAccessForEntityType:completionHandler:] + 77
3 Contacts 0x000000010e072c44 -[CNXPCDataMapper requestAccessForEntityType:completionHandler:] + 123
4 Contacts 0x000000010e0c299a __55-[CNDataMapperContactStore requestAccessForEntityType:]_block_invoke + 174
5 libsystem_trace.dylib 0x000000011269cf00 os_activity_apply_f + 66
6 Contacts 0x000000010e116d52 -[_CNContactsLogger requestingAccessForContacts:] + 225
7 Contacts 0x000000010e0c28a4 -[CNDataMapperContactStore requestAccessForEntityType:] + 177
8 Contacts 0x000000010e09b77f -[CNContactStore requestAccessForEntityType:completionHandler:] + 54
9 Sales Networker 0x000000010ccaadc7 $s15Sales_Networker17ContactsAppHelperC17checkAccessStatusyyySbcF + 535
10 Sales Networker 0x000000010cce9673 $s15Sales_Networker24OnBoardingViewControllerC17rightButtonTappedyySo8UIButtonCF + 451
11 Sales Networker 0x000000010cce9ddc $s15Sales_Networker24OnBoardingViewControllerC17rightButtonTappedyySo8UIButtonCFTo + 60
12 UIKitCore 0x0000000119c7d204 -[UIApplication sendAction:to:from:forEvent:] + 83
13 UIKitCore 0x00000001196d2c19 -[UIControl sendAction:to:forEvent:] + 67
14 UIKitCore 0x00000001196d2f36 -[UIControl _sendActionsForEvents:withEvent:] + 450
15 UIKitCore 0x00000001196d1eec -[UIControl touchesEnded:withEvent:] + 583
16 UIKitCore 0x0000000119cb5eee -[UIWindow _sendTouchesForEvent:] + 2547
17 UIKitCore 0x0000000119cb75d2 -[UIWindow sendEvent:] + 4079
18 UIKitCore 0x0000000119c95d16 -[UIApplication sendEvent:] + 356
19 UIKitCore 0x0000000119d66293 __dispatchPreprocessedEventFromEventQueue + 3232
20 UIKitCore 0x0000000119d68bb9 __handleEventQueueInternal + 5911
21 CoreFoundation 0x000000010ebd6be1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
22 CoreFoundation 0x000000010ebd6463 __CFRunLoopDoSources0 + 243
23 CoreFoundation 0x000000010ebd0b1f __CFRunLoopRun + 1231
24 CoreFoundation 0x000000010ebd0302 CFRunLoopRunSpecific + 626
25 GraphicsServices 0x0000000114a702fe GSEventRunModal + 65
26 UIKitCore 0x0000000119c7bba2 UIApplicationMain + 140
27 Sales Networker 0x000000010cca7f6b main + 75
28 libdyld.dylib 0x0000000112416541 start + 1
)
2019-06-14 15:59:12.236494-0700 Sales Networker[805:28798] [Rx] A promise was finished incorrectly.
2019-06-14 15:59:12.236582-0700 Sales Networker[805:28798] [Rx] Result: (null)
2019-06-14 15:59:12.236669-0700 Sales Networker[805:28798] [Rx] Error : (null)
2019-06-14 15:59:12.238150-0700 Sales Networker[805:28798] [Rx] Call stack: (
0 ContactsFoundation 0x0000000122422ed8 -[CNFuture finishWithResult:error:] + 290
1 Contacts 0x000000010e0c2a82 __55-[CNDataMapperContactStore requestAccessForEntityType:]_block_invoke_2 + 187
2 Contacts 0x000000010e0ffc71 +[CNAuthorization requestAccessForEntityType:completionHandler:] + 77
3 Contacts 0x000000010e072c44 -[CNXPCDataMapper requestAccessForEntityType:completionHandler:] + 123
4 Contacts 0x000000010e0c299a __55-[CNDataMapperContactStore requestAccessForEntityType:]_block_invoke + 174
5 libsystem_trace.dylib 0x000000011269cf00 os_activity_apply_f + 66
6 Contacts 0x000000010e116d52 -[_CNContactsLogger requestingAccessForContacts:] + 225
7 Contacts 0x000000010e0c28a4 -[CNDataMapperContactStore requestAccessForEntityType:] + 177
8 Contacts 0x000000010e09b77f -[CNContactStore requestAccessForEntityType:completionHandler:] + 54
9 Sales Networker 0x000000010ccaadc7 $s15Sales_Networker17ContactsAppHelperC17checkAccessStatusyyySbcF + 535
10 Sales Networker 0x000000010cce9673 $s15Sales_Networker24OnBoardingViewControllerC17rightButtonTappedyySo8UIButtonCF + 451
11 Sales Networker 0x000000010cce9ddc $s15Sales_Networker24OnBoardingViewControllerC17rightButtonTappedyySo8UIButtonCFTo + 60
12 UIKitCore 0x0000000119c7d204 -[UIApplication sendAction:to:from:forEvent:] + 83
13 UIKitCore 0x00000001196d2c19 -[UIControl sendAction:to:forEvent:] + 67
14 UIKitCore 0x00000001196d2f36 -[UIControl _sendActionsForEvents:withEvent:] + 450
15 UIKitCore 0x00000001196d1eec -[UIControl touchesEnded:withEvent:] + 583
16 UIKitCore 0x0000000119cb5eee -[UIWindow _sendTouchesForEvent:] + 2547
17 UIKitCore 0x0000000119cb75d2 -[UIWindow sendEvent:] + 4079
18 UIKitCore 0x0000000119c95d16 -[UIApplication sendEvent:] + 356
19 UIKitCore 0x0000000119d66293 __dispatchPreprocessedEventFromEventQueue + 3232
20 UIKitCore 0x0000000119d68bb9 __handleEventQueueInternal + 5911
21 CoreFoundation 0x000000010ebd6be1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
22 CoreFoundation 0x000000010ebd6463 __CFRunLoopDoSources0 + 243
23 CoreFoundation 0x000000010ebd0b1f __CFRunLoopRun + 1231
24 CoreFoundation 0x000000010ebd0302 CFRunLoopRunSpecific + 626
25 GraphicsServices 0x0000000114a702fe GSEventRunModal + 65
26 UIKitCore 0x0000000119c7bba2 UIApplicationMain + 140
27 Sales Networker 0x000000010cca7f6b main + 75
28 libdyld.dylib 0x0000000112416541 start + 1
)
I tested your code and found that there are two things happening here.
The first is that when you call requestAccess(for:completion:) when the status is already .denied, you get a non-fatal stack trace on the console. You can either ignore this or only request access in the case of a .notDetermined status.
The second problem is related to the synchronous dispatch on the main queue. That causes an access violation for some reason. The solution is to use an asynchronous dispatch. There is no good reason to block the calling queue anyway.
func checkAccessStatus(_ completionHandler: #escaping (_ accessGranted: Bool) -> Void) {
let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
switch authorizationStatus {
case .authorized:
completionHandler(true)
case .denied:
self.showSettingsAlert(completionHandler)
case .notDetermined:
store.requestAccess(for: .contacts, completionHandler: { (access, accessError) -> Void in
if access {
completionHandler(access)
}
else {
print("access denied")
self.showSettingsAlert(completionHandler)
}
})
default:
completionHandler(false)
}
}
private func showSettingsAlert(_ completionHandler: #escaping (_ accessGranted: Bool) -> Void) {
let msg = "This app requires access to Contacts to proceed. Would you like to open settings and grant permission?"
let alert = UIAlertController(title: nil, message: msg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in
completionHandler(false)
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
completionHandler(false)
})
DispatchQueue.main.async {
if let vc = UIApplication.getPresentedViewController() {
vc.present(alert, animated: true)
} else {
completionHandler(false)
}
}
}
This error will come in two cases.
When you ask for contact permission to user and user Denied it .
User given contact permission and later go into settings -> your app > off contact permission.
IN these two scenarios in logs you will see "A promise was finished with a nil error".
As per customer requirement, you can show permission denied alert or you can ignore it.
I am a bit new in the development of native apps for iOS. I am working on Swift 4 and when trying to move to another screen from my login, I am generating the following error:
BanGuayaPrototype[11289:1143773] -[BanGuayaPrototype.ViewController getTextId:]: unrecognized selector sent to instance 0x7fe5f69027d0 2018-01-10 14:40:06.213350-0500
BanGuayaPrototype[11289:1143773] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BanGuayaPrototype.ViewController getTextId:]: unrecognized selector sent to instance 0x7fe5f69027d0'
* First throw call stack: (
0 CoreFoundation 0x000000010d42512b exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000108ce3f41 objc_exception_throw + 48
2 CoreFoundation 0x000000010d4a6024 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 UIKit 0x0000000109a52f51 -[UIResponder doesNotRecognizeSelector:] + 295
4 CoreFoundation 0x000000010d3a7f78 ___forwarding_ + 1432
5 CoreFoundation 0x000000010d3a7958 _CF_forwarding_prep_0 + 120
6 UIKit 0x0000000109820972 -[UIApplication sendAction:to:from:forEvent:] + 83
7 UIKit 0x000000010999fc3c -[UIControl sendAction:to:forEvent:] + 67
8 UIKit 0x000000010999ff59 -[UIControl _sendActionsForEvents:withEvent:] + 450
9 UIKit 0x000000010a548407 -[UITextField _resignFirstResponder] + 155
10 UIKit 0x0000000109a52939 -[UIResponder _finishResignFirstResponder] + 286
11 UIKit 0x000000010a548026 -[UITextField _finishResignFirstResponder] + 48
12 UIKit 0x0000000109a529e8 -[UIResponder resignFirstResponder] + 140
13 UIKit 0x000000010a547ef6 -[UITextField resignFirstResponder] + 135
14 UIKit 0x00000001098d6463 -[UIView(Hierarchy) _removeFirstResponderFromSubtree] + 167
15 UIKit 0x00000001098d6a73 UIViewWillBeRemovedFromSuperview + 72
16 UIKit 0x00000001098d685d -[UIView(Hierarchy) removeFromSuperview] + 95
17 UIKit 0x000000010999b591 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke.674 + 858
18 UIKit 0x0000000109994b5b -[UIPresentationController transitionDidFinish:] + 111
19 UIKit 0x0000000109c1cc1e -[_UICurrentContextPresentationController transitionDidFinish:] + 44
20 UIKit 0x0000000109998f4f __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 183
21 UIKit 0x000000010a58d088 -[_UIViewControllerTransitionContext completeTransition:] + 102
22 UIKit 0x0000000109991dba -[UITransitionView notifyDidCompleteTransition:] + 251
23 UIKit 0x0000000109991a31 -[UITransitionView _didCompleteTransition:] + 1397
24 UIKit 0x00000001099940c8 -[UITransitionView _transitionDidStop:finished:] + 104
25 UIKit 0x00000001098b56c4 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 343
26 UIKit 0x00000001098b5d23 -[UIViewAnimationState animationDidStop:finished:] + 293
27 UIKit 0x00000001098b5dd7 -[UIViewAnimationState animationDidStop:finished:] + 473
28 QuartzCore 0x00000001096696bd _ZN2CA5Layer23run_animation_callbacksEPv + 323
29 libdispatch.dylib 0x000000010e54733d _dispatch_client_callout + 8
30 libdispatch.dylib 0x000000010e5525f9 _dispatch_main_queue_callback_4CF + 628
31 CoreFoundation 0x000000010d3e7e39 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9
32 CoreFoundation 0x000000010d3ac462 __CFRunLoopRun + 2402
33 CoreFoundation 0x000000010d3ab889 CFRunLoopRunSpecific + 409
34 GraphicsServices 0x0000000110ff39c6 GSEventRunModal + 62
35 UIKit 0x000000010981f5d6 UIApplicationMain + 159
36 BanGuayaPrototype 0x00000001083a31d7 main + 55
37 libdyld.dylib 0x000000010e5c3d81 start + 1
38 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
Below are the classes involved:
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var getText: UITextField!
var cliente = Cliente()
#IBAction func onGoButtonLH(_ sender: Any) {
let idTxt:String? = getText.text
if idTxt == "1234" {
self.performSegue(withIdentifier: "LoginToComercial", sender: self)
}else{
let urlString = "http://localhost:8080/RestServiceBgPrototype/cognitiva/clientService/"+idTxt!
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else { return }
//Implement JSON decoding and parsing
do {
let decoder = JSONDecoder()
self.cliente = try! decoder.decode(Cliente.self, from: data)
OperationQueue.main.addOperation{
self.performSegue(withIdentifier: "LoginToHome", sender: self.cliente)
}
}
}.resume()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "LoginToHome") {
let homeViewController = segue.destination as? HomeViewController
let cliente = sender as! Cliente
homeViewController?.cliente = cliente
}
}
}
HomeViewController.swift
class HomeViewController: UIViewController {
#IBOutlet weak var userLabel: UILabel!
var cliente = Cliente()
override func viewDidLoad() {
super.viewDidLoad()
let nombreCliente:String = cliente.nombre
let fullNameArr = nombreCliente.components(separatedBy:(" "))
let nombre = fullNameArr[2]
let apellido = fullNameArr[0]
self.userLabel.text = "Hola, "+nombre.capitalized+" "+apellido.capitalized
}
}
Any idea why I get this error?
To debug crash while it's happening and inspect what is the reason.
You can do this:
In your Breakpoint navigator at the bottom click plus button and add exception breakpoint
That will add to your project all exception break point.
It means when ever your app crashes is will stop on a line which generate crash.
Then we can figure out what to do next.
However, you are using force unwrap a lot, for instance:
let cliente = sender as! Cliente
if error != nil {
print(error!.localizedDescription)
}
It's better to do like this
if let error = error {
print(error.localizedDescription)
}
Please try not to use !. In case if your application encounter nil instead of object program will crash.
To answer your question. Your application do crash trying to send message getTextId to an object of type BanGuayaPrototype.ViewController.
This selector is not recognised. That's the root of your crash.
How did that happen?
For now what I can think. You have an object:
let obj: BanGuayaPrototype
and what are you trying to do is to call a method getTextId on this object.
This type of error is common in ObjectiveC. Occurs when you can try to send message to an object. If given object are unable to handle message program is crashing.
I have 3 main VC (MyAccount, Register, Login). Then I have a Swift file(Manager.swift) where I set up a class function where after the registering or logging in it would dismiss the VC.
Manager.swift
class Manager {
class func registerUser(vc: UIViewController?, user_email : String, user_password : String){
let myUrl = NSURL(string: hostURL + "userRegister.php")
let request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST";
// Compose a query string
let postString = "user_email=\(user_email)&user_password=\(user_password)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil
{
print("error=\(error)")
return
}
// You can print out response object
print("response = \(response)")
// Print out response body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
//Let’s convert response sent from a server side script to a NSDictionary object:
let myJSON = try!NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
if let parseJSON = myJSON {
let status = parseJSON["status"] as? String
let msg = parseJSON["message"] as? String
print("Status: \(status)")
if(status != "Success")
{
UIAlert.displayAlert(vc, title: "Error", message: msg!, dismissTxt: "OK")
}
else{
defaults.setBool(true, forKey: "isLoggedIn")
//My Failed attempt to go back to Root :C
vc?.navigationController?.popToRootViewControllerAnimated(true)
}
}
}
task.resume()
}
}
RegisterVC
buttonPressed(sender: AnyObject) {
Manger.registerUser(self, user_email:username, user_password:password1234)
}
I used navigationController?.popToRootViewControllerAnimated in an attempt to back
It would work but sometimes the app would crash, spitting out this:
2015-10-02 14:51:01.410 Retail_Template[4551:261846] * Assertion failure in -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/Keyboard/UIKeyboardTaskQueue.m:378
2015-10-02 14:51:01.415 Retail_Template[4551:261846] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] may only be called from the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x009f8a94 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x02b26e02 objc_exception_throw + 50
2 CoreFoundation 0x009f892a +[NSException raise:format:arguments:] + 138
3 Foundation 0x010bd3e6 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118
4 UIKit 0x021f9d2e -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] + 180
5 UIKit 0x019e14f2 -[UIKeyboardImpl setDelegate:force:] + 703
6 UIKit 0x019e122e -[UIKeyboardImpl setDelegate:] + 60
7 UIKit 0x01ddd1d6 -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 1208
8 UIKit 0x01de6bef -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 502
9 UIKit 0x01de6c85 -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:] + 57
10 UIKit 0x0190dd0a -[UINavigationController navigationTransitionView:didStartTransition:] + 1029
11 UIKit 0x01903bf4 -[UINavigationController _startCustomTransition:] + 5104
12 UIKit 0x01913c0b -[UINavigationController _startDeferredTransitionIfNeeded:] + 801
13 UIKit 0x01914d05 -[UINavigationController __viewWillLayoutSubviews] + 68
14 UIKit 0x01aded9f -[UILayoutContainerView layoutSubviews] + 252
15 UIKit 0x017cb16b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 813
16 libobjc.A.dylib 0x02b3b059 -[NSObject performSelector:withObject:] + 70
17 QuartzCore 0x003ed60c -[CALayer layoutSublayers] + 144
18 QuartzCore 0x003e128e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 388
19 QuartzCore 0x003e10f2 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
20 QuartzCore 0x003d3c2b _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 317
21 QuartzCore 0x00407c23 _ZN2CA11Transaction6commitEv + 589
22 QuartzCore 0x00407fbd _ZN2CA11Transaction14release_threadEPv + 289
23 libsystem_pthread.dylib 0x04bc32f7 _pthread_tsd_cleanup + 93
24 libsystem_pthread.dylib 0x04bc3051 _pthread_exit + 108
25 libsystem_pthread.dylib 0x04bc3734 pthread_get_stackaddr_np + 0
26 libsystem_pthread.dylib 0x04bc0e0e start_wqthread + 30
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Not sure what I'm doing wrong here.
Any solution will be appreciated. Thanks!
As your error says:
may only be called from the main thread.
Your operation should be called into main thread. As shown into below code:
dispatch_async(dispatch_get_main_queue()) {
//Perform your task here.
}
I'm getting this error when Trying to share on facebook or twitter.
2015-04-12 17:49:42.208 TestShareApp[1069:30252] *** Assertion failure in -[UICGColor encodeWithCoder:], /SourceCache/UIKit_Sim/UIKit-3347.44/UIColor.m:1448
2015-04-12 17:49:42.359 TestShareApp[1069:30252] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only RGBA or White color spaces are supported in this situation.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110424c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010fce0bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000110424aca +[NSException raise:format:arguments:] + 106
3 Foundation 0x000000010f24298f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 UIKit 0x0000000110c8379a -[UIColor encodeWithCoder:] + 972
5 Foundation 0x000000010f1f13e5 _encodeObject + 1120
6 Foundation 0x000000010f1f0c49 +[NSKeyedArchiver archivedDataWithRootObject:] + 162
7 UIKit 0x0000000110f842f7 -[_UIAppearanceRecorder _recordInvocation:withClassName:containerClassNames:traitCollection:selectorString:forRemoteProcess:] + 1915
8 UIKit 0x0000000110f7ef5d __54+[_UIAppearance _recordersExcludingSource:withWindow:]_block_invoke + 907
9 CoreFoundation 0x0000000110364656 __65-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 102
10 CoreFoundation 0x000000011036455c -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 204
11 UIKit 0x0000000110f7ebc0 +[_UIAppearance _recordersExcludingSource:withWindow:] + 137
12 UIKit 0x000000011114897d UIViewServiceCurrentAppearanceSerializedRepresentations + 77
13 UIKit 0x000000011103bcc9 +[_UIRemoteViewController _requestViewController:traitCollection:fromServiceWithBundleIdentifier:service:connectionHandler:] + 232
14 UIKit 0x000000011103bbaa +[_UIRemoteViewController requestViewControllerWithService:connectionHandler:] + 91
15 UIKit 0x0000000110f13db8 __117-[NSExtension(UIViewControllerAdditions) instantiateViewControllerWithInputItems:listenerEndpoint:connectionHandler:]_block_invoke_2 + 621
16 libdispatch.dylib 0x000000011220e186 _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x000000011222d614 _dispatch_client_callout + 8
18 libdispatch.dylib 0x0000000112215a1c _dispatch_main_queue_callback_4CF + 1664
19 CoreFoundation 0x000000011038c1f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
20 CoreFoundation 0x000000011034ddcb __CFRunLoopRun + 2043
21 CoreFoundation 0x000000011034d366 CFRunLoopRunSpecific + 470
22 GraphicsServices 0x0000000113f81a3e GSEventRunModal + 161
23 UIKit 0x0000000110a4d900 UIApplicationMain + 1282
24 TestShareApp 0x000000010e38d457 main + 135
25 libdyld.dylib 0x0000000112261145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
and here is my facebook and twitter actionsheet code
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
if buttonIndex == 1 { // Facebook
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) {
var controller = SLComposeViewController(forServiceType:SLServiceTypeFacebook)
controller.setInitialText(shareText)
controller.addURL(NSURL(string: appUrl) )
self.presentViewController(controller, animated: true, completion: nil)
controller.completionHandler = { (result:SLComposeViewControllerResult) -> Void in
switch result {
case SLComposeViewControllerResult.Cancelled:
println("fb cancel")
case SLComposeViewControllerResult.Done:
println("done")
}
}
} else {
var alert = UIAlertView(title: "No Facebook Account", message: "Oops, you've not added facebook account in your iphone settings", delegate: self, cancelButtonTitle: "Okay")
alert.show()
}
} else if buttonIndex == 2 { // Twitter
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter) {
var controller = SLComposeViewController(forServiceType:SLServiceTypeTwitter)
controller.setInitialText(shareText)
controller.addURL(NSURL(string: appUrl) )
self.presentViewController(controller, animated: true, completion: nil)
controller.completionHandler = { (result:SLComposeViewControllerResult) -> Void in
switch result {
case SLComposeViewControllerResult.Cancelled:
println("fb cancel")
case SLComposeViewControllerResult.Done:
println("done")
}
}
} else {
var alert = UIAlertView(title: "No Twitter Account", message: "Oops! Looks like you've not added Twitter account in your settings", delegate: self, cancelButtonTitle: "Okay")
alert.show()
}
}
}
same code works fine on my other apps. Not sure why this is happeing when I click or either facebook or twitter.