We are observing lots of crashes on iOS 15.7 for our iOS game. Something iOS is responsible for, which is fixed in iOS 16.
More info: [SKStoreProductViewController scen… | Apple Developer Forums
People have suggested workarounds for this problem, But can anyone help me migrate this to Unity?
I really prefer this to be done from inside Unity, and not after exporting the Xcode project and modifying manually; Either by doing something in IPostprocessBuildWithReport, or any other possible way.
(though how to do it manually is also needed, if this can’t be automated)
Available workarounds:
storekit - SKStoreProductViewController crashes for unrecognized selector named sceneDisconnected: in iOS 15.6 beta5 - Stack Overflow, storekit - SKStoreProductViewController crashes for unrecognized selector named sceneDisconnected: in iOS 15.6 beta5 - Stack Overflow
1 Like
Can anyone help with this?
1 Like
OK, I had to do it myself.
Call this method from an IPostprocessBuildWithReport in OnPostprocessBuild() and pass it report.summary.outputPath and all will be set:
//Fix for a bug that Apple introduced in iOS 15.7 that leads to crashes
//More info: https://developer.apple.com/forums/thread/714464 , workarounds: https://stackoverflow.com/a/73796906/1235063 , https://stackoverflow.com/questions/72907240/skstoreproductviewcontroller-crashes-for-unrecognized-selector-named-scenediscon/74232140#74232140
//Expections on Xcode project:
//SWIFT_OBJC_BRIDGING_HEADER must be set (only for Unity-iPhone target)
//CLANG_ENABLE_MODULES set to true, for Unity-iPhone, Unity-iPhone Tests, and UnityFramework
//SWIFT_VERSION for the 3 targets must be specified
private void AddWorkaroundForCrashIniOS15_7(string pathToBuiltProject)
{
string projectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
PBXProject project = new PBXProject();
project.ReadFromString(File.ReadAllText(projectPath));
string swiftFileName = "CrashPrevIOS15_7.swift";
string swiftFileContent = "//\n// File.swift\n// Unity-iPhone\n//\n// Created by Paiman Roointan on 1/18/23.\n//\n\nimport Foundation\nimport StoreKit\n\n@available(iOS, introduced: 15.7, obsoleted: 16.0)\n@objc extension SKStoreProductViewController {\n func sceneDisconnected(_ arg: AnyObject) {}\n func appWillTerminate() {}\n}\n";
string swiftFilePath = Path.Combine(pathToBuiltProject, swiftFileName);
if (!File.Exists(swiftFilePath))
File.WriteAllText(swiftFilePath, swiftFileContent);
project.AddFileToBuild(
project.GetUnityMainTargetGuid(),
project.AddFile(swiftFileName, swiftFileName));
string bridgingHeaderFileName = "Unity-iPhone-Bridging-Header.h";
string bridgingHeaderFileContent = "//\n// Use this file to import your target's public headers that you would like to expose to Swift.\n//";
string bridgingHeaderFilePath = Path.Combine(pathToBuiltProject, bridgingHeaderFileName);
if (!File.Exists(bridgingHeaderFilePath))
File.WriteAllText(bridgingHeaderFilePath, bridgingHeaderFileContent);
if (string.IsNullOrEmpty(project.GetBuildPropertyForConfig(project.GetUnityMainTargetGuid(), "SWIFT_VERSION")))
project.SetBuildProperty(project.GetUnityMainTargetGuid(), "SWIFT_VERSION", "5.0");
if (string.IsNullOrEmpty(project.GetBuildPropertyForConfig(project.GetUnityFrameworkTargetGuid(), "SWIFT_VERSION")))
project.SetBuildProperty(project.GetUnityFrameworkTargetGuid(), "SWIFT_VERSION", "5.0");
if (string.IsNullOrEmpty(project.GetBuildPropertyForConfig(project.TargetGuidByName("Unity-iPhone Tests"), "SWIFT_VERSION")))
project.SetBuildProperty(project.TargetGuidByName("Unity-iPhone Tests"), "SWIFT_VERSION", "5.0");
project.SetBuildProperty(project.GetUnityMainTargetGuid(), "CLANG_ENABLE_MODULES", "YES");
project.SetBuildProperty(project.GetUnityFrameworkTargetGuid(), "CLANG_ENABLE_MODULES", "YES");
project.SetBuildProperty(project.TargetGuidByName("Unity-iPhone Tests"), "CLANG_ENABLE_MODULES", "YES");
project.SetBuildProperty(project.GetUnityMainTargetGuid(), "SWIFT_OBJC_BRIDGING_HEADER", bridgingHeaderFileName);
File.WriteAllText(projectPath, project.WriteToString());
2 Likes