I have an intermittent (rarely occurring) crash which, so far has only occurred in the wild with reports from AppStore. With the limited crash log, I have not been able to grok the issue.
I am trying to display an App Store Product page view. Here is the code
The enclosing class includes the SKStoreProductViewControllerDelegate and
the delegate is set to self.
@objc func adTap(sender: UITapGestureRecognizer? = nil) -> Void {
if adAppID.isEmpty {return}
let paramDict = [SKStoreProductParameterITunesItemIdentifier: adAppID]
storeProductViewController.loadProduct(withParameters: paramDict, completionBlock: { (status: Bool, error: Error?) -> Void in
if status {
self.storeProductViewController.view.frame.origin.y = 0
let eventParams = ["AppID": self.adAppID]
self.present(self.storeProductViewController, animated: true, completion: nil)
}
else {
if let error = error {
print("Error: \(error.localizedDescription)")
}
}})
}
The error is triggered at the self.present:
#8 (null) in thunk for @escaping @callee_guaranteed (@unowned Bool, @guaranteed Error?) -> () ()
#7 0x100b68350 in closure #1 in ViewController.adTap(sender:)
#6 (null) in -[UIViewController presentViewController:animated:completion:] ()
#0 (null) in __exceptionPreprocess ()
Dumping the actual cashpoint file shows a SIGABRT:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x1ad1db278 __exceptionPreprocess + 220 (NSException.m:199)
1 libobjc.A.dylib 0x1acf040a4 objc_exception_throw + 56 (objc-exception.mm:565)
2 UIKitCore 0x1b0bcbe0c -[UIViewController _presentViewController:withAnimationController:completion:] + 4880 (UIViewController.m:7185)
3 UIKitCore 0x1b0bce074 __63-[UIViewController _presentViewController:animated:completion:]_block_invoke + 104 (UIViewController.m:7671)
4 UIKitCore 0x1b0bce570 -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 508 (UIViewController.m:7772)
5 UIKitCore 0x1b0bcdfc4 -[UIViewController _presentViewController:animated:completion:] + 196 (UIViewController.m:7678)
6 UIKitCore 0x1b0bce22c -[UIViewController presentViewController:animated:completion:] + 160 (UIViewController.m:7716)
7 MyAppName 0x100b68350 closure #1 in ViewController.adTap(sender:) + 1016 (ViewController.swift:991)
8 MyAppName 0x100b68580 thunk for @escaping @callee_guaranteed (@unowned Bool, @guaranteed Error?) -> () + 60 (<compiler-generated>:0)
9 StoreKit 0x1bba3c1e8 -[SKStoreProductViewController _loadDidFinishWithResult:error:] + 48 (SKStoreProductViewController.m:425)
10 StoreKit 0x1bba3e624 -[SKRemoteProductViewController loadDidFinishWithResult:error:] + 128 (SKRemoteProductViewController.m:61)
///////
I understand that the completion block is an implicitly escaping block, but I do not see how it does not fulfill the block spec (arguments, if indeed that is the issue). Again, this is an intermittent event. Never seen it on a device tethered to Xcode or on one of our untethered devices. Recently it has occurred in the field, once on a iPhone 7 running iOS 13, and once on a X running 12.3.1
/////
Any thoughts would be appreciated
Let me write this as answer, as I see now that my comment may be unclear. The block
if status {
self.storeProductViewController.view.frame.origin.y = 0
let eventParams = ["AppID": self.adAppID]
self.present(self.storeProductViewController, animated: true, completion: nil)
}
accesses some UI elements, yet it may not be running on main thread (since it's inside callback). So first thing I would suspect is that it's crashing if it happens to be called outside of main thread. Hence I would try this:
if status {
DispatchQueue.main.async {
self.storeProductViewController.view.frame.origin.y = 0
let eventParams = ["AppID": self.adAppID]
self.present(self.storeProductViewController, animated: true, completion: nil)
}
}
If it helps, maybe think of better MVC separation...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With