将绑定迁移到 Unified API
本文提供必要步骤,介绍如何更新现有 Xamarin 绑定项目来支持对 Xamarin.IOS 和 Xamarin.Mac 应用程序使用 Unified API。
概述
从 2015 年 2 月 1 日起,Apple 要求向 iTunes 和 Mac App Store 提交的所有新内容都必须是 64 位应用程序。 因此,为了支持 64 位,所有新的 Xamarin.iOS 或 Xamarin.Mac 应用程序都需要使用新的 Unified API 而不是现有的 Classic MonoTouch 和 MonoMac API。
此外,所有 Xamarin 绑定项目也必须支持要包含在 64 位 Xamarin.iOS 或 Xamarin.Mac 项目中的新的 Unified API。 本文将介绍更新现有绑定项目来使用 Unified API 所需的步骤。
要求
要完成本文所述的步骤,需要满足以下条件:
- Visual Studio for Mac - 在开发计算机上安装和配置的最新版本的 Visual Studio for Mac。
- Apple Mac - 要生成适用于 iOS 和 Mac 的绑定项目,需要使用 Apple Mac。
Windows 计算机上的 Visual Studio 不支持绑定项目。
修改 Using 语句
借助 Unified API,可在 Mac 和 iOS 之间比以往更轻松地共享代码,还能使用相同的二进制文件支持 32 和 64 位应用程序。 通过从命名空间中删除 MonoMac 和 MonoTouch 前缀,可以跨 Xamarin.Mac 和 Xamarin.iOS 应用程序项目更简单地进行共享。
因此,我们需要修改我们的所有绑定协定(以及绑定项目中的其他 .cs
文件),以便从 using
语句中删除 MonoMac 和 MonoTouch 前缀。
例如,给定绑定协定中的以下 using 语句:
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.ObjCRuntime;
我们将删除 MonoTouch
前缀,结果如下所示:
using System;
using System.Drawing;
using Foundation;
using UIKit;
using ObjCRuntime;
同样,我们需要对绑定项目中的所有 .cs
文件执行此操作。 完成此更改后,下一步是更新绑定项目以使用新的原生数据类型。
有关 Unified API 的详细信息,请参阅 Unified API 文档。 有关支持 32 位和 64 位应用程序的更多背景信息和框架相关信息,请参阅 32 位和 64 位平台注意事项文档。
更新到原生数据类型
Objective-C 在 32 位系统上将 NSInteger
数据类型映射到 int32_t
,在 64 位系统上则映射到 int64_t
。 为了匹配此行为,新的 Unified API 将以前使用的 int
(它在 .NET 中定义为始终是 System.Int32
)替换为新的数据类型:System.nint
。
除了新的 nint
数据类型,Unified API 还引入了 nuint
和 nfloat
,用于映射到 NSUInteger
和 CGFloat
类型。
鉴于上述情况,我们需要查看 API,并确保之前映射到的 int
、uint
和 float
的 NSInteger
、NSUInteger
和 CGFloat
的任何实例都更新为新的 nint
、nuint
和 nfloat
类型。
例如,给定 Objective-C 方法定义如下:
-(NSInteger) add:(NSInteger)operandUn and:(NSInteger) operandDeux;
如果上一个绑定协定具有以下定义:
[Export("add:and:")]
int Add(int operandUn, int operandDeux);
我们会更新新绑定,使其如下所示:
[Export("add:and:")]
nint Add(nint operandUn, nint operandDeux);
如果我们要映射到比最初链接到的版本更新的第三方库,我们需要查看库的 .h
头文件,并查看对 int
、int32_t
、unsigned int
、uint32_t
或 float
的任何现有显式调用是否已更新为 NSInteger
、NSUInteger
或 CGFloat
。 如果已经更新,需要对 nint
、nuint
和 nfloat
类型和其映射进行相同的修改。
若要详细了解这些数据类型的变化,请参阅原生类型文档。
更新 CoreGraphics 类型
与 CoreGraphics
一起使用的点、大小和矩形数据类型根据运行它们的设备来使用 32 或 64 位。 当 Xamarin 最初绑定 iOS 和 Mac API 时,我们使用了与 System.Drawing
中的数据类型匹配的现有数据结构(例如 RectangleF
)。
由于需要支持 64 位和新的原生数据类型,因此在调用 CoreGraphic
方法时,需要对现有代码进行以下调整:
- CGRect - 在定义浮点矩形区域时使用
CGRect
而不是RectangleF
。 - CGSize - 在定义浮点大小(宽度和高度)时使用
CGSize
而不是SizeF
。 - CGPoint - 在定义浮点位置(X 和 Y 坐标)时使用
CGPoint
而不是PointF
。
鉴于上述情况,我们需要查看 API,并确保之气绑定到 RectangleF
、SizeF
或 PointF
的 CGRect
、CGSize
或 CGPoint
的任何实例直接更改为原生类型 CGRect
、CGSize
或 CGPoint
。
例如,给定下述项的 Objective-C 初始值设定项:
- (id)initWithFrame:(CGRect)frame;
如果上一个绑定包含以下代码:
[Export ("initWithFrame:")]
IntPtr Constructor (RectangleF frame);
我们会将该代码更新为:
[Export ("initWithFrame:")]
IntPtr Constructor (CGRect frame);
现在所有代码更改都已到位,我们需要修改绑定项目或使文件绑定到 Unified API。
修改绑定项目
在更新绑定项目来使用 Unified API 的步骤中,最后我们需要修改用于生成项目的 MakeFile
或者 Xamarin 项目类型(如果我们从 Visual Studio for Mac 中进行绑定),并指示 btouch 绑定到 Unified API 而不是 Classic API。
更新生成文件
如果使用生成文件将绑定项目生成到 Xamarin .DLL,则需要包含 --new-style
命令行选项,并调用 btouch-native
而不是 btouch
。
因此,给定以下 MakeFile
:
BINDDIR=/src/binding
XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=XMBindingLibrarySample
PROJECT=$(PROJECT_ROOT)/XMBindingLibrarySample.xcodeproj
TARGET=XMBindingLibrarySample
BTOUCH=/Developer/MonoTouch/usr/bin/btouch
all: XMBindingLibrary.dll
libXMBindingLibrarySample-i386.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(TARGET).a $@
libXMBindingLibrarySample-arm64.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch arm64 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@
libXMBindingLibrarySample-armv7.a:
$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch armv7 -configuration Release clean build
-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@
libXMBindingLibrarySampleUniversal.a: libXMBindingLibrarySample-armv7.a libXMBindingLibrarySample-i386.a libXMBindingLibrarySample-arm64.a
lipo -create -output $@ $^
XMBindingLibrary.dll: AssemblyInfo.cs XMBindingLibrarySample.cs extras.cs libXMBindingLibrarySampleUniversal.a
$(BTOUCH) -unsafe -out:$@ XMBindingLibrarySample.cs -x=AssemblyInfo.cs -x=extras.cs --link-with=libXMBindingLibrarySampleUniversal.a,libXMBindingLibrarySampleUniversal.a
clean:
-rm -f *.a *.dll
我们需要从调用 btouch
切换到调用 btouch-native
,因此我们将按如下所示调整宏定义:
BTOUCH=/Developer/MonoTouch/usr/bin/btouch-native
我们将更新对 btouch
的调用并添加 --new-style
选项,如下所示:
XMBindingLibrary.dll: AssemblyInfo.cs XMBindingLibrarySample.cs extras.cs libXMBindingLibrarySampleUniversal.a
$(BTOUCH) -unsafe --new-style -out:$@ XMBindingLibrarySample.cs -x=AssemblyInfo.cs -x=extras.cs --link-with=libXMBindingLibrarySampleUniversal.a,libXMBindingLibrarySampleUniversal.a
现在,我们可以像平常一样执行 MakeFile
来生成新的 64 位版本的 API。
更新绑定项目类型
如果使用 Visual Studio for Mac 绑定项目模板来生成 API,需要更新到绑定项目模板新的 Unified API 版本。 执行此操作的最简单方法是启动新的 Unified API 绑定项目,并复制所有现有代码和设置。
请执行以下操作:
启动 Visual Studio for Mac。
选择“文件”>“新建”>“解决方案...”
在“新建解决方案”对话框中,选择“iOS”>“Unified API”>“iOS 绑定项目”:
在“配置新项目”对话框中,输入新绑定项目的名称,然后单击“确定”按钮。
添加要为其创建绑定的 Objective-C 库的 64 位版本。
从现有 32 位 Classic API 绑定项目复制源代码(如
ApiDefinition.cs
和StructsAndEnums.cs
文件)。对源代码文件进行上述更改。
完成所有这些更改后,可以像生成 32 位版本一样生成新的 64 位版本的 API。
总结
在本文中,我们介绍了需要对现有 Xamarin 绑定项目进行哪些更改来支持新的 Unified API 和 64 位设备,还介绍了生成新的 64 位兼容 API 版本所需的步骤。