MarketingCloudSDK.Net.iOS 11.0.2.3

dotnet add package MarketingCloudSDK.Net.iOS --version 11.0.2.3
                    
NuGet\Install-Package MarketingCloudSDK.Net.iOS -Version 11.0.2.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MarketingCloudSDK.Net.iOS" Version="11.0.2.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MarketingCloudSDK.Net.iOS" Version="11.0.2.3" />
                    
Directory.Packages.props
<PackageReference Include="MarketingCloudSDK.Net.iOS" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MarketingCloudSDK.Net.iOS --version 11.0.2.3
                    
#r "nuget: MarketingCloudSDK.Net.iOS, 11.0.2.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MarketingCloudSDK.Net.iOS@11.0.2.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MarketingCloudSDK.Net.iOS&version=11.0.2.3
                    
Install as a Cake Addin
#tool nuget:?package=MarketingCloudSDK.Net.iOS&version=11.0.2.3
                    
Install as a Cake Tool

MarketingCloudSDK.Net.iOS

NuGet release Targets: net8.0 | net9.0 | net10.0 MarketingCloudSDK 11.0.2 Licence: MIT AND BSD-3-Clause

.NET for iOS bindings for the Salesforce Marketing Cloud MobilePush framework (MarketingCloudSDK) — push registration, inbox, in-app messages and location messaging — at the v11 Unified SDK generation.

dotnet add package MarketingCloudSDK.Net.iOS
using Foundation;
using MarketingCloudSDK;
using SFMCSDK;

var pushConfig = new SFMarketingCloudSdkConfigBuilder("your-app-id")
    .SetAccessToken("your-access-token")
    // NSUrl, not a string - the builder takes the native type the header declares.
    .SetMarketingCloudServerUrl(new NSUrl("https://your-tenant.device.marketingcloudapis.com/"))
    .SetMid("your-mid")
    .Build();

var config = new SFMCSdkConfigBuilder().SetPushFeature(pushConfig).Build();
SFMCSdk.InitializeSdk(config, statuses => { });

// Contact key at v11 is a core identity edit, not a module call:
SFMCSdk.Identity.Edit(modifier => { modifier.ProfileId = "contact-key"; return modifier; });

// The sfmc_* category surface lives on MobilePushSDK (renamed from MarketingCloudSDK at v11).
// Selectors keep their sfmc_ prefix natively; the binding projects them without it:
var sdk = MobilePushSDK.SharedInstance;
var pushEnabled = sdk.IsPushEnabled;

The SFMC SDK core (SFMCSDK.Net.iOS) and the AppGroupSDK payload (MarketingCloudSDK.Net.AppGroupSDK.iOS) arrive as dependencies of this package, mirroring the native package manifests. Android lives in the sibling MarketingCloudSDK.Net.Android; a cross-platform ergonomic layer lives in MarketingCloudSDK.Net.


Contents

Packages

Package Wraps Depends on What it is for
MarketingCloudSDK.Net.iOS MarketingCloudSDK.xcframework 11.0.2 SFMCSDK.Net.iOS, MarketingCloudSDK.Net.AppGroupSDK.iOS Push registration, inbox, in-app messages, location
MarketingCloudSDK.Net.AppGroupSDK.iOS AppGroupSDK.xcframework 1.0.0 Payload-only: the internal app-group storage layer v11 requires; no API projected

Versions are <MarketingCloudSDK version>.<binding revision>11.0.2.3 is MarketingCloudSDK 11.0.2, binding revision 3. Both packages version together; AppGroupSDK's own native line (1.0.0) is pinned in Directory.Build.props.

What is bound, and how

By hand, never by Sharpie, descending from the hand-curated 8.x binding, ported to 11.0.2 by header diff and verified with a bidirectional selector-parity check (every selector in all ten headers bound, no stale selectors). The packed binding passes live smoke tests on a simulator — all three frameworks load together and a module-configured initialization is accepted by the core with its module roster intact.

What changed at v11, for consumers of the old 8.x packages:

  • The sfmc_* category surface moved from class MarketingCloudSDK to MobilePushSDK — same selectors, new class name.
  • PushConfig/PushConfigBuilder/SFMCSdkPushModule are replaced by SFMarketingCloudSdkConfig(Builder) attached via SFMCSdkConfigBuilder.SetPushFeature, and SFMarketingCloudSdk with RequestSdk(Action<IMarketingCloudSdkInterface>).
  • The URL-handling and event delegates left this framework (v4 SFMCSDK carries event-based replacements — SFMCSdkPushURLHandlingEvent and friends — and the new sfmc_handle*Event: hooks here feed them).
  • Device-token and notification-request setters left the category surface (the SDK observes them itself); the readers remain.

Installing

<PackageReference Include="MarketingCloudSDK.Net.iOS" Version="11.0.2.3" />

Target frameworks: net8.0-ios18.0, net9.0-ios18.0, net10.0-ios26.0. Floor: iOS 12.2.

Push prerequisites

The binding does not change what MobilePush itself needs: an APNs-entitled app (aps-environment), a UNUserNotificationCenter authorization request, RegisterForRemoteNotifications, and MobilePush app credentials. Never commit credentials; the sample takes them as runtime input.

How this repository works

Nothing native is committed. Salesforce commits the built xcframeworks into the repository trees (MarketingCloudSDK-iOS, app-group-internal-sdk) and attaches nothing to releases, so build/FetchXcFrameworks.sh downloads both tag archives and verifies every slice binary against the SHA-256 pins in build/checksums.txt — pins over binaries, not archives, because GitHub tag archives are not byte-stable.

build/BuildNugets.sh packs twice (net9 band, then net10 from a scratch global.json) and build/merge-packages.py grafts the net10 assets into each package. The native payloads ship as compressed .resources.zip.

Layout

Path What
src/Sfmc.Binding.props TFM bands, xcframework validation, packaging — a one-file port from the sibling SFMCSDK.Net.iOS
src/MarketingCloudSDK.Net.iOS/ ApiDefinitions.cs + StructsAndEnums.cs, hand-maintained
src/MarketingCloudSDK.Net.AppGroupSDK.iOS/ The payload-only sibling; its ApiDefinitions deliberately binds nothing
build/ Fetch, checksum, pack and upgrade scripts; packages.tsv is the roster
tests/ PackageTests and DeviceTests (a bare UIKit app driving the real SDK on a simulator)
samples/ A MAUI app driving configuration and registration
.github/workflows/ pr, release, auto-release, upstream-drift

Building locally

./build/FetchXcFrameworks.sh          # populate ./libs, checksum-verified
./build/BuildNugets.sh                # packs 11.0.2.3 into ./artifacts
dotnet test tests/MarketingCloudSDK.Net.iOS.PackageTests

SFMCSDK.Net.iOS restores from nuget.org, or from ./artifacts if you drop the sibling's package there.

Tests

dotnet test tests/MarketingCloudSDK.Net.iOS.PackageTests
./.github/scripts/run-simulator-tests.sh 11.0.2.3 net9.0-ios18.0

The simulator tests run without credentials on purpose: all three frameworks load (each probed by a real exported ObjC class name), a module-configured initializeSdk is accepted and the core's module roster still reports pushfeature with a parseable per-module shape, and the MobilePushSDK category surface answers.

What they cannot prove, and do not claim to: that the push module finished initializing. Measured on 11.0.2, an unprovisioned tenant leaves every module reading "status": "inactive" and the completion block never fires — and nothing in either state JSON reflects the configuration that was passed, so no credential-free assertion exists for it. That belongs to the manual checklist with a provisioned tenant and an APNs entitlement.

Upgrading the SFMC SDK

./build/BumpNativeVersion.sh 11.1.0

then port the header diff into ApiDefinitions.cs by hand — the script prints what it does not automate. Bump the sibling SFMCSDK.Net.iOS first when sfmc-sdk-ios moved; upstream-drift watches both repositories this package binds, and the sibling's package on nuget.org — a core release lands here as a re-pin of SfmcCorePackageVersion in Directory.Build.props and a binding-revision release.

Releasing

Merging a file named docs/release-notes/<four-part-version>.md to main is the release: auto-release tags it, release packs with verification off and publishes to nuget.org via trusted publishing. Every PR publishes a -beta.<pr>.<run> prerelease.

Troubleshooting

MarketingCloudSDK.xcframework is missing. Run ./build/FetchXcFrameworks.sh — nothing native is committed, and packing does not fetch.

Migrating 8.x code: MarketingCloudSDK (the class) does not exist. It is MobilePushSDK at v11 — the sfmc_* members are unchanged. See What is bound, and how for the config-builder replacement.

Xcode version errors building the net10 sample locally. The net10 iOS workload pins an exact Xcode line (CI selects Xcode_26.0); with a newer local Xcode, build the net9-band device tests instead.

Licence

The binding code in this repository is MIT. The native frameworks inside the packages are © Salesforce, BSD-3-Clause. The package licence expression is MIT AND BSD-3-Clause and both texts ship in every package under licenses/.

Product Compatible and additional computed target framework versions.
.NET net8.0-ios18.0 is compatible.  net9.0-ios was computed.  net9.0-ios18.0 is compatible.  net10.0-ios was computed.  net10.0-ios26.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on MarketingCloudSDK.Net.iOS:

Package Downloads
MarketingCloudSDK.Net

One cross-platform API for Salesforce Marketing Cloud MobilePush: awaitable initialization with real credentials, identity (contact key and attributes) via the SFMC SDK core, registration reads and tag/attribute edits on Android and iOS from shared code, over the MarketingCloudSDK.Net.Android and MarketingCloudSDK.Net.iOS bindings. Restores on plain target frameworks too, so shared class libraries and unit tests need no platform conditionals.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
11.0.2.3 149 7/30/2026
11.0.2.3-beta.7.11 51 7/30/2026
11.0.2.2 129 7/30/2026
11.0.2.2-beta.6.10 50 7/30/2026
11.0.2.2-beta.5.7 46 7/30/2026
11.0.2.2-beta.4.6 56 7/30/2026
11.0.2.1-beta.2.3 55 7/30/2026
8.1.3.8 1,941 10/30/2024
8.1.3.6 196 10/7/2024
8.1.2.10 186 7/12/2024
8.1.2.4 180 7/12/2024
8.1.2.3 214 5/20/2024
8.1.2.2 219 5/17/2024
8.1.1.81 497 2/28/2024
8.1.1.80 195 2/28/2024
8.1.1.79 219 2/22/2024
8.1.1.71 219 2/7/2024

## What's changed

A test-and-documentation revision on the same native line: `MarketingCloudSDK.xcframework` stays
**11.0.2**, `AppGroupSDK.xcframework` **1.0.0**, the core pin **SFMCSDK.Net.iOS 4.0.1.2**, and the
binding's projected API is byte-for-byte what `11.0.2.2` shipped. What changed is what the tests
prove and what the documentation claims.

### Fixed

- **The README quick-start did not compile.** `SetMarketingCloudServerUrl` takes an `NSUrl`, not a
 string, and there is no `Sfmc_setContactKey` member — the binding projects the selector as
 `SetContactKey`, and at v11 the contact key is a core identity edit anyway. The snippet now shows
 the `SFMCSdk.Identity.Edit` form, and it was compiled against the packed binding before landing.
- **The AppGroupSDK load check could not fail.** It probed for `AGSAppGroupCoordinator`, a guessed
 name that does not exist, and on not finding it logged "presence is proven by dyld not failing" and
 continued — so the framework could have been missing entirely and the check would still have
 passed. It now probes `SFMCAppDeviceInfo`, which `AppGroupSDK-Swift.h` declares as a real exported
 ObjC class (`SWIFT_CLASS_NAMED("AppDeviceInfo")`), and a null handle is a failure.
- **The initialization smoke test asserted nothing.** Its credential-free fallback was
 `state.Contains("pushfeature")`, and the core reports that module whether or not a push config was
 ever supplied — so it passed against a bare stub. It now parses the state JSON and asserts the
 `modules` object, the `pushfeature` entry and its per-module shape, which fails on a real upstream
 rename or restructure. The reported status is logged verbatim.
- **The README-version check ignored the core pin.** Its pattern only matched this repository's own
 package ids, so a `SFMCSDK.Net.iOS` pin in the README could name any version at all. It is now
 checked against `SfmcCorePackageVersion`.
- **The device-test app shared its bundle id with the sibling SFMCSDK.Net.iOS repository**
 (`com.sbokatuk.sfmcsdknet.devicetests`), so installing one replaced the other on a shared simulator
 and a local run of both repositories' suites could launch the wrong app. This one is now
 `com.sbokatuk.mcsdknet.devicetests`, matching its own sample's prefix.

### Documentation

- The README claimed the simulator tests prove "the module-configured `initializeSdk` completion
 fires with real statuses". They do not, and cannot without credentials: measured on 11.0.2, an
 unprovisioned tenant leaves every module reading `"status": "inactive"`, the completion block never
 fires, and nothing in either state JSON reflects the configuration that was passed. The README and
 the test suite's own summary now say what is actually proven, and name what belongs to the manual
 checklist instead.
- Removed copy-paste residue from the sibling DatadogNet repository: a `.gitignore` comment about
 "eleven Datadog xcframeworks", a `/Binding/` entry described as Objective Sharpie scratch output
 (this repository's headline rule is that Sharpie is never used), a duplicated `artifacts/` block,
 and a `NuGet.config` comment naming DatadogNet packages.

### Upgrading

Nothing to do — no API changed. `11.0.2.2` consumers can stay on it; the difference is in this
repository's own tests and documentation.