Skip to content

Conversation

melekr
Copy link
Contributor

@melekr melekr commented Sep 15, 2025

Changes summary

This PR migrates the Unity native integration from the legacy cocoa static libraries to dynamic backtrace-cocoa frameworks:

  • iOS: link Backtrace.xcframework (dynamic) + CrashReporter.xcframework (static), embed Backtrace, set Swift/platform flags via a post-build.
  • macOS: Update plugin bundle (BacktraceMacUnity.bundle) that exports the native C API and nests Backtrace.framework for runtime. PLCrashReporter is linked statically.

The public C# API remains unchanged, only NativeClient and build steps are updated.

Why this change

  • Modern packaging: XCFramework is Apple’s native distribution format for binary SDKs. Bundles device & simulator slices + correct slice selection at build time and Privacy & resources packaging.
  • Stability/maintainability: Native standard Apple linking/embedding semantics + Swift runtime embedding of Swift stdlibs.
  • Parity: aligns Unity integration with Backtrace’s official iOS/macOS SDK expectations.

Footprint

size

Sample Reports

What's next

  • Expose more cocoa settings & expand configuration
  • Offload/remove frameworks and bundle from repo

@melekr melekr marked this pull request as draft September 15, 2025 23:25
@melekr melekr changed the title Feature/update cocoa dylib Migrate Unity iOS/macOS native integration Sep 16, 2025
@melekr melekr self-assigned this Sep 16, 2025
@melekr melekr marked this pull request as ready for review September 16, 2025 03:25
{
if (buildTarget != BuildTarget.iOS) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad formatting

Comment on lines +32 to +38
#if UNITY_2019_3_OR_NEWER
string appTargetGuid = project.GetUnityMainTargetGuid();
string unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
#else
string appTargetGuid = project.TargetGuidByName("Unity-iPhone");
string unityFrameworkTargetGuid = appTargetGuid;
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit:

what do you think about?

Suggested change
#if UNITY_2019_3_OR_NEWER
string appTargetGuid = project.GetUnityMainTargetGuid();
string unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
#else
string appTargetGuid = project.TargetGuidByName("Unity-iPhone");
string unityFrameworkTargetGuid = appTargetGuid;
#endif
string appTargetGuid =
#if UNITY_2019_3_OR_NEWER
project.GetUnityMainTargetGuid();
#else
project.TargetGuidByName("Unity-iPhone");
#endif
string unityFrameworkTargetGuid =
#if UNITY_2019_3_OR_NEWER
project.GetUnityFrameworkTargetGuid();
#else
appTargetGuid;
#endif

}

// Locate exported xcframeworks
string FindXCFramework(string folderName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move it to class instance? It's not popular in C# to have a function declaration inside another function. its also inconsistent with the rest of the library code

Comment on lines +52 to +64
var backtraceXCPath = FindXCFramework("Backtrace.xcframework");
var crashReporterXCPath = FindXCFramework("CrashReporter.xcframework");

if (string.IsNullOrEmpty(backtraceXCPath))
{
Debug.LogError($"[Backtrace] Could not locate Backtrace.xcframework under: {buildPath}");
return;
}
if (string.IsNullOrEmpty(crashReporterXCPath))
{
Debug.LogError($"[Backtrace] Could not locate CrashReporter.xcframework under: {buildPath}");
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit:

Suggested change
var backtraceXCPath = FindXCFramework("Backtrace.xcframework");
var crashReporterXCPath = FindXCFramework("CrashReporter.xcframework");
if (string.IsNullOrEmpty(backtraceXCPath))
{
Debug.LogError($"[Backtrace] Could not locate Backtrace.xcframework under: {buildPath}");
return;
}
if (string.IsNullOrEmpty(crashReporterXCPath))
{
Debug.LogError($"[Backtrace] Could not locate CrashReporter.xcframework under: {buildPath}");
return;
}
var backtraceXCPath = FindXCFramework("Backtrace.xcframework");
if (string.IsNullOrEmpty(backtraceXCPath))
{
Debug.LogError($"[Backtrace] Could not locate Backtrace.xcframework under: {buildPath}");
return;
}
var crashReporterXCPath = FindXCFramework("CrashReporter.xcframework");
if (string.IsNullOrEmpty(crashReporterXCPath))
{
Debug.LogError($"[Backtrace] Could not locate CrashReporter.xcframework under: {buildPath}");
return;
}

Comment on lines +68 to +79
string relCrashReporterXC = ToProjectRelative(buildPath, crashReporterXCPath);

// Add file references
string backtraceFileGuid = project.FindFileGuidByProjectPath(relBacktraceXC);
if (string.IsNullOrEmpty(backtraceFileGuid)) {
backtraceFileGuid = project.AddFile(relBacktraceXC, relBacktraceXC, PBXSourceTree.Source);
}

string crashReporterFileGuid = project.FindFileGuidByProjectPath(relCrashReporterXC);
if (string.IsNullOrEmpty(crashReporterFileGuid)) {
crashReporterFileGuid = project.AddFile(relCrashReporterXC, relCrashReporterXC, PBXSourceTree.Source);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit:

Suggested change
string relCrashReporterXC = ToProjectRelative(buildPath, crashReporterXCPath);
// Add file references
string backtraceFileGuid = project.FindFileGuidByProjectPath(relBacktraceXC);
if (string.IsNullOrEmpty(backtraceFileGuid)) {
backtraceFileGuid = project.AddFile(relBacktraceXC, relBacktraceXC, PBXSourceTree.Source);
}
string crashReporterFileGuid = project.FindFileGuidByProjectPath(relCrashReporterXC);
if (string.IsNullOrEmpty(crashReporterFileGuid)) {
crashReporterFileGuid = project.AddFile(relCrashReporterXC, relCrashReporterXC, PBXSourceTree.Source);
}
// Add file references
var backtraceFileGuid = project.FindFileGuidByProjectPath(relBacktraceXC);
if (string.IsNullOrEmpty(backtraceFileGuid)) {
backtraceFileGuid = project.AddFile(relBacktraceXC, relBacktraceXC, PBXSourceTree.Source);
}
var relCrashReporterXC = ToProjectRelative(buildPath, crashReporterXCPath);
var crashReporterFileGuid = project.FindFileGuidByProjectPath(relCrashReporterXC);
if (string.IsNullOrEmpty(crashReporterFileGuid)) {
crashReporterFileGuid = project.AddFile(relCrashReporterXC, relCrashReporterXC, PBXSourceTree.Source);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants