Udostępnij za pośrednictwem


Porady dotyczące aktualizowania kodu na potrzeby ujednoliconego interfejsu API

Podczas aktualizowania starszych rozwiązań platformy Xamarin do ujednoliconego interfejsu API mogą wystąpić następujące błędy.

Nie można odnaleźć błędu scenorysu NSInvalidArgumentException

W bieżącej wersji Visual Studio dla komputerów Mac występuje usterka, która może wystąpić po użyciu narzędzia do automatycznej migracji w celu przekonwertowania projektu na ujednolicone interfejsy API. Jeśli po aktualizacji zostanie wyświetlony komunikat o błędzie w formularzu:

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

Aby rozwiązać ten problem, znajdź następujący plik docelowy kompilacji:

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

W tym pliku należy znaleźć następującą deklarację docelową:

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

DependsOnTargets="_CollectBundleResources" Dodaj do niego atrybut . Jak to:

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

Zapisz plik, uruchom ponownie Visual Studio dla komputerów Mac i wykonaj czystą i ponownie skompiluj projekt. Poprawka tego problemu powinna wkrótce zostać wydana przez platformę Xamarin.

Przydatne Wskazówki

Po użyciu narzędzia do migracji nadal mogą wystąpić błędy kompilatora wymagające interwencji ręcznej. Niektóre elementy, które mogą wymagać ręcznego naprawienia, obejmują:

  • Porównanie enums może wymagać rzutu (int) .

  • NSDictionary.IntValue teraz zwraca element nint, którego Int32Value można użyć zamiast tego.

  • nfloat typy i nint nie mogą być oznaczone const; static readonly nint jest rozsądną alternatywą.

  • Elementy, które kiedyś były bezpośrednio w MonoTouch. przestrzeni nazw, są teraz ogólnie dostępne w ObjCRuntime. przestrzeni nazw (np. MonoTouch.Constants.Version jest teraz ObjCRuntime.Constants.Version).

  • Kod, który serializuje obiekty, może spowodować przerwanie podczas próby serializacji nint i nfloat typów. Pamiętaj, aby sprawdzić, czy kod serializacji działa zgodnie z oczekiwaniami po migracji.

  • Czasami narzędzie zautomatyzowane pomija kod wewnątrz #if #else dyrektyw kompilatora warunkowego. W takim przypadku należy ręcznie wprowadzić poprawki (zobacz typowe błędy poniżej).

  • Ręcznie wyeksportowane metody przy użyciu narzędzia [Export] do migracji mogą nie zostać automatycznie naprawione, na przykład w tym fragmencie kodu należy ręcznie zaktualizować typ powrotu do nfloat:

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • Ujednolicony interfejs API nie zapewnia niejawnej konwersji między NSDate i .NET DateTime, ponieważ nie jest to konwersja bezstratna. Aby zapobiec błędom związanym z DateTimeKind.Unspecified konwertowaniem platformy .NET DateTime na lokalny lub UTC przed rzutowaniem na NSDate.

  • Objective-C metody kategorii są teraz generowane jako metody rozszerzenia w ujednoliconym interfejsie API. Na przykład kod, który był wcześniej używany UIView.DrawString , odwołuje NSString.DrawString się teraz do ujednoliconego interfejsu API.

  • Kod używający klas AVFoundation z VideoSettings poleceniem powinien ulec zmianie, aby używać WeakVideoSettings właściwości . Wymaga to elementu Dictionary, który jest dostępny jako właściwość w klasach ustawień, na przykład:

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • Konstruktor NSObject .ctor(IntPtr) został zmieniony z publicznego na chroniony (aby zapobiec niewłaściwemu użyciu).

  • NSActionzostał zastąpiony standardową platformą .NET Action. Niektóre proste (pojedynczy parametr) delegaty zostały również zastąpione elementem Action<T>.

Na koniec zapoznaj się z klasycznymi różnicami w ujednoliconym interfejsie API, aby wyszukać zmiany interfejsów API w kodzie. Wyszukiwanie na tej stronie pomoże znaleźć klasyczne interfejsy API i informacje o aktualizacjach.

Uwaga

MonoTouch.Dialog Przestrzeń nazw pozostaje taka sama po migracji. Jeśli w kodzie jest używana aplikacja MonoTouch.Dialog , nadal należy używać tej przestrzeni nazw — nie zmieniaj jej MonoTouch.Dialog na Dialog!

Typowe błędy kompilatora

Poniżej wymieniono inne przykłady typowych błędów wraz z rozwiązaniem:

Błąd CS0012: typ "MonoTouch.UIKit.UIView" jest zdefiniowany w zestawie, do którego nie odwołuje się odwołanie.

Poprawka: zwykle oznacza to, że projekt odwołuje się do składnika lub pakietu NuGet, który nie został skompilowany przy użyciu ujednoliconego interfejsu API. Należy usunąć i ponownie dodać wszystkie składniki i pakiety NuGet. Jeśli ten błąd nie zostanie naprawiony, biblioteka zewnętrzna może jeszcze nie obsługiwać ujednoliconego interfejsu API.

Błąd MT0034: Nie można dołączyć zarówno wartości "monotouch.dll" jak i "Xamarin.iOS.dll" w tym samym projekcie platformy Xamarin.iOS — "Xamarin.iOS.dll", podczas gdy odwołanie "monotouch.dll" dotyczy elementu "Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null".

Poprawka: usuń składnik, który powoduje ten błąd i ponownie dodaj go do projektu.

Błąd CS0234: nazwa typu lub przestrzeni nazw "Foundation" nie istnieje w przestrzeni nazw "MonoTouch". Czy nie brakuje odwołania do zestawu?

Poprawka: narzędzie do automatycznej migracji w Visual Studio dla komputerów Mac powinno zaktualizować wszystkie MonoTouch.Foundation odwołania do Foundationprogramu , jednak w niektórych przypadkach należy je zaktualizować ręcznie. Podobne błędy mogą pojawić się dla innych przestrzeni nazw zawartych wcześniej w MonoTouchpliku , takich jak UIKit.

Błąd CS0266: Nie można niejawnie przekonwertować typu "double" na "System.float"

Poprawka: zmień typ i rzutowanie na nfloat. Ten błąd może również wystąpić w przypadku innych typów z odpowiednikami 64-bitowymi (takimi jak nint, )

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

Błąd CS0266: Nie można niejawnie przekonwertować typu "CoreGraphics.CGRect" na "System.Drawing.RectangleF". Istnieje jawna konwersja (czy brakuje rzutu?)

Poprawka: Zmień wystąpienia na RectangleF , na CGRectCGSize, SizeF i PointF na CGPoint. Przestrzeń nazw using System.Drawing; powinna zostać zastąpiona ciągiem using CoreGraphics; (jeśli jeszcze nie istnieje).

błąd CS1502: Najlepsze przeciążone dopasowanie metody dla metody "CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])" ma kilka nieprawidłowych argumentów

Poprawka: Zmień typ tablicy na nfloat[] i jawnie rzutuj Math.PI.

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

Błąd CS0115: "WordsTableSource.RowsInSection(UIKit.UITableView, int)" jest oznaczony jako zastąpienie, ale nie znaleziono odpowiedniej metody, aby zastąpić

Poprawka: Zmień zwracaną wartość i typy parametrów na nint. Często występuje to w przesłonięciach metod, takich jak te w UITableViewSource, w tym RowsInSection, NumberOfSections, GetHeightForRow, TitleForHeader, , , GetViewForHeaderitp.

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

Błąd CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView)zwracany typ musi mieć wartość "System.nint", aby dopasować zastąpiony element członkowski UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

Poprawka: gdy zwracany typ jest zmieniany na nint, rzutuj wartość zwracaną na nint.

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

Błąd CS1061: Typ "CoreGraphics.CGPath" nie zawiera definicji polecenia "AddElipseInRect"

Poprawka: Popraw pisownię na AddEllipseInRect. Inne zmiany nazw to:

  • Zmień wartość "Color.Black" na NSColor.Black.
  • Zmień element MapKit "AddAnnotation" na AddAnnotations.
  • Zmień wartość AVFoundation "DataUsingEncoding" na Encode.
  • Zmień wartość AVFoundation "AVMetadataObject.TypeQRCode" na AVMetadataObjectType.QRCode.
  • Zmień element AVFoundation "Video Ustawienia" na WeakVideoSettings.
  • Zmień wartość PopViewControllerAnimated na PopViewController.
  • Zmień element CoreGraphics "CGBitmapContext.SetRGBFillColor" na SetFillColor.

Błąd CS0546: nie można zastąpić, ponieważ element "MapKit.MKAnnotation.Coordinate" nie ma przesłonięć metody dostępu zestawu (CS0546)

Podczas tworzenia adnotacji niestandardowej przez podklasę MKAnnotation pole Współrzędnych nie ma ustawiania, tylko getter.

Poprawka

  • Dodawanie pola w celu śledzenia współrzędnych
  • zwróć to pole we właściwości Getter właściwości Coordinate
  • Zastąpij metodę SetCoordinate i ustaw pole
  • Wywołaj metodę SetCoordinate w ctor z przekazanym parametrem współrzędnych

Zawartość powinna wyglądać mniej więcej tak:

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