My app is crashing with following error. It is random error so can't catch the error during testing.
What is causing this crash and how to fix it?
Crashlytics log
Crashed: com.apple.main-thread
0 MyApp 0x177fdc closure #1 in closure #1 in AppVersionChecker.checkVersion(force:title:message:) 4307714012 (AppVersionChecker.swift:4307714012)
1 MyApp 0x3a07fc thunk for @escaping @callee_guaranteed () -> () 4309977084 (<compiler-generated>:4309977084)
2 libdispatch.dylib 0x631a4 _dispatch_call_block_and_release 24
3 libdispatch.dylib 0x641a8 _dispatch_client_callout 16
4 libdispatch.dylib 0x454b8 _dispatch_main_queue_callback_4CF$VARIANT$armv81 908
5 CoreFoundation 0x4d888 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ 12
6 CoreFoundation 0xb188 __CFRunLoopRun 2528
7 CoreFoundation 0x1de1c CFRunLoopRunSpecific 572
8 GraphicsServices 0x19a0 GSEventRunModal 160
9 UIKitCore 0x4ec600 -[UIApplication _run] 1080
10 UIKitCore 0x281b08 UIApplicationMain 2028
11 MyApp 0xf678 main 23 (AppDelegate.swift:23)
12 ??? 0x102b2c250 (Missing)
Code
private func checkVersion(force: Bool, title: String?, message: String?) {
let info = Bundle.main.infoDictionary
guard let currentVersion = info?["CFBundleShortVersionString"] as? String else {
NSLog("Error currentVerion")
return
}
_ = getAppInfo { (info, error) in
// Compare with version on appstore
guard let appStoreAppVersion = info?.version else {
NSLog("Error appStoreAppVersion")
return
}
if let error = error {
NSLog("getAppInfo Error: \(error)")
} else if appStoreAppVersion.compare(currentVersion, options: .numeric) == .orderedDescending {
DispatchQueue.main.async {
let topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
topController.showAppUpdateAlert(Version: (info?.version)!, Force: force, AppURL: (info?.trackViewUrl)!, title: title, message: message)
}
}
}
}
CodePudding user response:
Force unwrap are a reason to crash.
let topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
If UIApplication.shared.keyWindow
is nil
, it will crash.
If UIApplication.shared.keyWindow!.rootViewController!
is nil
, it will crash.
(info?.version)!
If (info?.version)
is nil
, it will crash.
(info?.trackViewUrl)!
If (info?.trackViewUrl)!
is nil
, it will crash.
Now, you have optional values, it means that the value can be nil
, so why use optional, in first place, and force unwrap after?
Use if let
, guard let
or ??
providing a default value to ensure the value exists.