44

In iOS 15.6 beta5 and iOS 16.0 beta:

When an UISceneDidDisconnectNotification was posted, any active SKStoreProductViewController instance would crash for the unrecognized selector named sceneDisconnected.

-[SKStoreProductViewController sceneDisconnected:]: unrecognized selector sent to instance 0x115161a00

This crash only happened in the latest iOS15.6 and iOS16 beta version. Yet I can't find the selector name in any official documents……

Any solutions? Or Is there anything I haven't done right?

QianKai
  • 443
  • 1
  • 4
  • 5

8 Answers8

25

Looks like this was fixed in the iOS 15.6 release candidate that was realeased today.

Sept 14 2022 Update: Apple re-introduced this crash in the official 15.7 release. It only seems to happen when the app is force quit so it should not affect users. I've filed a ticket to Apple on feedbackassistant.apple.com and would encourage others to do the same.

Lorenzo
  • 1,605
  • 14
  • 18
  • That seems to be the case. Phew! – fearmint Jul 13 '22 at 15:14
  • 1
    The latest 15.6 RC version, the crash still exists – leaveslife Jul 14 '22 at 07:06
  • @leaveslife are you sure? I just updated to the latest 15.6 RC and I didn't see the crash – Lorenzo Jul 20 '22 at 00:56
  • I'm sure, I reproduced the way tedrothrock described above. Create a new project, then call the related methods of SKStoreProductViewController, restart the APP a few times, it will crash – leaveslife Jul 20 '22 at 02:14
  • @leaveslife Strange, I'm trying the same steps on my device and I'm not seeing any crashes. If you go to Settings > General > Software Update does it say "iOS 15.6 iOS is up to date"? – Lorenzo Jul 21 '22 at 00:35
  • 5
    iOS 15.7 the crash still exists – leaveslife Sep 14 '22 at 08:25
  • @leaveslife yeah looks like Apple re-introduced the crash. Updated my answer – Lorenzo Sep 14 '22 at 17:13
  • Can't file an issue - their website now is having an issue. Things were really going downhill. That's what happens when you have a marketing guy at the helm instead of a product guy. RIP Apple... – inteist Oct 18 '22 at 18:19
  • 1
    Since version 15.7.1 has been released, we see a decrease in crashes in Firebase Crashlytics. Also when filtering on iOS version, 15.7.1 is not in the list. This seems a good indication that Apple has finally resolved this issue in 15.7.1. – Martijn Nov 05 '22 at 16:07
11

Not a solution, but a clear indication that this is Apple's bug to fix. Starting with a clean sample project, all you need to do is present a SKStoreProductViewController and then force quit your application:

import StoreKit
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let storeKitViewController = SKStoreProductViewController()
        storeKitViewController.loadProduct(withParameters: [
            SKStoreProductParameterITunesItemIdentifier: NSNumber(integerLiteral: 364709193)
        ])
        present(storeKitViewController, animated: true)

        // Force quit after presentation to trigger crash
        // -[SKStoreProductViewController sceneDisconnected:]: unrecognized selector sent to instance
    }

}

I've filed this with Apple via Feedback Assistant.

tedrothrock
  • 368
  • 2
  • 9
10

The crash has been fixed in iOS16

below is an explanation by Apple Framework Engineer

This crash happens in the public release of iOS/iPadOS 15.7, and seed releases of iOS/iPadOS 16 prior to seed 4 [1]. It does not occur in the public release of iOS 16. The crash primarily happens when the app is in the background and is about to be terminated by the operating system. As a result, these crashes are not expected to be visible to the majority of end users. (One exception is on iPad with an app that supports multiple scenes, and a user manually terminates a scene.) Your analytics will show an increased in crash rate, however your customers should not be affected by this issue. We are actively working to address the crash. [1] In which case you should update to the most recent release.

source: https://developer.apple.com/forums/thread/714464?answerId=729646022#729646022

Husam
  • 8,149
  • 3
  • 38
  • 45
7

Able to reproduce a crash with the same stack symbols locally and the code below stops the crash from occurring. The code is creating empty functions to handle the unrecognized selector message and restricting this extension to iOS 15.7:

@available(iOS, introduced: 15.7, obsoleted: 16.0)
@objc extension SKStoreProductViewController {
    func sceneDisconnected(_ arg: AnyObject) {}
    func appWillTerminate() {}
}
Chris
  • 71
  • 1
  • 4
  • I'm not sure this is completely safe... what about if Apple releases a new patch release on iOS 15.7.1 or 15.8 ? sceneDisconnected and appWillTerminate will be ignored. – Vjardel Oct 05 '22 at 15:14
  • 1
    What would be the objective-c version of this? – user955853 Oct 06 '22 at 04:05
  • The analog of a Swift extension In Objective-C is a category. Although it should also work for Objective-C like shown above because it exposes itself with @objc. Your project needs a bridging header for this https://developer.apple.com/documentation/swift/importing-swift-into-objective-c/?language=objc and i would add an import to Foundation and StoreKit to the code above. – MacMark Oct 10 '22 at 08:53
  • In my tests this fix works as it is also in Objective-C apps (with bridging header). – MacMark Oct 10 '22 at 10:23
  • This is the only solution I've seen. It also works for me. I'm aware it is not taking care of 15.7.x or 15.8, but it's been a long time waiting for those versions from Apple with a bugfix and I will not wait more... I'm including this in the production release. Thanks @Chirs – Juan Peralta Oct 15 '22 at 11:49
  • The Apple documentation of `SKStoreProductViewController` at https://developer.apple.com/documentation/storekit/skstoreproductviewcontroller/ clearly mentions it doesn’t support subclassing or embedding: "Prevent Exceptions The SKStoreProductViewController class doesn’t support subclassing or embedding, and must be used as-is." – Martijn Oct 23 '22 at 09:38
2

Add this code in application(_:didFinishLaunchingWithOptions:) (at least before the app is terminated). It adds the methods at runtime if they don’t exist.

if #available(iOS 15.7, *) {
    if #unavailable(iOS 16.0) {
        class_addMethod(
            SKStoreProductViewController.self,
            Selector(("appWillTerminate")),
            unsafeBitCast({ _, _ in } as @convention(c) (SKStoreProductViewController, Selector) -> Void, to: IMP.self),
            "v@:"
        )
        class_addMethod(
            SKStoreProductViewController.self,
            Selector(("sceneDisconnected:")),
            unsafeBitCast({ _, _, _ in } as @convention(c) (SKStoreProductViewController, Selector, NSNotification) -> Void, to: IMP.self),
            "v@:@"
        )
    }
}

It seems they removed appWillTerminate and sceneDisconnected(_:) methods in iOS 15.7, but forgot to remove the code that adds UIApplication.willTerminateNotification and UIScene.didDisconnectNotification observers to the NotificationCenter.


Edit: They seem to have re-added appWillTerminate and sceneDisconnected(_:) methods in iOS 15.7.1. So I’ve updated the code to add the methods only in iOS 15.7.


Edit: They removed the methods AGAIN in iOS 15.7.2 and the crash recurred. I’ve reverted the code.

MMP0
  • 111
  • 2
  • 3
1

This is actually an inaccurate reporting because it doesn't actually cause the crash.

I reproduced the reported scene: click on the app-download advertisement in your app, pop up the in-app App Store download page, and then back to the background, the crash message is generated in this time -- but no crash actually occurred, and nothing changed when I returned to the foreground. Everything works fine. The next time the app starts, the crash information will be reported.

So no need to do anything now, just wait for Apple to fix it.

  • Thanks for clarifying. If no crashes are actually occurring and it's just a reporting issue, that's quite a relief – tedrothrock Jul 11 '22 at 14:54
0

Since version 15.7.1 has been released, we see a decrease in crashes in Firebase Crashlytics. Also when filtering the crashes on iOS version, version 15.7.1 is not present in the list.

This seems a good indication that Apple has finally resolved this issue in 15.7.1.

Please share your observations from your own crash reports to verify that my assumption is correct.

Martijn
  • 429
  • 4
  • 13
0

Objective C version, via a category on NSObject. ✌

@interface NSObject (crashPrevent)
@end

@implementation NSObject (crashPrevent)
-(void) sceneDisconnected:(id) item {
    return;
}
-(void) appWillTerminate {
    return;
}
@end
dklt
  • 1,703
  • 1
  • 12
  • 12