Ionic/Angular应用iOS端崩溃问题求助
我刚开发完首款Ionic/Angular应用,Android端跑起来很稳定,已经上架Google Play了。但iOS打包IPA后,虽然启动正常——能显示启动页并跳转到首页,但碰到几个场景就会崩溃:
- 点击输入框唤起键盘的时候
- 用
onclick="window.open('tel:+000000000', '_system')"或者onclick="window.open('mailto:mail@mail.nl', '_system')"调用系统功能后重启应用 - 甚至只是点iOS Home键切后台,再重启应用也会崩
以下是崩溃日志:
Date/Time: 2018-05-21 17:14:53.5359 +0200 Launch Time: 2018-05-21 17:14:47.9337 +0200 OS Version: iPhone OS 11.3.1 (15E302) Baseband Version: 2.03.12 Report Version: 104 Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Triggered by Thread: 0 Application Specific Information: abort() called Filtered syslog: None found Last Exception Backtrace: 0 CoreFoundation 0x1816f2d8c __exceptionPreprocess + 228 1 libobjc.A.dylib 0x1808ac5ec objc_exception_throw + 55 2 CoreFoundation 0x181700098 -[NSObject+ 1388696 (NSObject) doesNotRecognizeSelector:] + 139 3 UIKit 0x18b7a6de4 -[UIResponder doesNotRecognizeSelector:] + 291 4 CoreFoundation 0x1816f85c8 ___forwarding___ + 1379 5 CoreFoundation 0x1815de41c _CF_forwarding_prep_0 + 91 6 Duofor 0x102e63e2c 0x102e40000 + 146988 7 Duofor 0x102e63c24 0x102e40000 + 146468 8 libdispatch.dylib 0x180fe4ae4 _dispatch_client_callout + 15 9 libdispatch.dylib 0x180fecf18 _dispatch_continuation_pop$VARIANT$mp + 423 10 libdispatch.dylib 0x180ff6808 _dispatch_source_invoke$VARIANT$mp + 1363 11 libdispatch.dylib 0x180ff15b8 _dispatch_main_queue_callback_4CF$VARIANT$mp + 715 12 CoreFoundation 0x18169b070 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 11 13 CoreFoundation 0x181698bc8 __CFRunLoopRun + 2271 14 CoreFoundation 0x1815b8da8 CFRunLoopRunSpecific + 551 15 GraphicsServices 0x18359b020 GSEventRunModal + 99 16 UIKit 0x18b59978c UIApplicationMain + 235 17 Duofor 0x102e464ac 0x102e40000 + 25772 18 libdyld.dylib 0x181049fc0 start + 3
问题分析
从崩溃日志里的-[NSObject doesNotRecognizeSelector:]可以看出,核心问题是某个对象收到了它根本不认识的方法调用,而且这个调用是在主队列的dispatch回调里触发的。结合你遇到的几个崩溃场景,大概率是WebView和原生层的交互出了问题,或者是某些插件在iOS的生命周期处理上有bug。
具体排查与解决步骤
1. 升级或替换相关插件
首先检查你用的插件兼容性,尤其是键盘和系统调用相关的:
- 如果你用的是旧版的
cordova-plugin-keyboard,建议换成官方维护的cordova-plugin-ionic-keyboard,它对iOS 11+的支持更好。执行以下命令更新:ionic cordova plugin rm cordova-plugin-keyboard ionic cordova plugin add cordova-plugin-ionic-keyboard npm install @ionic-native/keyboard - 对于
tel和mailto这类系统调用,别直接用window.open了,换成Ionic Native的InAppBrowser插件,它对iOS的处理更稳定,不容易出现后台恢复时的异常:import { InAppBrowser } from '@ionic-native/in-app-browser/ngx'; constructor(private iab: InAppBrowser) { } // 拨打电话 makePhoneCall() { this.iab.create('tel:+000000000', '_system'); } // 发送邮件 sendEmail() { this.iab.create('mailto:mail@mail.nl', '_system'); }
2. 检查WebView插件版本
cordova-plugin-ionic-webview的旧版本在iOS应用从后台恢复时,容易出现WebView状态异常的问题。更新到最新稳定版试试:
ionic cordova plugin rm cordova-plugin-ionic-webview ionic cordova plugin add cordova-plugin-ionic-webview@latest npm install @ionic-native/ionic-webview
3. 调试定位具体代码
用Xcode连接真机调试,重现崩溃场景,这样能看到更详细的调用栈信息。日志里的Duofor 0x102e63e2c这类地址可以通过符号化来定位到具体的代码位置:
- 打开Xcode的
Window > Organizer,导入你的崩溃日志,Xcode会自动尝试符号化;如果没自动完成,手动指定打包时生成的dSYM文件(和IPA在同一个目录里)。
4. 检查生命周期钩子
看看你页面的ionViewWillEnter、ionViewDidEnter这些生命周期钩子里面,有没有在iOS上执行的代码导致了对象被释放后还被调用。比如某些RxJS订阅没在ionViewWillLeave里取消,后台恢复时回调触发到已经销毁的组件,就会引发这类崩溃。
5. 最小化测试
如果上面的方法都没解决,可以建一个最小化的测试项目,只保留输入框、拨打电话这些崩溃相关的功能,然后逐步添加原项目的代码和插件,一步步定位到具体是哪个部分导致的崩溃。
内容的提问来源于stack exchange,提问作者Gary S.

