Содержание
- Upgrading the project file
- The SDK assemblies have been renamed.
- Removed the System.nint and System.nuint types.
- Removed the System.nfloat type.
- System.NMath moved to ObjCRuntime.NMath
- NSObject.Handle and INativeObject.Handle changed type from System.IntPtr to ObjCRuntime.NativeHandle
- The SceneKit.SCNMatrix4 matrix is transposed in memory.
- Some types were moved from the CoreServices namespace to the CFNetwork namespace.
- Numerous types in ModelIO have corrected their API.
- Removed the property ObjCRuntime.Runtime.UseAutoreleasePoolInThreadPool.
- Moved types NSFileProviderExtension and NSFileProviderExtensionFetchThumbnailsHandler from UIKit to NSFileProvider.
- The Foundation.MonoTouchException and Foundation.ObjCException types have been renamed/moved to ObjCRuntime.ObjCException.
- The type CFNetwork.MessageHandler has been removed.
- Changed name of the Info.plist entry with our version number.
- macOS: Different current directory at launch
- iOS: dropped support for ARMv7s
- Environment.OSVersion returns the actual OS version.
- MulticastDelegate.BeginInvoke throws a PlatformNotSupportedException.
- Type.IsInterface now returns a different value reference types.
- The WeakAttribute is not supported.
- Environment.SpecialFolder.ProgramFiles maps to NSSearchPathDirectory.ApplicationDirectory
- Reflection-only assembly loads are not supported
- Incompatible NuGets
- CFNetworkHandler
- Remapping P/Invoke to a different native library using a config file (dllmap) is no longer supported.
- Files are locked by default in .NET
Existing Xamarin.iOS and Xamarin.Mac projects and assemblies are not compatible with the .NET SDKs, and will have to be modified and recompiled.
In particular:
- Existing code will most likely require a few changes to compile. This document lists some of the most important modifications to our public API, for a complete listing of the API difference look at the documents here.
- Existing NuGets targeting the
xamarinios10
,xamarinmac20
orxamarintvos10
target frameworks will not work in .NET. These NuGets will have to be updated to (multi-)targetnet6.0-ios
,net6.0-macos
ornet6.0-tvos
instead.
For a more in-depth discussion about why we chose to break the managed API in .NET, please refer to: https://github.com/xamarin/xamarin-macios/issues/13087.
Upgrading the project file
The new project files are much simpler, and can easily be edited in a text editor. This is a very simple macOS project, which only contains a target framework property stating we're building using the macOS SDK, and the OutputType
property to indicate that we're building an app bundle.
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-macos</TargetFramework> <!-- Other target frameworks: `net6.0-ios`, `net6.0-tvos` and `net6.0-maccatalyst` -->
<OutputType>Exe</OutputType>
</PropertyGroup>
</Project>
There's no need to list any source files, resources will be picked up automatically, and other configuration have default values that work for most cases. The typical upgrade path is to start with a bare bones project file like the above, and then copy over any specific customizations.
The '${ProjectDir}' variable is no longer supported in project files.
It was possible to use the variable ${ProjectDir}
in project files to refer
to the full path of the directory where the project file was located.
This is no longer supported: use the standard MSBuild property
$(MSBuildProjectDirectory)
instead (note that MSBuild properties uses
parenthesis, not curly brackets like in ${ProjectDir}
).
The SDK assemblies have been renamed.
We've renamed the SDK assemblies like this:
Xamarin.iOS.dll
->Microsoft.iOS.dll
Xamarin.TVOS.dll
->Microsoft.tvOS.dll
Xamarin.Mac.dll
->Microsoft.macOS.dll
This will affect:
- Code using reflection with a hardcoded assembly name.
- Custom linker configuration files, since they contain the assembly name.
In any case when upgrading a project file manually, the reference to Xamarin.iOS
, Xamarin.Mac
or Xamarin.TVOS
can just be removed, the corresponding .NET assembly is automatically referenced.
Removed the System.nint
and System.nuint
types.
The two types System.nint
and System.nuint
(which despite their System
namespace were shipped with Xamarin.iOS/Xamarin.Mac) have been removed in
favor of the C# 9 nint
and nuint
types (these map to System.IntPtr
and
System.UIntPtr
respectively).
-
Code that uses these types with the full namespace (
System.nint
/System.nuint
) won't compile.Example:
public void DoSomething (System.nint value) {}
Fix: remove the namespace, and use
nint
/nuint
only:public void DoSomething (nint value) {}
-
Code that overloads on
System.IntPtr
/System.UIntPtr
andnint
/nuint
won't compile.Example:
public void DoSomething (IntPtr value) {} public void DoSomething (nint value) {}
Fix: one of the overloads must be either renamed or removed.
Reference: https://github.com/xamarin/xamarin-macios/issues/10508
Removed the System.nfloat
type.
The System.nfloat
type has been removed in favor of the
System.Runtime.InteropServices.NFloat
type.
In order to make existing code compile as much as possible, we're adding a
global using directive to C# projects, so that using nfloat
as a type name
continues to work:
global using nfloat = System.Runtime.InteropServices.NFloat;
If this global using directive is undesirable, it can be turned off by setting
a NoNFloatUsing=true
property in the project file.
Also, we're only adding the global using directive for projects that target C# 10 or later (since that's the first C# version that supports global using directives). Projects that use an older C# version will have to manually add the using directive to every source file.
There are a few other source code incompatibilities:
-
Any code that refers to the full typename (
System.nfloat
) will have to be modified to just usenfloat
, or the new full typename (System.Runtime.InteropServices.NFloat
).Example:
public void DoSomething (System.nfloat value) {}
Fixed option 1:
public void DoSomething (nfloat value) {}
Fixed option 2:
public void DoSomething (System.Runtime.InteropServices.NFloat value) {}
-
The
nfloat.CopyArray
methods don't exist inNFloat
. The code needs to be rewritten to useBuffer.CopyMemory
instead.
System.NMath
moved to ObjCRuntime.NMath
The NMath
type moved from the System
namespace to the ObjCRuntime
namespace.
-
Code that uses the
NMath
type won't compile unless theObjCRuntime
namespace is imported.public nint DoSomething (nint value) { return NMath.Abs (value) + 42; }
Fix: add
using ObjCRuntime
to the file in question, or as a global using directive.using ObjCRuntime; public nint DoSomething (nint value) { return NMath.Abs (value) + 42; }
-
Alternatively use the methods in the
System.Math
type instead, since are now overloads there that takenint
andnuint
:Fix:
public nint DoSomething (nint value) { return Math.Abs (value) + 42; }
NSObject.Handle and INativeObject.Handle changed type from System.IntPtr to ObjCRuntime.NativeHandle
The NSObject.Handle
and INativeObject.Handle
properties changed type from
System.IntPtr
to a custom struct: ObjCRuntime.NativeHandle
. This also means that numerous
other parameters and return values change type in the same way; most important
are the constructors that previously took a System.IntPtr
, or
System.IntPtr
+ bool
. Both variants now take a ObjCRuntime.NativeHandle
instead.
This is so that we can support API that take native-sized integers (nint
/
nuint
- which map to System.[U]IntPtr
) while at the same time have a
different overload that takes a handle.
The most common examples are constructors - all NSObject
subclasses have a
constructor that (now) take a single ObjCRuntime.NativeHandle
parameter, and
some types also need to expose a constructor that take a native-sized integer.
For instance NSMutableString
has a nint capacity
constructor, which
without this type change would be impossible to expose correctly.
There are implicit conversions between System.IntPtr
and
ObjCRuntime.NativeHandle
, so most code should compile without changes.
The SceneKit.SCNMatrix4 matrix is transposed in memory.
The managed SCNMatrix4 struct used to be a row-major matrix, while the native SCNMatrix4 struct is a column-major matrix. This difference in the memory representation meant that matrices would often have to be transposed when interacting with the platform.
In .NET, we've changed the managed SCNMatrix4 to be a column-major matrix, to match the native version. This means that any transposing that's currently done when accessing Apple APIs has to be undone.
Note: last-minute we've discovered that numerous other SCNMatrix4 APIs are incorrect. We'll probably fix these in a service release (no decision has been made yet). Updates will be posted on the issue in question.
Ref: https://github.com/xamarin/xamarin-macios/issues/15094
Some types were moved from the CoreServices namespace to the CFNetwork namespace.
The following types:
CFHTTPStream
CFHTTPMessage
CFHTTPAuthentication
were moved from the CoreServices
namespace to the CFNetwork
namespace.
This requires adding a using CFNetwork;
statement to any files that uses these types.
Numerous types in ModelIO have corrected their API.
When we originally implemented ModelIO, we didn't notice at first that some of the matrix types Apple used had a column-major layout, so we accidentally bound many API with the wrong matrix type (with a row-major layout). This was troublesome, because many matrices had to be transposed for code to work correctly. We re-implemented all the API with the correct matrix type, but named differently (and worse). In .NET we've removed all the incorrectly bound API, and we've renamed the correctly bound API to use the best name (usually reflecting how Apple named these APIs).
This affects methods and properties on the following classes:
MDLCamera
MDLMaterialProperty
MDLStereoscopicCamera
MDLTransform
MDLTransformComponent
Removed the property ObjCRuntime.Runtime.UseAutoreleasePoolInThreadPool
.
The property Runtime.UseAutoreleasePoolInThreadPool has been removed.
Enabling or disabling this feature is not supported at runtime and must
be done at build time using the MSBuild AutoreleasePoolSupport
property instead.
You can query if the build-time feature is enabled with the following code:
AppContext.TryGetSwitch ("System.Threading.Thread.EnableAutoreleasePool", out var enabled);
Moved types NSFileProviderExtension
and NSFileProviderExtensionFetchThumbnailsHandler
from UIKit
to NSFileProvider
.
The types NSFileProviderExtension
and
NSFileProviderExtensionFetchThumbnailsHandler
moved from the UIKit
namespace to the NSFileProvider
namespace (this is reflecting that Apple
originally added these types to UIKit
, but then moved them to their own
namespace, NSFileExtension
).
The Foundation.MonoTouchException
and Foundation.ObjCException
types have been renamed/moved to ObjCRuntime.ObjCException
.
The type Foundation.MonoTouchException
(for iOS and tvOS) and
the type Foundation.ObjCException
(for macOS) have been renamed/moved to
ObjCRuntime.ObjCException
. Both types had the exact same functionality: they
were wrapping a native NSException, and were renamed so that we have identical
API and behavior on all platforms.
The type CFNetwork.MessageHandler
has been removed.
The type CFNetwork.MessageHandler
has been removed. Please use
System.Net.Http.CFNetworkHandler
or the more recent
Foundation.NSUrlSessionHandler
instead.
Changed name of the Info.plist entry with our version number.
We add an entry to the app's Info.plist with the version number used to build
the app. In .NET, we've changed the name of this entry from com.xamarin.ios
to com.microsoft.<platform in lower case>
(for instance com.microsoft.tvos
for tvOS apps).
The version format has also changed, from "X.Y.Z.W (branch
: hash
)" to the
semantic versioning we use for .NET: "X.Y.Z-branch
+sha.hash
".
macOS: Different current directory at launch
The current directory at startup is different for macOS applications (it's now the root directory in the app bundle, instead of the Contents/Resources
subdirectory), to get the same behavior between all our platforms.
Ref: https://github.com/xamarin/xamarin-macios/pull/12104.
iOS: dropped support for ARMv7s
Support for the 32-bit ARMv7s architecture has been dropped. We still support the 32-bit ARMv7 architecture.
Environment.OSVersion returns the actual OS version.
Environment.OSVersion now returns the public-facing OS version (for instance 12.3.1
for macOS), instead of the version of the kernel (which would be 21.4.0.0
for macOS 12.3.1).
Ref: https://github.com/dotnet/runtime/issues/34977.
MulticastDelegate.BeginInvoke throws a PlatformNotSupportedException.
- Ref: https://github.com/dotnet/runtime/issues/16312
- Ref: https://devblogs.microsoft.com/dotnet/migrating-delegate-begininvoke-calls-for-net-core/
Type.IsInterface now returns a different value reference types.
Example:
interface I {}
Console.WriteLine (typeof (I).MakeByRefType ().IsInterface);
This will return False
now, when it used to return True
in Xamarin.iOS and Xamarin.Mac
Ref: https://github.com/dotnet/runtime/issues/39068
The WeakAttribute is not supported.
The [Weak]
attribute is no longer supported. Code will have to be refactored to use either a WeakReference
or a GCHandle
.
Ref: https://github.com/dotnet/runtime/issues/68702
Environment.SpecialFolder.ProgramFiles maps to NSSearchPathDirectory.ApplicationDirectory
Environment.SpecialFolder.ProgramFiles maps to NSSearchPathDirectory.ApplicationDirectory (as opposed to /Applications
in Xamarin.iOS).
Reflection-only assembly loads are not supported
Reflection-only assembly loads are not supported in .NET 5+.
Ref: https://github.com/dotnet/runtime/issues/7273
Incompatible NuGets
The following NuGets are incompatible with .NET 6:
- System.Data.SqlClient (use Microsoft.Data.SqlClient instead)
- System.Json (use System.Text.Json instead)
- System.Xml.XPath.XmlDocument
Ref: https://github.com/dotnet/designs/pull/222
CFNetworkHandler
It's no longer possible to select CFNetworkHandler
as the default http handler (it's still possible to manually pass it to HttpClient
).
Remapping P/Invoke to a different native library using a config file (dllmap) is no longer supported.
Remapping P/Invoke to a different native library using a config file (dllmap) is not supported in .NET.
There are two potential solutions:
- Use the correct name for the native library in the P/Invoke.
- Use a custom DllImport resolver at runtime: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary.setdllimportresolver?view=netcore-3.0
Files are locked by default in .NET
Files are locked by default when they're opened in .NET (using advisory locks), while legacy Xamarin did not acquire any kind of file locks.
This has a potential effects if an app has open files, and is then minimized / backgrounded, because iOS will terminate backgrounded apps if the app has a file lock (crash reports will show that the app was killed with termination reason 0xdead10cc, and the device log will show which file is locked).
There are two possible workarounds:
-
Disable file locking (i.e. get Xamarin's behavior in .NET) by adding the following to the project file:
<ItemGroup> <RuntimeHostConfigurationOption Include="System.IO.DisableFileLocking" Value="true" /> </ItemGroup>
-
Close the files in question when the app is backgrounded.
References:
Contributing
Bindings
- README
- xcode13.0 Binding Status
- xcode13.1 Binding Status
- xcode13.2 Binding Status
- xcode13.3 Binding Status
- xcode13.4 Binding Status
- xcode14.0 Binding Status
- xcode14.1 Binding Status
- xcode14.2 Binding Status
- xcode14.3 Binding Status
- xcode15.0 Binding Status
- xcode15.1 Binding Status
- xcode15.3 Binding Status
- xcode15.4 Binding Status
- xcode16.0 Binding Status
- xcode16.1 Binding Status