crisp-im / crisp-sdk-ios

:package: Crisp iOS SDK, add a chat in any iOS app and communicate with your users.
https://docs.crisp.chat/guides/chatbox-sdks/ios-sdk/
Other
44 stars 19 forks source link

ChatViewController cannot be used in an existing navigation #60

Closed StevenWatremez closed 1 year ago

StevenWatremez commented 3 years ago

Hi

I am planning to integrate your chat in my application. But I have a problem during my tests. I have a chat in my application that is on a specific tab inside a UITabController and I wanted to replace it with your chat. But as your ChatViewController is final I can't inherit it on a custom UIViewController. So I tried to push it into an existing UINavigationController to place it in my navigation, to simulate the tab with the chat inside, and I have a crash when I tried to push you ChatViewController. Have you an idea how to do this with your sdk. Have you a special ViewController for this ?

Fatal Exception: NSInvalidArgumentException

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'

Stacktrace

Thread 1 Queue : com.apple.main-thread (serial)
#0  0x00007fff6bf9e92e in __pthread_kill ()
#1  0x00007fff6bfee5bd in pthread_kill ()
#2  0x00007fff20107684 in abort ()
#3  0x00007fff202535c2 in abort_message ()
#4  0x00007fff2024476d in demangling_terminate_handler() ()
#5  0x00007fff20184c1b in _objc_terminate() ()
#6  0x00007fff202529e7 in std::__terminate(void (*)()) ()
#7  0x00007fff20255254 in __cxa_rethrow ()
#8  0x00007fff2019ed46 in objc_exception_rethrow ()
#9  0x00007fff20363229 in CFRunLoopRunSpecific ()
#10 0x00007fff2c851cd3 in GSEventRunModal ()
#11 0x00007fff24ffbe63 in -[UIApplication _run] ()
#12 0x00007fff25000a53 in UIApplicationMain ()
#13 0x0000000100188a7f in main at /Users/leocare/Downloads/crisp-sdk-ios-master/Examples/Sample-Swift/Sample-Swift/AppDelegate.swift:13
#14 0x00000001001a9e1e in start_sim ()
Thread#0    0x00007fff203fbba4 in __exceptionPreprocess ()
#1  0x00007fff2019ebe7 in objc_exception_throw ()
#2  0x00007fff2476fb9b in -[UINavigationController pushViewController:transition:forceImmediate:] ()
#3  0x00007fff2476ea75 in -[UINavigationController pushViewController:animated:] ()
#4  0x0000000100187ec2 in EncapsulateViewController.viewDidLoad() at /Users/leocare/Downloads/crisp-sdk-ios-master/Examples/Sample-Swift/Sample-Swift/ViewController.swift:30
#5  0x0000000100187f1c in @objc EncapsulateViewController.viewDidLoad() ()
#6  0x00007fff2483d2f0 in -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] ()
#7  0x00007fff24841cf4 in -[UIViewController loadViewIfRequired] ()
#8  0x00007fff2476b1ee in -[UINavigationController _updateScrollViewFromViewController:toViewController:] ()
#9  0x00007fff2476b4ef in -[UINavigationController _startTransition:fromViewController:toViewController:] ()
#10 0x00007fff2476c4c7 in -[UINavigationController _startDeferredTransitionIfNeeded:] ()
#11 0x00007fff2476d887 in -[UINavigationController __viewWillLayoutSubviews] ()
#12 0x00007fff2474c12e in -[UILayoutContainerView layoutSubviews] ()
#13 0x00007fff255bcaad in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#14 0x00007fff2893c2b6 in CA::Layer::layout_if_needed(CA::Transaction*) ()
#15 0x00007fff289474f1 in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#16 0x00007fff288830ca in CA::Context::commit_transaction(CA::Transaction*, double, double*) ()
#17 0x00007fff288bac47 in CA::Transaction::commit() ()
#18 0x00007fff24ffa814 in _UIApplicationFlushRunLoopCATransactionIfTooLate ()
#19 0x00007fff250b3e36 in __processEventQueue ()
#20 0x00007fff250aa1b6 in __eventFetcherSourceCallback ()
#21 0x00007fff20369e25 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#22 0x00007fff20369d1d in __CFRunLoopDoSource0 ()
#23 0x00007fff203691f2 in __CFRunLoopDoSources0 ()
#24 0x00007fff20363951 in __CFRunLoopRun ()
#25 0x00007fff20363103 in CFRunLoopRunSpecific ()
#26 0x00007fff2c851cd3 in GSEventRunModal ()
#27 0x00007fff24ffbe63 in -[UIApplication _run] ()
#28 0x00007fff25000a53 in UIApplicationMain ()
#29 0x0000000100188a7f in main at /Users/leocare/Downloads/crisp-sdk-ios-master/Examples/Sample-Swift/Sample-Swift/AppDelegate.swift:13
#30 0x00000001001a9e1e in start_sim ()
#31 0x0000000000000001 in 0x00000001 ()
StevenWatremez commented 2 years ago

So I have more information and pain point for this. I tried to encapsulate the ChatViewController inside a tab of an UITabBarController

    let ctrl1 = UIViewController()
    ctrl1.view.backgroundColor = .red
    ctrl1.tabBarItem = .init(tabBarSystemItem: .favorites, tag: 0)

    let appearance = UITabBarAppearance()
    appearance.configureWithOpaqueBackground()

    let chatCtrl = ChatViewController()
    chatCtrl.tabBarItem = .init(title: "Support", image: UIImage(systemName: "message"), tag: 1)

    let tabController = UITabBarController()
    tabController.tabBar.standardAppearance = appearance
    tabController.tabBar.scrollEdgeAppearance = appearance
    tabController.viewControllers = [
      ctrl1,
      chatCtrl,
    ]

As a result, the chat is integrated inside the tabBar, job done. But the cross button at the top right and corner is not cliquable to dismiss the keyboard, because on your side you bind it to only dismiss le controller and not the keyboard. The only way to dismiss the keyboard is to click on the chat scroll view.

I know that your chat is not built to be integrated inside an existing navigation, but can we find a quick solution for this ? Maybe add a dismiss keyboard in addition to the dismiss controller ?

baptistejamin commented 2 years ago

We can consider implementing a such feature, however, we believe that in terms of UI/UX, embedding a chat like Crisp in a TabBar seems a bad idea, because of the keyboard management would overlay the tabbar menu anyway.

It would be nice if you show how Crisp is currently integrated in your app.

As an example, here is what we do with Crisp:

IMG_2195

IMG_2194

StevenWatremez commented 2 years ago

For our usecase the chat is central for customer communication.

Here you can see the integration. IMG_4463

We tried to handle the chat like you did but we had a deeplink problem to present a view when the navigation stack is creating, hard to handle this case if I present the chat. So with your code I integrated inside the tabBar and the bug appear.

nesium commented 1 year ago

Hi there,

It’s been a while since this issue was reported, and we’ve launched a new major version of the Crisp SDK since then. The updates might have resolved the issue you encountered.

We’d appreciate it if you test the latest version to see if the issue persists. Feel free to reopen this issue with more details if needed.

Thanks for your support!