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
enum
s może wymagać rzutu(int)
.NSDictionary.IntValue
teraz zwraca elementnint
, któregoInt32Value
można użyć zamiast tego.nfloat
typy inint
nie mogą być oznaczoneconst
;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 wObjCRuntime.
przestrzeni nazw (np.MonoTouch.Constants.Version
jest terazObjCRuntime.Constants.Version
).Kod, który serializuje obiekty, może spowodować przerwanie podczas próby serializacji
nint
infloat
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 donfloat
:[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 .NETDateTime
na lokalny lub UTC przed rzutowaniem naNSDate
.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łujeNSString.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 elementuDictionary
, 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).NSAction
został zastąpiony standardową platformą .NETAction
. Niektóre proste (pojedynczy parametr) delegaty zostały również zastąpione elementemAction<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 Foundation
programu , 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 MonoTouch
pliku , 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 CGRect
CGSize
, 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
, , , GetViewForHeader
itp.
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);
}
}