バインドの Unified API への移行

この記事では、Xamarin.IOS および Xamarin.Mac アプリケーションの Unified API をサポートするための、既存の Xamarin バインド プロジェクトの更新に必要な手順について説明します。

概要

2015 年 2 月 1 日より、Apple では、iTunes と Mac App Store へのすべての新しい申請は 64 ビット アプリケーションであることが必要とされています。 その結果、新しい Xamarin.iOS または Xamarin.Mac アプリケーションでは、既存のClassic MonoTouch および MonoMac API ではなく新しい Unified API を使用して 64 ビットをサポートする必要があります。

さらに、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 アプリケーション プロジェクト間での共有がよりシンプルになります。

その結果、using ステートメントから MonoMac および MonoTouch プレフィックスを削除するために、バインディング コントラクト (およびバインド プロジェクト内の他の .cs ファイル) を変更する必要があります。

たとえば、バインディング コントラクトで次の 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 は、NSInteger データ型を 32 ビット システムの int32_t と、64 ビット システムの int64_t にマップします。 この動作を一致させるために、新しい Unified API は、以前の int の使用 (.NET では常に System.Int32 と定義されています) を新しいデータ型である System.nint に置き換えます。

Unified API では、新しい nint データ型と共に、NSUIntegerCGFloat 型にマッピングするための nuintnfloat 型も導入されています。

以上のことから、API を確認し、以前に intuintfloat にマップした NSIntegerNSUIntegerCGFloat のインスタンスが新しい nintnuintnfloat 型に更新されるようにする必要があります。

たとえば、次の 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 ヘッダー ファイルを確認し、intint32_tunsigned intuint32_tfloat への既存の終了する明示的な呼び出しが、NSIntegerNSUIntegerCGFloat にアップグレードされているかどうかを確認する必要があります。 その場合は、nintnuintnfloat の型に対する修正と同じ内容をそのマッピングにも加える必要があります。

これらのデータ型の変更の詳細については、ネイティブ型のドキュメントを参照してください。

CoreGraphics 型を更新する

CoreGraphics で使用されるポイント、サイズ、四角形のデータ型は、実行されているデバイスに応じて 32 ビットまたは 64 ビットを使用します。 Xamarin で最初に iOS および Mac API がバインドされたとき、System.Drawing (RectangleF など) のデータ型と一致する既存のデータ構造を使用しました。

64 ビットと新しいネイティブ データ型をサポートする要件のため、CoreGraphic メソッドを呼び出すときに、既存のコードに対して次の調整を行う必要があります。

  • CGRect - 浮動小数点の四角形領域を定義するときに RectangleF の代わりに CGRect を使用します。
  • CGSize - 浮動小数点のサイズ (幅と高さ) を定義するときに、SizeF の代わりに CGSize を使用します。
  • CGPoint - 浮動小数点の位置 (X および Y 座標) を定義するときに、PointF の代わりに CGPoint を使用します。

上記の場合、API を確認し、以前に RectangleFSizeFPointF にバインドされていた CGRectCGSizeCGPoint のインスタンスをネイティブ型の CGRectCGSizeCGPoint に直接変更する必要があります。

たとえば、次の 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 内からバインドする場合) を変更し、Classic ではなく Unified API にバインドするように btouch に指示する必要があります。

MakeFile の更新

メイクファイルを使用してバインド プロジェクトを Xamarin .DLL にビルドする場合は、--new-style コマンド ライン オプションを含め、btouch の代わりに btouch-nativeを呼び出す必要があります。

次の 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 バインド プロジェクトを開始し、既存のすべてのコードと設定をコピーすることです。

次の操作を行います。

  1. Visual Studio for Mac を起動します。

  2. [ファイル]>[新規]>[ソリューション] を選択します

  3. [新しいソリューション] ダイアログ ボックスで、[iOS]>[Unified API]>[iOS バインド プロジェクト] を選択します。

    In the New Solution Dialog Box, select iOS / Unified API / iOS Binding Project

  4. [新しいプロジェクトの構成] ダイアログで、新しいバインド プロジェクトの名前を入力し、[OK] ボタンを選択します。

  5. バインドを作成する 64 ビット バージョンの Objective-C ライブラリを含めます。

  6. 既存の 32 ビット Classic API バインド プロジェクト (ApiDefinition.csStructsAndEnums.cs ファイルなど) からソース コードをコピーします。

  7. 上記の変更をソース コード ファイルに加えます。

これらの変更をすべて行えば、32 ビット バージョンと同様に、新しい 64 ビット バージョンの API をビルドできます。

まとめ

この記事では、新しい Unified API と 64 ビット デバイスをサポートするために既存の Xamarin バインド プロジェクトに対して行う必要がある変更と、新しい 64 ビット互換バージョンの API をビルドするために必要な手順について説明しました。