Yes for SDKs you may replace, that handle data, or that appear across many screens. A thin wrapper gives you one place to control initialisation, consent and logging, and turns removal into a one module change. For small single use libraries, a wrapper can be needless overhead.
What a wrapper is
A wrapper is a small interface in your own code that exposes only what your app needs, such as track event, show ad or sign in. One implementation class calls the vendor SDK. The rest of the app imports your interface, never the vendor types.
interface Analytics {
fun track(name: String, props: Map<String, String>)
fun setEnabled(enabled: Boolean)
}
Only the class that implements this interface imports the vendor package.
Why it helps governance
Removal gets cheap. The removal playbook starts with finding every use. With a wrapper, there is one place to look and one place to change.
One control point for data. If the wrapper is the only caller, you can filter what leaves the app. Drop fields you did not approve, enforce consent, and switch collection off. That makes the privacy review concrete: you can point to the code that decides what is passed.
Easier swaps. When a vendor is abandoned or changes terms, replacing the implementation behind the interface takes days instead of weeks.
Safer upgrades. Vendor API changes touch one file. Tests can use a fake implementation.
When not to wrap
- UI toolkits and frameworks where the SDK types are the app. Wrapping a layout library adds noise and little value.
- Libraries with large, rich APIs that you use broadly. A wrapper that mirrors the whole API is a copy of the SDK under another name.
- One off prototypes you will delete.
Decision table
| Question | If yes |
|---|---|
| Handles personal data or identifiers | Wrap |
| Could plausibly be replaced in two years | Wrap |
| Used from more than a few screens | Wrap |
| Provides framework level types the whole app uses | Do not wrap |
| Tiny, local only, stable | Do not wrap |
Pitfalls
- A wrapper that leaks vendor types in its signatures is not a wrapper. Review the interface for imports.
- Do not hide initialisation inside the wrapper in a way that runs before consent. Make start explicit.
- Keep the wrapper small. If it grows business logic, split it.
Add a CI check that fails when vendor packages are imported outside the wrapper module. That enforces the boundary cheaply, and fits with an allowlist in CI.
Apple is clear that you are responsible for everything an SDK includes in your app and for knowing its data practices. A wrapper does not remove that responsibility, but it makes the practices easier to observe and constrain. Safeguard's dependency scanning and policies can complement it by reporting where a vendor package appears in a project.
Quick check
Does a wrapper reduce the SDK's own risk?
No. The vendor code still runs. It reduces your integration risk and makes control and replacement easier.
Is a wrapper worth it for a crash reporter?
Often yes, because it handles device data and is a common swap candidate. Keep the interface to a few methods.
Sources
Last reviewed: 19 October 2026.