看起来这个问题已经在今天发布的iOS 15.6正式版中得到了修复。
2022年9月14日更新:苹果在官方的15.7版本中重新引入了这个崩溃问题。只有当应用程序被强制退出时才会出现,因此不应影响用户。我已经在feedbackassistant.apple.com上向苹果提交了一张工单,并鼓励其他人也这样做。
这并不是一个解决方案,但清楚地表明这是苹果需要修复的错误。从一个干净的样本项目开始,你只需要呈现一个SKStoreProductViewController,然后强制退出你的应用程序:
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
}
}
我已经通过反馈助手向苹果提交了此问题。
以下是由苹果框架工程师解释:
此崩溃问题发生在iOS/iPadOS 15.7的公开发布以及iOS/iPadOS 16种子版本seed 4之前的种子发布中,但不会在iOS 16的公开发布中出现。 主要发生在应用程序在后台运行且即将被操作系统终止时。因此,这些崩溃不应该对大多数最终用户可见。(唯一的例外情况是iPad上支持多个场景的应用程序,并且用户手动终止场景。) 您的分析数据将显示崩溃率升高,但您的客户不应受此问题影响。 我们正在积极处理此崩溃问题。 [1] 在这种情况下,您应更新到最新版本。
来源:https://developer.apple.com/forums/thread/714464?answerId=729646022#729646022
SKStoreReviewController
导致了这个崩溃。 - Husam@available(iOS, introduced: 15.7, obsoleted: 16.0)
@objc extension SKStoreProductViewController {
func sceneDisconnected(_ arg: AnyObject) {}
func appWillTerminate() {}
}
SKStoreProductViewController
的苹果文档(https://developer.apple.com/documentation/storekit/skstoreproductviewcontroller/)明确指出它不支持子类化或嵌入:“防止异常 SKStoreProductViewController类不支持子类化或嵌入,并且必须按原样使用。” - Martijn将以下代码添加到 application(_:didFinishLaunchingWithOptions:)
中(至少在应用程序终止之前)。如果方法不存在,它会在运行时添加方法。
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@:@"
)
}
}
appWillTerminate
和sceneDisconnected(_:)
方法,但忘记了删除将UIApplication.willTerminateNotification
和UIScene.didDisconnectNotification
观察者添加到NotificationCenter的代码。appWillTerminate
和sceneDisconnected(_:)
方法。因此,我已更新代码,仅在iOS 15.7中添加这些方法。这实际上是一种不准确的报告,因为它并没有导致应用程序崩溃。
我复现了所报告的情况:在您的应用程序中点击应用下载广告,在应用内弹出App Store下载页面,然后返回到后台,此时会生成崩溃信息 -- 但实际上并没有发生崩溃,当我返回前台时什么也没变化,一切都正常运作。下次启动应用程序时,将会报告崩溃信息。
因此现在无需做任何事情,只需等待苹果修复即可。
Objective C 版本,通过在 NSObject
上添加一个分类实现。✌
@interface NSObject (crashPrevent)
@end
@implementation NSObject (crashPrevent)
-(void) sceneDisconnected:(id) item {
return;
}
-(void) appWillTerminate {
return;
}
@end