Xamarin.iOS / Xamarin.Mac / Xamarin.tvOS → .NET Migration
Use this skill when migrating Xamarin.iOS, Xamarin.Mac, or Xamarin.tvOS native apps (not Xamarin.Forms) to .NET for iOS, .NET for macOS, or .NET for tvOS.
Migration Workflow Overview
-
Create a new .NET for iOS/macOS/tvOS project
-
Convert project file to SDK-style format
-
Update MSBuild properties (MtouchArch, HttpClientHandler, code signing)
-
Migrate Info.plist values to csproj
-
Copy code and resources
-
Update NuGet dependencies
-
Migrate binding libraries (if applicable)
-
Set up Xamarin.Essentials replacement (if applicable)
-
Handle configuration file removal
-
Build, verify code signing, test on device
Migration Strategy
Create a new .NET project of the same type and name, then copy code into it. This is simpler than converting the existing project file in place.
Step 1 — SDK-Style Project File
.NET for iOS
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0-ios</TargetFramework> <OutputType>Exe</OutputType> <Nullable>enable</Nullable> <ImplicitUsings>true</ImplicitUsings> <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion> </PropertyGroup> </Project>
.NET for macOS (Mac Catalyst)
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0-macos</TargetFramework> <OutputType>Exe</OutputType> <Nullable>enable</Nullable> <ImplicitUsings>true</ImplicitUsings> <SupportedOSPlatformVersion>10.15</SupportedOSPlatformVersion> </PropertyGroup> </Project>
.NET for tvOS
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net8.0-tvos</TargetFramework> <OutputType>Exe</OutputType> <Nullable>enable</Nullable> <ImplicitUsings>true</ImplicitUsings> <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion> </PropertyGroup> </Project>
For library projects, omit <OutputType> or set to Library .
Replace net8.0 with net9.0 or net10.0 as appropriate. Valid TFMs: net8.0-ios , net8.0-macos , net8.0-tvos .
Step 2 — MSBuild Property Changes
Xamarin Property .NET Equivalent Action
MtouchArch / XamMacArch
RuntimeIdentifier / RuntimeIdentifiers
Convert (see table below)
HttpClientHandler / MtouchHttpClientHandler
UseNativeHttpHandler
Convert (see table below)
MtouchExtraArgs
(some still apply) Copy and test
EnableCodeSigning
(unchanged) Copy
CodeSigningKey
CodesignKey
Rename
CodesignKey
(unchanged) Copy
CodesignProvision
(unchanged) Copy
CodesignEntitlements
(unchanged) Copy
CodesignExtraArgs
(unchanged) Copy
PackageSigningKey
(unchanged) Copy
PackagingExtraArgs
(unchanged) Copy
ProductDefinition
(unchanged) Copy
MtouchEnableSGenConc
EnableSGenConc
Rename
LinkDescription
(unchanged) Copy
MtouchArch → RuntimeIdentifier (iOS)
MtouchArch Value RuntimeIdentifier RuntimeIdentifiers
ARMv7
ios-arm
ARMv7s
ios-arm
ARMv7+ARMv7s
ios-arm
ARM64
ios-arm64
ARMv7+ARM64
ios-arm;ios-arm64
ARMv7+ARMv7s+ARM64
ios-arm;ios-arm64
x86_64
iossimulator-x64
i386
iossimulator-x86
x86_64+i386
iossimulator-x86;iossimulator-x64
Use RuntimeIdentifiers (plural) when targeting multiple architectures.
MtouchArch → RuntimeIdentifier (macOS)
Value RuntimeIdentifier
x86_64
osx-x64
MtouchArch → RuntimeIdentifier (tvOS)
Value RuntimeIdentifier
ARM64
tvos-arm64
x86_64
tvossimulator-x64
HttpClientHandler Conversion
Xamarin Value UseNativeHttpHandler
HttpClientHandler
false
NSUrlSessionHandler
(don't set — default)
CFNetworkHandler
(don't set — default)
Step 3 — Info.plist Changes
MinimumOSVersion / LSMinimumSystemVersion
Move from Info.plist to the project file:
<!-- BEFORE (Info.plist) --> <key>MinimumOSVersion</key> <string>13.0</string>
<!-- AFTER (csproj) --> <PropertyGroup> <SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion> </PropertyGroup>
Other Info.plist entries (display name, bundle identifier, permissions, etc.) remain in Info.plist.
Step 4 — Copy Code and Resources
-
Copy source files, storyboards, XIBs, assets, and other resources from the Xamarin project to the new project.
-
Copy project properties (code signing, entitlements, linker settings) by comparing project files side-by-side.
-
Copy or merge any linker XML files (LinkDescription items).
Step 5 — Update NuGet Dependencies
Compatible Frameworks Incompatible Frameworks
net8.0-ios
monotouch , xamarinios , xamarinios10
net8.0-macos
monomac , xamarinmac , xamarinmac20
net8.0-tvos
xamarintvos
Unlike Android, there is no backward compatibility with old Xamarin iOS/Mac TFMs. Packages must be recompiled for net8.0-ios etc.
.NET Standard libraries without incompatible dependencies remain compatible.
If no compatible version exists:
-
Recompile with .NET TFMs (if you own it)
-
Look for a preview .NET version
-
Replace with a .NET-compatible alternative
Step 6 — iOS Binding Library Migration
For binding libraries wrapping Objective-C/Swift frameworks:
-
Use SDK-style project format with net8.0-ios TFM
-
The binding generator and API definitions work the same way
-
Verify that native frameworks are updated for the target iOS version
-
Test thoroughly — binding edge cases are common
Step 7 — Xamarin.Essentials in Native Apps
If your Xamarin.iOS app used Xamarin.Essentials:
-
Remove the Xamarin.Essentials NuGet package
-
Add <UseMauiEssentials>true</UseMauiEssentials> to your project file
-
Initialize in your AppDelegate:
using Microsoft.Maui.ApplicationModel;
[Register("AppDelegate")] public class AppDelegate : UIApplicationDelegate { public override UIWindow? Window { get; set; }
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var vc = new UIViewController();
Window.RootViewController = vc;
Platform.Init(() => vc);
Window.MakeKeyAndVisible();
return true;
}
}
- Update using directives:
Xamarin.Essentials .NET MAUI Namespace
App actions, permissions, version tracking Microsoft.Maui.ApplicationModel
Contacts, email, networking Microsoft.Maui.ApplicationModel.Communication
Battery, sensors, flashlight, haptics Microsoft.Maui.Devices
Media picking, text-to-speech Microsoft.Maui.Media
Clipboard, file sharing Microsoft.Maui.ApplicationModel.DataTransfer
File picking, secure storage, preferences Microsoft.Maui.Storage
- For app actions, override PerformActionForShortcutItem :
public override void PerformActionForShortcutItem( UIApplication application, UIApplicationShortcutItem shortcutItem, UIOperationHandler completionHandler) { Platform.PerformActionForShortcutItem(application, shortcutItem, completionHandler); }
Step 8 — Configuration Files
There is no support for .dll.config or .exe.config files in .NET for iOS/macOS. <dllmap> elements are not supported in .NET Core. Migrate configuration to appsettings.json , embedded resources, or platform preferences.
Step 9 — watchOS
Xamarin.watchOS is not supported in .NET. The recommendation is to bundle Swift extensions with .NET for iOS apps instead.
Step 10 — Unsupported Projects
Project Type Status
Xamarin.iOS ✅ Supported
Xamarin.Mac ✅ Supported
Xamarin.tvOS ✅ Supported
iOS App Extensions ✅ Supported
SpriteKit / SceneKit / Metal ✅ Supported
Xamarin.watchOS ❌ Not supported
OpenGL (iOS) ❌ Not supported (OpenTK unavailable)
Build and Troubleshoot
-
Delete all bin/ and obj/ folders
-
Build and fix compiler errors iteratively
-
Verify code signing settings match your provisioning profiles
-
Test on physical devices (especially for App Store builds)
Common issues:
-
Namespace not found: Replace Xamarin.iOS /UIKit imports — most UIKit namespaces remain the same, but verify against the .NET for iOS API surface.
-
Linker errors: Update LinkDescription XML files if custom linker configuration was used. The linker behavior is similar but stricter in .NET.
-
Entitlements: Ensure CodesignEntitlements points to the correct file.
API Currency Note
If your migrated app will also adopt .NET MAUI controls (e.g., via UseMaui ), check the maui-current-apis skill for deprecated MAUI APIs to avoid (ListView, Frame, Device.*, etc.).
Quick Checklist
-
☐ Created new .NET for iOS/macOS/tvOS project
-
☐ Set TargetFramework to net8.0-ios (or net8.0-macos /net8.0-tvos )
-
☐ Set SupportedOSPlatformVersion (moved from Info.plist)
-
☐ Converted MtouchArch → RuntimeIdentifier(s)
-
☐ Converted HttpClientHandler → UseNativeHttpHandler
-
☐ Renamed CodeSigningKey → CodesignKey (if applicable)
-
☐ Renamed MtouchEnableSGenConc → EnableSGenConc (if applicable)
-
☐ Copied source, resources, storyboards, entitlements
-
☐ Updated NuGet dependencies for net8.0-ios compatibility
-
☐ Added UseMauiEssentials if using Essentials
-
☐ Removed .dll.config files (not supported)
-
☐ Deleted bin/ and obj/ folders
-
☐ Verified code signing and provisioning
-
☐ Tested on physical device