Tipy pro aktualizaci kódu na Unified API
Při aktualizaci starších řešení Xamarinu na sjednocené rozhraní API se můžou zobrazit následující chyby.
Chyba NSInvalidArgumentException nenašla chybu scénáře
V aktuální verzi Visual Studio pro Mac může dojít k chybě, ke které může dojít po použití nástroje pro automatizovanou migraci k převodu projektu na sjednocená rozhraní API. Pokud se po aktualizaci ve formuláři zobrazí chybová zpráva:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'xxx' in bundle NSBundle...
Pokud chcete tento problém vyřešit, vyhledejte následující cílový soubor sestavení:
/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/2.1/Xamarin.iOS.Common.targets
V tomto souboru potřebujete najít následující cílovou deklaraci:
<Target Name="_CopyContentToBundle"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
A přidejte DependsOnTargets="_CollectBundleResources"
do něj atribut. Nějak tak:
<Target Name="_CopyContentToBundle"
DependsOnTargets="_CollectBundleResources"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
Uložte soubor, restartujte Visual Studio pro Mac a proveďte čisté a opětovné sestavení projektu. Brzy by měl Xamarin vydat opravu tohoto problému.
Užitečné Tipy
Po použití nástroje pro migraci může dojít k chybám kompilátoru vyžadujících ruční zásah. Mezi některé věci, které můžou být potřeba opravit ručně, patří:
Porovnání
enum
může vyžadovat(int)
přetypování.NSDictionary.IntValue
nyní vrátí hodnotunint
, jeInt32Value
k dispozici místo toho, kterou lze použít.nfloat
anint
typy nelze označovatconst
;static readonly nint
je rozumnou alternativou.Věci, které se dřív používaly přímo v
MonoTouch.
oboru názvů, jsou teď obecně vObjCRuntime.
oboru názvů (např.MonoTouch.Constants.Version
teď).ObjCRuntime.Constants.Version
Kód, který serializuje objekty může přerušit při pokusu o serializaci
nint
anfloat
typy. Po migraci zkontrolujte, jestli kód serializace funguje podle očekávání.V některých případech automatizovaný nástroj vynechá kód uvnitř
#if #else
direktiv podmíněného kompilátoru. V takovém případě budete muset provést opravy ručně (viz níže uvedené běžné chyby).Ručně exportované metody používající
[Export]
nástroj pro migraci nemusí být automaticky opraveny nástrojem pro migraci, například v tomto výsuvku kódu je nutné ručně aktualizovat návratový typ nanfloat
:[Export("tableView:heightForRowAtIndexPath:")] public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
Jednotné rozhraní API neposkytuje implicitní převod mezi NSDate a .NET DateTime, protože se nejedná o bezeztrátový převod. Chcete-li zabránit chybám souvisejícím s
DateTimeKind.Unspecified
převodem rozhraní .NETDateTime
na místní nebo UTC před přetypování naNSDate
.Objective-C Metody kategorií se teď generují jako rozšiřující metody v sjednoceném rozhraní API. Například kód, který jste dříve použili
UIView.DrawString
, by teď odkazovalNSString.DrawString
na sjednocené rozhraní API.Kód používající třídy AVFoundation s
VideoSettings
by se měl změnit tak, aby používal vlastnostWeakVideoSettings
. To vyžadujeDictionary
vlastnost , která je k dispozici jako vlastnost u tříd nastavení, například:vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
Konstruktor NSObject
.ctor(IntPtr)
byl změněn z veřejného na chráněný (aby se zabránilo nesprávnému použití).NSAction
byla nahrazena standardem .NETAction
. Některé jednoduché delegáty (s jedním parametrem) byly také nahrazeny .Action<T>
Nakonec si projděte rozdíly klasického v sjednoceného rozhraní API a vyhledejte změny rozhraní API ve vašem kódu. Hledání na této stránce vám pomůže najít klasická rozhraní API a informace, na které byly aktualizovány.
Poznámka:
Obor MonoTouch.Dialog
názvů zůstane po migraci stejný. Pokud váš kód používá MonoTouch.Dialog, měli byste pokračovat v používání tohoto oboru názvů - neměňte MonoTouch.Dialog
na !Dialog
Běžné chyby kompilátoru
Další příkladyběžnýchch
Chyba CS0012: Typ MonoTouch.UIKit.UIView je definován v sestavení, na které není odkazováno.
Oprava: Obvykle to znamená, že projekt odkazuje na komponentu nebo balíček NuGet, který nebyl sestaven pomocí sjednoceného rozhraní API. Měli byste odstranit a znovu přidat všechny komponenty a balíčky NuGet. Pokud se tím chyba nevyřeší, nemusí externí knihovna ještě podporovat sjednocené rozhraní API.
Chyba MT0034: Do stejného projektu Xamarin.iOS nelze zahrnout monotouch.dll i Xamarin.iOS.dll – na Xamarin.iOS.dll se odkazuje explicitně, zatímco na monotouch.dll odkazuje Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null.
Oprava: Odstraňte komponentu, která způsobuje tuto chybu, a znovu přidejte do projektu.
Chyba CS0234: Název typu nebo oboru názvů Foundation v oboru názvů MonoTouch neexistuje. Nechybí odkaz na sestavení?
Oprava: Automatizovaný nástroj pro migraci v Visual Studio pro Mac by měl aktualizovat všechny MonoTouch.Foundation
odkazy na Foundation
, ale v některých případech bude nutné je aktualizovat ručně. Podobné chyby se mohou objevit u jiných oborů názvů, které byly dříve obsaženy v MonoTouch
, například UIKit
.
Chyba CS0266: Typ double nelze implicitně převést na System.float.
Oprava: změňte typ a přetypování na nfloat
. K této chybě může dojít také u ostatních typů s 64bitovými ekvivalenty (například nint
)
nfloat scale = (nfloat)Math.Min(rect.Width, rect.Height);
Chyba CS0266: Typ CoreGraphics.CGRect nelze implicitně převést na System.Drawing.RectangleF. Existuje explicitní převod (chybí přetypování?)
Oprava: Změňte instance na RectangleF
CGRect
, SizeF
na CGSize
a PointF
na CGPoint
. Obor názvů using System.Drawing;
by se měl nahradit using CoreGraphics;
(pokud ještě není k dispozici).
chyba CS1502: Nejlepší přetížená metoda pro 'CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[]) má několik neplatných argumentů.
Oprava: Změna typu pole na nfloat[]
a explicitní přetypování Math.PI
.
grphc.SetLineDash (0, new nfloat[] { 0, 3 * (nfloat)Math.PI });
Chyba CS0115: WordsTableSource.RowsInSection(UIKit.UITableView, int) je označena jako přepsání, ale nebyla nalezena žádná vhodná metoda k přepsání
Oprava: Změna návratové hodnoty a typů parametrů na nint
. K tomu často dochází v přepsání metody, jako jsou ty UITableViewSource
, včetně RowsInSection
, NumberOfSections
, GetHeightForRow
, TitleForHeader
atd GetViewForHeader
.
public override nint RowsInSection (UITableView tableview, nint section) {
Chyba CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView)
Návratový typ musí být System.nint, aby odpovídal přepsaný člen UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)
Oprava: Při změně návratového typu na nint
, přetypování návratové hodnoty na nint
.
public override nint NumberOfSections (UITableView tableView)
{
return (nint)navItems.Count;
}
Chyba CS1061: Typ CoreGraphics.CGPath neobsahuje definici pro AddElipseInRect
Oprava: Oprava pravopisu na AddEllipseInRect
. Mezi další změny názvu patří:
- Změňte "Color.Black" na
NSColor.Black
. - Změňte MapKit AddAnnotation na
AddAnnotations
. - Změňte AVFoundation DataUsingEncoding na
Encode
. - Změňte AVFoundation AVMetadataObject.TypeQRCode na
AVMetadataObjectType.QRCode
. - Změňte AVFoundation Video Nastavení na
WeakVideoSettings
. - Změňte PopViewControllerAnimated na
PopViewController
. - Změňte CoreGraphics CGBitmapContext.SetRGBFillColor na
SetFillColor
.
Chyba CS0546: Nelze přepsat, protože MapKit.MKAnnotation.Coordinate nemá přepisovatelného přístupového objektu sady (CS0546).
Při vytváření vlastní poznámky podtřídou MKAnnotation pole Souřadnice nemá žádné setter, pouze getter.
Oprava
- Přidání pole pro sledování souřadnic
- vrátit toto pole v getter vlastnosti Souřadnice
- Přepsání metody SetCoordinate a nastavení pole
- Volání SetCoordinate v ctoru s předaným parametrem souřadnic
Mělo by to vypadat nějak takto:
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);
}
}