watchOS SDK
watchOS SDK
Section titled “watchOS SDK”Build Apple Watch apps in C# with an MSBuild Project SDK. Consumer projects do not need Swift sources.
Package identity
Section titled “Package identity”| Item | Value |
|---|---|
NuGet / MSBuild SDK PackageId (shipping) |
WatchOS.Sdk |
| Project SDK attribute | WatchOS.Sdk |
| TFM | net10.0-watchos (platform version 26.0) |
| Spec catalog name | AvantiPoint.WatchOS.Sdk |
Pin the SDK via global.json msbuild-sdks (do not pin a .NET sdk.version for this product):
{ "msbuild-sdks": { "WatchOS.Sdk": "26.0.1" }}Use a real released version string when you publish; do not leave an unresolvable placeholder.
Source of truth: the Apple.Sdk / WatchOS.Sdk tree README and status docs on the engineering machine. Public mirror today: AvantiPoint/WatchOS.Sdk. Prefer that README over this page when they disagree.
Project SDK usage
Section titled “Project SDK usage”Minimal watch head (from the WatchOS.Sdk app skill / project-shape reference):
<Project Sdk="WatchOS.Sdk"> <PropertyGroup> <TargetFramework>net10.0-watchos</TargetFramework> <OutputType>Exe</OutputType> <ApplicationTitle>Watch</ApplicationTitle> <SupportedOSPlatformVersion>26.0</SupportedOSPlatformVersion> </PropertyGroup></Project>Companion phone project (MAUI / Uno / net*-ios): keep the phone’s existing Sdk=. Add a plain project reference — no second <Sdk>, no special metadata:
<ItemGroup> <ProjectReference Include="..\MyApp.Watch\MyApp.Watch.csproj" /></ItemGroup>Import WatchOS.Phone.targets from the nearest Directory.Build.targets so the iOS inner TFM embeds Watch/*.app and supplies companion application id / version. On Android phone TFMs the watch reference is pruned.
Default resources (no ItemGroup required when defaults are on):
Resources/AppIcon/** → WatchIconResources/Images/** → WatchImageResources/Fonts/** → WatchFontResources/Raw/** → WatchAssetNative AOT path
Section titled “Native AOT path”Watch managed runtime for v1 is Native AOT for watchsimulator-arm64 / watchos-arm64 — not Mono JIT on device, and not consuming Microsoft.NETCore.App.Runtime.NativeAOT.ios-*.
Verified go/no-go sample in-tree: sample/HelloWatchRuntime.
dotnet publish -f net10.0-watchos -r watchsimulator-arm64 -c ReleaseSuccess criteria used by engineering:
- Linked process is
PLATFORM_WATCHOSSIMULATOR(otool platform 9) - Link line does not mention
Microsoft.NETCore.App.Runtime.NativeAOT.ios-orMicrosoft.iOS.Runtime - Simulator spawn logs the Native AOT entry (
watchos_start/IsWatchOS=true)
Publish-time properties on that sample include PublishAot, WatchOSRequireNativeAot, and related WatchOS.Sdk switches. See the sample csproj in WatchOS.Sdk — do not invent additional public AOT APIs here.
Windows hosts: restore + compile managed code only. Producing a .app or running the simulator requires Mac + Xcode.
Simulator vs device (honesty)
Section titled “Simulator vs device (honesty)”| Surface | Status |
|---|---|
| Watch simulator — C# UI / Native AOT path | Works (engineering go/no-go + app samples on Mac) |
| Physical device | Unverified — do not claim device parity or production device install |
| Mac inner loop | Paired iOS Simulator + Watch Simulator (watchsimulator-arm64 default on Apple Silicon) |
| Toolchain baseline | Xcode 26.6 (CI pins MAUI/iOS workload set 10.0.302 on the Mac pack/sample agents) |
Mac packaging still uses generated Info.plist and, where Native AOT packaging is incomplete for a given sample, an SDK-owned Swift @main host. That is an SDK implementation detail. Consumer application projects stay C# — zero Swift in the app author’s project.
Bindings, CoreLib, and catalogs
Section titled “Bindings, CoreLib, and catalogs”- Platform surface ships as
WatchOS.CoreLibinside theWatchOS.Sdknupkg (bindings/), referenced by the SDK — not as a separate consumerPackageReference. - Do not PackageReference
WatchOS.CoreLib. - Automatic binding catalog remains unpromoted — do not market generated catalogs as a product surface until engineering promotes them.
- Namespaces follow Apple modules (Foundation, SwiftUI-in-C#, WatchKit, WatchConnectivity, HealthKit, …) as exposed by CoreLib.
Extras containment
Section titled “Extras containment”For containing iOS / MAUI / Uno phone heads that host a watch companion, use the shared Apple extras package when your feed provides it (AvantiPoint.Apple.Extras in portfolio docs). WatchOS.Sdk itself does not replace phone SDKs. See Apple SDKs overview for the package table.
Templates and samples
Section titled “Templates and samples”In AvantiPoint/WatchOS.Sdk:
| Path | Role |
|---|---|
sample/HelloWatch + sample/HelloWatch.Watch |
MAUI phone + Depth watch companion (Crown, haptics, WCSession) |
sample/HelloWatchRuntime |
Native AOT simulator go/no-go |
skills/watchos-app |
Agent/developer project-shape rules |
skills/watchos-sdk |
SDK pack / CI / Native AOT rules |
WristUI single-project templates (AvantiPoint.WristUI.Sdk) are see WristUI.Sdk overview.
Known limits
Section titled “Known limits”- Physical device execution unverified.
- WidgetKit and App Clips are separate SDKs — not pulled in automatically by every watch project.
- No promise of Pair-to-Mac remoting from Windows for
.appproduction. - No claim that stock Android packages are Wear-compatible (Wear is a different SDK).
- Do not PackageReference native assemblies the SDK already injects.
- Automatic binding catalog: unpromoted.
