コードを Unified API に更新する場合のヒント

古い Xamarin ソリューションを Unified API に更新すると、次のエラーが発生する可能性があります。

NSInvalidArgumentException がストーリーボードを見つけることができませんでしたエラー

現在のバージョンの Visual Studio for Mac には、自動移行ツールを使用してプロジェクトを統合 API に変換した後に発生する可能性があるバグがあります。 更新後、次の形式でエラー メッセージが表示される場合:

Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'xxx' in bundle NSBundle...

この問題を解決するには、次のビルド ターゲット ファイルを見つけます。

/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/2.1/Xamarin.iOS.Common.targets

このファイルでは、次のターゲット宣言を見つける必要があります。

<Target Name="_CopyContentToBundle"
        Inputs = "@(_BundleResourceWithLogicalName)"
        Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >

属性を DependsOnTargets="_CollectBundleResources" 追加します。 例:

<Target Name="_CopyContentToBundle"
        DependsOnTargets="_CollectBundleResources"
        Inputs = "@(_BundleResourceWithLogicalName)"
        Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >

ファイルを保存し、Visual Studio for Mac を再起動し、クリーンを実行してプロジェクトをリビルドします。 この問題の修正プログラムは、まもなく Xamarin によってリリースされる必要があります。

便利なヒント

移行ツールを使用した後も、手動による介入を必要とするコンパイラ エラーが発生する可能性があります。 手動で修正する必要がある場合は、次のようなものがあります。

  • s を比較するには enumキャストが必要な (int) 場合があります。

  • NSDictionary.IntValue が返 nintされるようになりました。代わりに使用できるオブジェクトがあります Int32Value

  • nfloatnint型をマークconststatic readonly nintすることはできません。これは妥当な代替手段です。

  • 以前は名前空間に MonoTouch. 直接存在するものは、一般的に名前空間にあります ObjCRuntime. (例: MonoTouch.Constants.Version 現在 ObjCRuntime.Constants.Version)。

  • オブジェクトをシリアル化するコードは、シリアル化 nintnfloat 型の試行時に中断する可能性があります。 移行後は、シリアル化コードが想定どおりに動作するようにチェックしてください。

  • 自動ツールによって、条件付きコンパイラ ディレクティブ内 #if #else のコードが見落とされることがあります。 この場合は、修正を手動で行う必要があります (以下の一般的なエラーを参照してください)。

  • 手動でエクスポートしたメソッドは [Export] 、移行ツールによって自動的に修正されない場合があります。たとえば、このコードでは、戻り値の型を手動で次のように更新する nfloat必要があります。

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • Unified API では、NSDate と .NET DateTime の間の暗黙的な変換は提供されません。これは、無損失の変換ではないためです。 キャスト前に .NET DateTimeDateTimeKind.Unspecifiedローカルまたは UTC に変換することに関連するエラーをNSDate回避するには、

  • Objective-C カテゴリ メソッドは、Unified API の拡張メソッドとして生成されるようになりました。 たとえば、以前に使用 UIView.DrawString したコードが Unified API で参照 NSString.DrawString されるようになりました。

  • AVFoundation クラスを使用するコードは VideoSettings 、プロパティを使用するように変更する WeakVideoSettings 必要があります。 これには、 Dictionary設定クラスのプロパティとして使用できる 、次のものが必要です。

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • NSObject .ctor(IntPtr) コンストラクターがパブリックから保護に変更されました (不適切な使用を防ぐため)。

  • NSActionは標準の .NET Actionに置き換えられました。 いくつかの単純な (単一のパラメーター) デリゲートも置き換えられました Action<T>

最後に、クラシックと Unified API の 違い を参照して、コード内の API の変更を確認します。 このページを検索すると、クラシック API と更新された内容を見つけることができます。

Note

名前空間はMonoTouch.Dialogメイン移行後も同じです。 コードで MonoTouch.Dialog を使用している場合は、引き続きその名前空間を使用する必要があります。!MonoTouch.DialogDialog

一般的なコンパイラ エラー

一般的なエラーのその他の例を、ソリューションと共に次に示します。

エラー CS0012: 型 'MonoTouch.UIKit.UIView' は、参照されていないアセンブリで定義されています。

修正: これは通常、プロジェクトが Unified API でビルドされていないコンポーネントまたは NuGet パッケージを参照することを意味します。 すべてのコンポーネントと NuGet パッケージを削除して再追加する必要があります。 それでもエラーが解決しない場合は、外部ライブラリで Unified API がまだサポートされていない可能性があります。

エラー MT0034: 'monotouch.dll' と 'Xamarin.iOS.dll' の両方を同じ Xamarin.iOS プロジェクトに含めることはできません。 'Xamarin.iOS.dll' は明示的に参照されますが、'monotouch.dll' は 'Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null' によって参照されます。

修正: このエラーの原因となっているコンポーネントを削除し、プロジェクトに再追加します。

エラー CS0234: 型または名前空間名 'Foundation' が名前空間 'MonoTouch' に存在しません。 アセンブリ参照が存在することを確認してください。

修正: Visual Studio for Mac の自動移行ツールでは、すべてのMonoTouch.Foundation参照を更新するFoundation必要があります。ただし、場合によっては、これらを手動で更新する必要があります。 以前に含まれていたMonoTouchUIKit他の名前空間にも同様のエラーが表示される場合があります。

エラー CS0266: 型 'double' を 'System.float' に暗黙的に変換できません

修正: 型を変更してキャストします nfloat。 このエラーは、64 ビットに相当する他の型 (例: nint, ) でも発生する可能性があります。

nfloat scale = (nfloat)Math.Min(rect.Width, rect.Height);

エラー CS0266: 型 'CoreGraphics.CGRect' を 'System.Drawing.RectangleF' に暗黙的に変換できません。 明示的な変換が存在します (型変換を忘れていませんか)。

修正: インスタンスを次の値にRectangleFCGRect変更し、SizeF次の値にCGSize変更PointFしますCGPoint。 名前空間 using System.Drawing; は (まだ存在しない場合) に置き換える using CoreGraphics; 必要があります。

エラー CS1502: 'CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])' のオーバーロードされた最適なメソッド一致には、無効な引数がいくつかあります

修正: 配列型を変更して nfloat[] 明示的にキャスト Math.PIします。

grphc.SetLineDash (0, new nfloat[] { 0, 3 * (nfloat)Math.PI });

エラー CS0115: 'WordsTableSource.RowsInSection(UIKit.UITableView, int)' はオーバーライドとしてマークされていますが、オーバーライドに適したメソッドが見つかりません

修正: 戻り値とパラメーターの型を次に変更します nint。 これは一般的に、メソッドのオーバーライドで発生しますUITableViewSource(例: , , NumberOfSectionsRowsInSection, GetHeightForRow, TitleForHeader, GetViewForHeaderなど)。

public override nint RowsInSection (UITableView tableview, nint section) {

エラー CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView): オーバーライドされたメンバーと一致させるには、戻り値の型が 'System.nint' である必要があります UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

修正: 戻り値の型が変更 nintされたときに戻り値をキャストします nint

public override nint NumberOfSections (UITableView tableView)
{
    return (nint)navItems.Count;
}

エラー CS1061: 型 'CoreGraphics.CGPath' に 'AddElipseInRect' の定義が含まれていません

修正: スペルを修正します AddEllipseInRect。 その他の名前の変更は次のとおりです。

  • 'Color.Black' を .. に変更します NSColor.Black
  • MapKit 'AddAnnotation' を AddAnnotations.
  • AVFoundation 'DataUsingEncoding' を Encode.
  • AVFoundation 'AVMetadataObject.TypeQRCode' を AVMetadataObjectType.QRCode.
  • AVFoundation 'Video設定' を WeakVideoSettings.
  • PopViewControllerAnimated を PopViewController.
  • CoreGraphics 'CGBitmapContext.SetRGBFillColor' を SetFillColor.

エラー CS0546: 'MapKit.MKAnnotation.Coordinate' にオーバーライド可能な set アクセサーがないため、オーバーライドできません (CS0546)

MKAnnotation をサブクラス化してカスタム注釈を作成する場合、Coordinate フィールドにはセッターがなく、getter のみが含まれます。

修正プログラム

  • 座標を追跡するフィールドを追加する
  • Coordinate プロパティの getter でこのフィールドを返す
  • SetCoordinate メソッドをオーバーライドし、フィールドを設定する
  • 渡された座標パラメーターを使用して ctor で SetCoordinate を呼び出す

次のようになっているはずです。

class BasicPinAnnotation : MKAnnotation
{
    private CLLocationCoordinate2D _coordinate;

    public override CLLocationCoordinate2D Coordinate
    {
        get
        {
            return _coordinate;
        }
    }

    public override void SetCoordinate(CLLocationCoordinate2D value)
    {
        _coordinate = value;
    }

    public BasicPinAnnotation (CLLocationCoordinate2D coordinate)
    {
        SetCoordinate(coordinate);
    }
}