Some time ago, I started seeing an explosion of “Out of memory” crashes in Dash. Bugsnag wouldn’t tell me much more than this:
This started to happen with iOS version 14.4.2, and subsequent OS versions. Without much to go around with, I decided to fix a warning I had lingering:
Well, you can guess where this is heading. At some point, around 14.4.2, the OS started to kill my app. I was using unavailable methods inside extensions. The culprit was the usage of UIApplicationMain
inside an extension.
So I wrote this abstraction:
public protocol MainApplication {
func registerForRemoteNotifications()
func unregisterForRemoteNotifications()
var isRegisteredForRemoteNotifications: Bool { get }
var alternateIconName: String? { get }
func setAlternateIconName(
_ alternateIconName: String?,
completionHandler: ((Error?) -> Void)?
)
func canOpenURL(_ url: URL) -> Bool
}
In the main app:
extension UIApplication: MainApplication {}
And on the extension:
struct DummyMainApplication: MainApplication {
init() {}
func registerForRemoteNotifications() {}
func unregisterForRemoteNotifications() {}
var isRegisteredForRemoteNotifications: Bool { return true }
var alternateIconName: String? { return nil }
func setAlternateIconName(
_ alternateIconName: String?,
completionHandler: ((Error?) -> Void)?
) {}
func canOpenURL(_ url: URL) -> Bool { return true }
}
Finally, turning Require Only App-Extension-Safe API
to True
, allowed me to quickly audit the codebase.
After releasing Dash 1.6 with these fixes, I haven’t see any crash due to Out of Memory.