My app is crashing on Production and I can't reproduce the error that Fabric keep sending me. There is some problem with the UISearchController, but when I use it on the app works well. One thing I noticed is the low ram memory available at the point of this error on all the devices. It could be something related with memory leak? As more memory is needed, maybe the OS deallocates the objects and thus "unrecognized selector sent to instance", because the object that is trying to send the message (function) is already deallocated, but is a guest, I'm still facing this issue, and in my app I don't have any memory leak at this point.
The stack trace:
Fatal Exception: NSInvalidArgumentException
-[_UIAlertControllerAlertPresentationController adaptivePresentationController]: unrecognized selector sent to instance 0x104fb1420
Raw Text
0
CoreFoundation
__exceptionPreprocess
1 libobjc.A.dylib
objc_exception_throw
2 CoreFoundation
__methodDescriptionForSelector
3
CoreFoundation
___forwarding___
4 CoreFoundation
_CF_forwarding_prep_0
5
UIKit
-[UISearchController _searchPresentationController]
6 UIKit
-[_UISearchControllerInPlaceSearchBarAnimator animateTransition:]
7 UIKit
__56-[UIPresentationController runTransitionForCurrentState]_block_invoke
8 UIKit
_runAfterCACommitDeferredBlocks
9 UIKit
_cleanUpAfterCAFlushAndRunDeferredBlocks
10 UIKit
_afterCACommitHandler
11 CoreFoundation
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
12 CoreFoundation
__CFRunLoopDoObservers
13 CoreFoundation
__CFRunLoopRun
14 CoreFoundation
CFRunLoopRunSpecific
15 GraphicsServices
GSEventRunModal
16
UIKit
UIApplicationMain
17 *****
MAMarketPlaceViewModel.swift line 14
main
18 libdyld.dylib
start
This is how I'm using the SearchController:
lazy var searchController = { () -> UISearchController in
let search = UISearchController(searchResultsController: nil)
search.searchResultsUpdater = self
search.delegate = self
search.hidesNavigationBarDuringPresentation = false
search.dimsBackgroundDuringPresentation = false
search.definesPresentationContext = true
search.searchBar.placeholder = L10n.searchProducts
search.searchBar.delegate = self
return search
}()
....
fileprivate func setupNavigationBar() {
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .always
self.navigationItem.searchController = searchController
self.navigationController?.navigationBar.tintColor = UIColor.Palette.intenseGray
self.navigationItem.hidesSearchBarWhenScrolling = false
} else {
self.extendedLayoutIncludesOpaqueBars = true
searchController.searchBar.searchBarStyle = .prominent
tableView.tableHeaderView = searchController.searchBar
}
if self.tableView.tableHeaderView != nil {
self.tableView.tableHeaderView?.isHidden = false
}
}
UPDATE
On the onError event of RxSwift I'm showing the AlertController, is the only place I can think I have a UISearchController and an showing an AlertController.
protocol MarketCartPresentable : class {
var disposeBag : DisposeBag { get }
func showCart()
func present(product: MAProductMktPlace, with cart: MACarts)
}
extension MarketCartPresentable where Self : MAMainViewController, Self : MAMainViewControllerProtocol {
func showCart() {
guard let viewModel = self.viewModel as? Buyable else { return } //We need to have a ViewModel which impements Buyable Protocol! =)
viewModel.getCarts()
.asDriver(onErrorJustReturn: MACarts())
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self](carts) in
let cartViewModel = MAMktCartViewModel(cartLines: carts)
let cartViewController = MAMktCartViewController(_associatedViewModel: cartViewModel)
let cartNavController = MACheckoutNavigationController(rootViewController: cartViewController)
self?.present(cartNavController, animated: true, completion: {
})
}, onError: { [weak self] (error) in
guard let errorMsg = error as? MAErrorProtocol else {
self?.showAlertWith(title: L10n.errorTitle , message: error.localizedDescription)
return
}
self?.showAlertWith(title: L10n.errorTitle , message: errorMsg.errorMessage)
}).addDisposableTo(self.disposeBag)
}