Quick answer: Mark callbacks with [Preserve] or list them in link.xml. Check the IL2CPP StrippingReport.xml for the actual list of removed methods.

A Unity game ships an iOS build. Editor works fine, IL2CPP build crashes when a third-party plugin invokes a managed callback. The callback method was stripped because static analysis couldn’t see who called it.

Preserve Attribute

using UnityEngine.Scripting;

[Preserve]
public class AnalyticsCallback
{
    [Preserve]
    public static void OnEvent(string name) { ... }
}

Compact for code you control. Apply to both class and method — class-only doesn’t preserve methods inside.

link.xml for Third-Party Assemblies

Add Assets/link.xml:

<linker>
  <assembly fullname="MyAnalyticsSDK">
    <type fullname="MyAnalyticsSDK.Callback" preserve="all" />
  </assembly>
  <assembly fullname="Assembly-CSharp">
    <type fullname="Game.SaveData" preserve="all" />
  </assembly>
</linker>

preserve=“all” keeps fields, methods, and the type itself. preserve=“fields” / “methods” for finer control.

JSON Deserialization Targets

Common offender: Newtonsoft.Json deserialization to a type whose only references are via reflection. Strip removes it. Mark every DTO/model class:

[Preserve]
[JsonObject(MemberSerialization.OptIn)]
public class ApiResponse
{
    [JsonProperty][Preserve] public string Id;
}

Diagnose Which Got Stripped

After a build, look in:

Library/il2cpp_cache/<platform>/Bee/StrippingReport.xml

Lists what was removed. Search for your missing type. Confirm absence in the build, then add to link.xml.

Lower Stripping Level

Player Settings → Managed Stripping Level. Options: Disabled, Minimal, Low, High. Default is High; lower for less aggressive stripping at cost of binary size. Use temporarily to confirm strip is the culprit.

Verifying

Build for target platform. Run; callback fires correctly. No InvalidOperationException / MethodNotFound at runtime. Binary size only slightly larger than before fix.

“IL2CPP strips what it can’t see. Anything called via reflection or native code needs explicit Preserve or link.xml.”

Maintain a per-asset link.xml in every plugin folder. Easier to keep in sync with code changes than one global file.