Tipps zum Aktualisieren von Code für Unified API

Beim Aktualisieren älterer Xamarin-Lösungen auf die Unified API sind möglicherweise die folgenden Fehler aufgetreten.

NSInvalidArgumentException Der Storyboardfehler konnte nicht gefunden werden

Es gibt einen Fehler in der aktuellen Version von Visual Studio für Mac, die auftreten kann, nachdem Sie das automatisierte Migrationstool zum Konvertieren Ihres Projekts in die Unified-APIs verwendet haben. Wenn nach dem Update eine Fehlermeldung im Formular angezeigt wird:

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

Sie können die folgenden Schritte ausführen, um dieses Problem zu beheben, die folgende Buildzieldatei zu finden:

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

In dieser Datei müssen Sie die folgende Zieldeklaration finden:

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

Und fügen Sie das DependsOnTargets="_CollectBundleResources" Attribut hinzu. Dies sieht folgendermaßen aus:

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

Speichern Sie die Datei, starten Sie Visual Studio für Mac neu, und führen Sie eine sauber & Neuerstellung Ihres Projekts durch. Ein Fix für dieses Problem sollte in Kürze von Xamarin veröffentlicht werden.

Nützliche Tipps

Nachdem Sie das Migrationstool verwendet haben, erhalten Sie möglicherweise immer noch Compilerfehler, die manuelle Eingriffe erfordern. Einige Dinge, die möglicherweise manuell behoben werden müssen, umfassen:

  • Der Vergleich enumvon "s" erfordert möglicherweise eine (int) Umwandlung.

  • NSDictionary.IntValue gibt nun ein nint, es gibt eine Int32Value , die stattdessen verwendet werden kann.

  • nfloat und nint Typen können nicht markiert constwerden ; static readonly nint ist eine vernünftige Alternative.

  • Dinge, die sich früher direkt im MonoTouch. Namespace befinden, befinden sich nun im Allgemeinen im ObjCRuntime. Namespace (z. B.: MonoTouch.Constants.Version ist jetzt ObjCRuntime.Constants.Version).

  • Code, der Objekte serialisiert, kann beim Serialisieren nint und nfloat Typen nicht mehr verwendet werden. Vergewissern Sie sich, dass der Serialisierungscode nach der Migration erwartungsgemäß funktioniert.

  • Manchmal fehlt das automatisierte Tool Code in #if #else bedingten Compilerdirektiven. In diesem Fall müssen Sie die Korrekturen manuell vornehmen (siehe die folgenden allgemeinen Fehler).

  • Manuell exportierte Methoden, die verwendet [Export] werden, werden möglicherweise nicht automatisch vom Migrationstool behoben, z. B. in diesem Code-Snippert, müssen Sie den Rückgabetyp manuell aktualisieren auf nfloat:

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • Die Einheitliche API stellt keine implizite Konvertierung zwischen NSDate und .NET DateTime bereit, da sie keine verlustfreie Konvertierung ist. So verhindern Sie Fehler im Zusammenhang mit DateTimeKind.Unspecified der Konvertierung von .NET DateTime in lokale oder UTC vor dem Umwandeln in NSDate.

  • Objective-C Kategoriemethoden werden jetzt als Erweiterungsmethoden in der Unified-API generiert. Beispielsweise würde code, der zuvor verwendet UIView.DrawString wurde, jetzt in der Unified API referenzierten NSString.DrawString .

  • Code mit AVFoundation-Klassen VideoSettings sollte geändert werden, um die WeakVideoSettings Eigenschaft zu verwenden. Dies erfordert eine Dictionary, die als Eigenschaft für die Einstellungsklassen verfügbar ist, z. B.:

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • Der NSObject-Konstruktor .ctor(IntPtr) wurde von öffentlich in geschützt geändert (um eine unsachgemäße Verwendung zu verhindern).

  • NSActionwurde durch den Standard .NET Actionersetzt. Einige einfache (einzelne Parameter)-Delegaten wurden ebenfalls durch Action<T>ersetzt.

Lesen Sie abschließend die Unterschiede der klassischen v Unified API, um Änderungen an APIs in Ihrem Code nachzuschlagen. Die Suche auf dieser Seite hilft ihnen, klassische APIs und deren Aktualisierung zu finden.

Hinweis

Der MonoTouch.Dialog Namespace wird nach der Migration wie folgt neu Standard. Wenn Ihr Code MonoTouch.Dialog verwendet, sollten Sie diesen Namespace weiterhin verwenden - ändern MonoTouch.Dialog Sie sich nicht in Dialog!

Häufige Compilerfehler

Weitere Beispiele für häufige Fehler sind unten aufgeführt, zusammen mit der Lösung:

Fehler CS0012: Der Typ "MonoTouch.UIKit.UIView" wird in einer Assembly definiert, auf die nicht verwiesen wird.

Fix: Dies bedeutet in der Regel, dass das Projekt auf eine Komponente oder ein NuGet-Paket verweist, das nicht mit der Unified-API erstellt wurde. Sie sollten alle Komponenten und NuGet-Pakete löschen und erneut hinzufügen. Wenn der Fehler dadurch nicht behoben wird, unterstützt die externe Bibliothek möglicherweise noch nicht die Unified-API.

Fehler MT0034: Es kann nicht sowohl "monotouch.dll" als auch "Xamarin.iOS.dll" in dasselbe Xamarin.iOS-Projekt eingeschlossen werden. Auf "Xamarin.iOS.dll" wird explizit verwiesen, während auf "monotouch.dll" von "Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null" verwiesen wird.

Behebung: Löschen Sie die Komponente, die diesen Fehler verursacht, und fügen Sie es dem Projekt erneut hinzu.

Fehler CS0234: Der Typ oder Namespacename 'Foundation' ist im Namespace 'MonoTouch' nicht vorhanden. Möglicherweise fehlt ein Assemblyverweis.

Fix: Das automatisierte Migrationstool in Visual Studio für Mac sollte alle MonoTouch.Foundation Verweise Foundationaktualisieren, in einigen Fällen müssen diese jedoch manuell aktualisiert werden. Ähnliche Fehler können für die anderen zuvor enthaltenen MonoTouchNamespaces auftreten, z UIKit. B. .

Fehler CS0266: Typ 'double' kann nicht implizit in 'System.float' konvertiert werden.

Fix: Typ ändern und in nfloat. Dieser Fehler kann auch für die anderen Typen mit 64-Bit-Entsprechungen (z nint. B. , ) auftreten.

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

Fehler CS0266: Der Typ "CoreGraphics.CGRect" kann nicht implizit in "System.Drawing.RectangleF" konvertiert werden. Eine explizite Konvertierung ist vorhanden (fehlt eine Umwandlung?)

Fix: Ändern von Instanzen in RectangleF , in , in und PointF in CGPoint.CGSizeSizeFCGRect Der Namespace using System.Drawing; sollte durch (sofern er noch nicht vorhanden ist) ersetzt using CoreGraphics; werden.

fehler CS1502: Die beste überladene Methodenübereinstimmung für "CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])" weist einige ungültige Argumente auf.

Fix: Ändern Des Arraytyps in nfloat[] und explizit umwandeln Math.PI.

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

Fehler CS0115: "WordsTableSource.RowsInSection(UIKit.UITableView, int)" ist als Außerkraftsetzung gekennzeichnet, aber es wurde keine geeignete Methode zum Außerkraftsetzen gefunden.

Fix: Ändern Sie den Rückgabewert und die Parametertypen in nint. Dies tritt häufig in Methodenüberschreibungen auf , einschließlich UITableViewSourceRowsInSection, NumberOfSections, GetHeightForRow, , TitleForHeader, GetViewForHeaderusw.

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

Fehler CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView)Der Rückgabetyp muss 'System.nint' lauten, damit es mit überschriebenem Element übereinstimmt. UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

Fix: Wenn der Rückgabetyp geändert nintwird, wandeln Sie den Rückgabewert in nint.

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

Fehler CS1061: Typ 'CoreGraphics.CGPath' enthält keine Definition für 'AddElipseInRect'

Korrektur: Korrigieren der Rechtschreibung in AddEllipseInRect. Weitere Namensänderungen sind:

  • Ändern Sie 'Color.Black' in NSColor.Black.
  • Ändern Sie MapKit 'AddAnnotation' in AddAnnotations.
  • Ändern Sie AVFoundation 'DataUsingEncoding' in Encode.
  • Ändern Sie AVFoundation 'AVMetadataObject.TypeQRCode' in AVMetadataObjectType.QRCode.
  • Ändern Sie AVFoundation "Video Einstellungen" in WeakVideoSettings.
  • Ändern Sie PopViewControllerAnimated in PopViewController.
  • Ändern Sie CoreGraphics 'CGBitmapContext.SetRGBFillColor' in SetFillColor.

Fehler CS0546: Kann nicht außer Kraft gesetzt werden, da 'MapKit.MKAnnotation.Coordinate' keinen überschreibbaren Set-Accessor (CS0546) aufweist.

Beim Erstellen einer benutzerdefinierten Anmerkung durch Unterklassen von MKAnnotation hat das Koordinatenfeld keinen Setter, nur einen Getter.

Der Fix

  • Hinzufügen eines Felds zum Nachverfolgen der Koordinate
  • dieses Feld im Getter der Coordinate-Eigenschaft zurückgeben
  • Überschreiben Der SetCoordinate-Methode und Festlegen des Felds
  • Aufrufen von SetCoordinate in Ihrem Ctor mit dem übergebenen Koordinatenparameter

Es sollte ungefähr wie folgt aussehen:

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);
    }
}