Unified API přehledu

Xamarin má Unified API umožňuje sdílet kód mezi Macem a iOSem a podporuje 32bitové a 64bitové aplikace se stejným binárním souborem. Tento Unified API se ve výchozím nastavení používá v nových projektech Xamarin.iOS a Xamarin.Mac.

Důležité

Funkce Xamarin Classic API, která předcházela Unified API, je zastaralá.

  • Poslední verzí Xamarin.iOS pro podporu Classic API (monotouch.dll) byl Xamarin.iOS 9.10.
  • Xamarin.Mac stále podporuje Classic API, ale už není aktualizovaný. Vzhledem k tomu, že je zastaralý, by vývojáři měli přesunout své aplikace do Unified API.

Aktualizace Classic API založených na aplikacích

Postupujte podle příslušných pokynů pro vaši platformu:

Tipy pro aktualizaci kódu na Unified API

Bez ohledu na to, jaké aplikace migrujete, se podívejte na tyto tipy, které vám pomůžou úspěšně aktualizovat na Unified API.

Rozdělení knihovny

Od tohoto okamžiku se naše rozhraní API zobrazí dvěma způsoby:

  • Classic API: Omezeno na 32 bitů (pouze) a vystaveno v XamMac.dll sestaveních a .
  • Unified API: Podpora 32bitového i 64bitového vývoje s jedním rozhraním API dostupným v Xamarin.Mac.dll sestaveních a .

To znamená, že pro vývojáře Enterprise (necílené na App Store) můžete dál používat stávající klasická rozhraní API, protože je budeme udržovat napořád, nebo můžete upgradovat na nová rozhraní API.

Změny oboru názvů

Aby se snížily třecí plochy při sdílení kódu mezi produkty mac a iOS, měníme obory názvů pro rozhraní API v produktech.

Z našeho produktu pro iOS zahodíme předponu MonoTouch a z našeho produktu Pro Mac přehodíme předponu MonoTouch pro datové typy.

To usnadňuje sdílení kódu mezi platformami Mac a iOS bez nutnosti použití podmíněné kompilace a snižuje šum v horní části souborů zdrojového kódu.

  • Classic API: Obory názvů používají MonoMac. předponu nebo .
  • Unified API: Žádná předpona oboru názvů

Výchozí nastavení modulu runtime

Pro Unified API vlastnictví objektů používá systém uvolňování paměti SGen a systém New Reference Counting. Stejná funkce byla portována do Xamarin.Mac.

Tím se řeší řada problémů, se kterým se vývojáři potýkají se starým systémem, a také usnadňuje správu paměti.

Všimněte si, že možnost Nový refcount je možné povolit i pro Classic API, ale výchozí hodnota je neschůdná a nevyžaduje, aby uživatelé počítal s žádnými změnami. V Unified API jsme využili příležitosti ke změně výchozího nastavení a poskytujeme vývojářům všechna vylepšení ve stejnou dobu, kdy refaktorují a znovu otestují svůj kód.

Změny rozhraní API

Rozhraní Unified API odebere zastaralé metody a existuje několik instancí, kdy názvy rozhraní API překlepy byly vázané na původní obory názvů MonoTouch a MonoMac v klasických rozhraních API. Tyto instance byly opraveny v nových sjednocených rozhraních API a bude nutné je aktualizovat v aplikacích pro iOS a Mac. Tady je seznam nejběžnějších, na které byste mohli na tyto problémy naběhat:

Classic API název metody Unified API název metody
UINavigationController.PushViewControllerAnimated() UINavigationController.PushViewController()
UINavigationController.PopViewControllerAnimated() UINavigationController.PopViewController()
CGContext.SetRGBFillColor() CGContext.SetFillColor()
NetworkReachability.SetCallback() NetworkReachability.SetNotification()
CGContext.SetShadowWithColor CGContext.SetShadow
UIView.StringSize UIKit.UIStringDrawing.StringSize

Úplný seznam změn při přechodu z verze Classic na Unified API najdete v naší dokumentaci k rozdílům mezi rozhraním Classic (monotouch.dll) a Unified (Xamarin.iOS.dll) API.

Aktualizace na Unified

V rozhraní Unified API není k dispozici několik starých, poškozených nebo zastaralých rozhraní API v klasickém prostředí. Před zahájením upgradu (ručního nebo automatizovaného) může být jednodušší upozornění opravit, protože se zobrazí zpráva o atributu (součást upozornění), která vás navede na CS0616[Obsolete] správné rozhraní API.

Upozorňujeme, že publikujete rozdíly mezi klasickými a jednotnými změnami rozhraní API, které je možné použít před aktualizací projektu nebo po jejich aktualizaci. Oprava zastaralých volání v klasickém systému bude často šetřit časem (méně vyhledávání v dokumentaci).

Podle těchto pokynů aktualizujte stávající aplikace pro iOSnebo aplikace pro Mac na Unified API. Ve zbývající části této stránky najdete další informace o migraci kódu v těchto tipech.

NuGet

NuGet balíčky, které dříve podporovaly Xamarin.iOS prostřednictvím Classic API publikovali svá sestavení pomocí monikeru platformy Monotouch10.

Rozhraní Unified API zavádí nový identifikátor platformy pro kompatibilní balíčky – Xamarin.iOS10. Stávající NuGet bude potřeba aktualizovat a přidat podporu pro tuto platformu sestavením proti Unified API.

Důležité

Pokud se ve stejném projektu Xamarin.iOS zobrazí chyba 3 – Chyba 3 nemůže ve stejném projektu Xamarin.iOS zahrnovat monotouch.dll i Xamarin.iOS.dll – výslovně se odkazuje na Xamarin.iOS.dll. zatímco na monotouch.dll odkazuje xxx, Version=0.0.000, Culture=neutral, PublicKeyToken=null" po převodu aplikace na sjednocená rozhraní API, je to obvykle způsobeno buď komponentou, nebo balíčkem NuGet v projektu, který nebyl aktualizován na Unified API. Budete muset odebrat existující komponentu nebo NuGet, aktualizovat na verzi, která podporuje sjednocená rozhraní API, a provést čisté sestavení.

The Road to 64 Bits

Základní informace o podpoře 32 a 64bitových aplikací a informace o architekturách najdete v tématu Aspekty 32bitové a 64bitové platformy.

Nové datové typy

Jádrem rozdílu je, že rozhraní API pro Mac i iOS používají datové typy specifické pro architekturu, které jsou vždy 32bitové na 32bitových platformách a 64bitové na 64bitových platformách.

Například Objective-C namapuje datový typ na v NSInteger 32bitových systémech a na int32_tint64_t 64bitové systémy.

Pro shodu s tímto chováním v našem Unified API nahrazujeme předchozí použití (které v .NET je definováno jako vždy int ) na nový datový System.Int32 typ: System.nint . "n" si můžete myslet jako "nativní", takže nativní celočíselný typ platformy.

V případě potřeby představujeme , a také poskytujeme datové typy, které jsou nintnuint nad nimi nfloat postavené.

Další informace o těchto změnách datových typů najdete v dokumentu Nativní typy.

Zjištění architektury aplikací pro iOS

Můžou se zobrazit situace, kdy vaše aplikace potřebuje vědět, jestli běží na 32bitovém nebo 64bitovém systému iOS. Ke kontrole architektury je možné použít následující kód:

if (IntPtr.Size == 4) {
    Console.WriteLine ("32-bit App");
} else if (IntPtr.Size == 8) {
    Console.WriteLine ("64-bit App");
}

Pole a System.Collections.Generic

Vzhledem k tomu, že indexery jazyka C# očekávají typ , budete muset explicitně přetypovat hodnoty pro přístup k prvkům v intnint kolekci nebo int poli. Například:

public List<string> Names = new List<string>();
...

public string GetName(nint index) {
    return Names[(int)index];
}

Toto chování je očekávané, protože přetypování z na je ztrátou na intnint 64bitové verzi, implicitní převod není proveden.

Převod data a času na NSDate

Při použití sjednocených rozhraní API se implicitní převod na DateTimeNSDate hodnoty už neprovádí. Tyto hodnoty bude potřeba explicitně převést z jednoho typu na jiný. K automatizaci tohoto procesu je možné použít následující rozšiřující metody:

public static DateTime NSDateToDateTime(this NSDate date)
{
    // NSDate has a wider range than DateTime, so clip
    // the converted date to DateTime.Min|MaxValue.
    double secs = date.SecondsSinceReferenceDate;
    if (secs < -63113904000)
        return DateTime.MinValue;
    if (secs > 252423993599)
        return DateTime.MaxValue;
    return (DateTime) date;
}

public static NSDate DateTimeToNSDate(this DateTime date)
{
    if (date.Kind == DateTimeKind.Unspecified)
        date = DateTime.SpecifyKind (date, /* DateTimeKind.Local or DateTimeKind.Utc, this depends on each app */)
    return (NSDate) date;
}

Zastaralá rozhraní API a překlepy

Uvnitř klasického rozhraní API xamarin.iOS (monotouch.dll) se [Obsolete] atribut použil dvěma různými způsoby:

  • Zastaralé rozhraní API pro iOS: To je v případě, že apple naznačuje, abyste přestali používat rozhraní API, protože ho nahrazuje novější. Aplikace Classic API stále v pořádku a často se vyžaduje (pokud podporujete starší verzi iOSu). Takové rozhraní API [Obsolete] (a atribut ) jsou součástí nových sestavení Xamarin.iOS.
  • Nesprávné rozhraní API Některé rozhraní API mělo překlepy ve svých názvech.

U původních sestavení (monotouch.dll a XamMac.dll) jsme starý kód udržoval dostupný pro kompatibilitu, ale byly odebrány ze sestavení Unified API (Xamarin.iOS.dll a Xamarin.Mac).

Podtřídy NSObject .ctor(IntPtr)

Každá NSObject podtřída má konstruktor, který přijímá IntPtr . Tímto způsobem můžeme vytvořit instanci nové spravované instance z nativního popisovače ObjC.

V klasickém to byl public konstruktor. Bylo ale snadné tuto funkci zneužít v uživatelském kódu, například vytvořit několik spravovaných instancí pro jednu instanci ObjC nebo vytvořit spravovanou instanci, která by chyběla očekávanému spravovanému stavu (pro podtřídy).

Abyste se tomuto druhu problémů vyhnuli, konstruktory jsou teď ve sjednocených rozhraních API, které se IntPtrprotected používají jenom pro podtřídy. IntPtr Tím se zajistí použití správného/bezpečného rozhraní API k vytvoření spravované instance z popisovačů, tj.

var label = Runtime.GetNSObject<UILabel> (handle);

Toto rozhraní API vrátí existující spravovanou instanci (pokud už existuje) nebo v případě potřeby vytvoří novou. Je už k dispozici v klasickém i jednotném rozhraní API.

Všimněte si, že je teď také , ale tento objekt se zřídka .ctor(NSObjectFlag)protected používal mimo podtřídy.

Akce NSAction nahrazena akcí

Sjednocená rozhraní API byla odebrána ve NSAction prospěch standardního rozhraní .NET Action . Jedná se o velké vylepšení, Action protože se jedná o běžný typ .NET, zatímco pro NSAction Xamarin.iOS byl specifický. Oba dělají přesně totéž, ale byly to odlišné a nekompatibilní typy a vedlo k tomu, že se pro dosažení stejného výsledku musí napsat více kódu.

Pokud například existující aplikace Xamarin obsahovala následující kód:

UITapGestureRecognizer singleTap = new UITapGestureRecognizer (new NSAction (delegate() {
    ShowDropDownAnimated (tblDataView);
}));

Teď ho můžete nahradit jednoduchým výrazem lambda:

UITapGestureRecognizer singleTap = new UITapGestureRecognizer (() => ShowDropDownAnimated(tblDataView));

Dříve to byla chyba kompilátoru, protože nelze přiřadit k , ale vzhledem k tomu, že teď přebírá místo , je platný ve sjednocených ActionNSActionUITapGestureRecognizerActionNSAction rozhraních API.

Vlastní delegáti nahrazeni akcí < T>

Ve sjednocené části byly některé jednoduché delegáty .net (např. jeden parametr) nahrazeny . Například

public delegate void NSNotificationHandler (NSNotification notification);

teď můžete použít jako Action<NSNotification> . Tím se podporuje opětovné použití kódu a omezení duplikace kódu v xamarin.iOSu i ve vašich vlastních aplikacích.

Logická < hodnota > úlohy byla nahrazena logickou < hodnotou úlohy, chybou NSError>>

V klasickém rozhraní byla některá asynchronní rozhraní API, která vracejí . Nicméně některé z nich, kde se mají použít, když byl součástí podpisu, tj. objekt byl již a museli jste zachytit výjimku, abyste NSErrorbooltrue získali NSError .

Vzhledem k tomu, že některé chyby jsou velmi běžné a návratová hodnota nebyla užitečná, tento vzor se změnil jednotně tak, aby vracel . To vám umožní zkontrolovat úspěch i jakoukoli chybu, ke které mohlo během asynchronního volání do došlo.

NSString vs. řetězec

V několika případech bylo třeba některé konstanty změnit z string na NSString , např. UITableViewCell

Klasické

public virtual string ReuseIdentifier { get; }

Jednotný

public virtual NSString ReuseIdentifier { get; }

Obecně dáváme přednost typu System.String .NET. Navzdory pokynům společnosti Apple však některé nativní rozhraní API porovnávaly konstantní ukazatele (nikoli samotný řetězec), a to může fungovat pouze v případě, že konstanty zveřejňujeme jako NSString .

Objective-C Protokoly

Původní monoTouch nenaplnil podporu protokolů ObjC a přidalo se některé neoptimální rozhraní API pro podporu nejběžnějšího scénáře. Toto omezení už neexistuje, ale kvůli zpětné kompatibilitě se v rámci a uchovávají několik rozhraní monotouch.dllXamMac.dll API.

Tato omezení byla ve sjednocených rozhraních API odebrána a vyčištěna. Většina změn bude vypadat takhle:

Klasické

public virtual AVAssetResourceLoaderDelegate Delegate { get; }

Jednotný

public virtual IAVAssetResourceLoaderDelegate Delegate { get; }

Předpona I znamená I vystavení rozhraní místo konkrétního typu pro protokol ObjC. To usnadní případy, kdy nechcete podtřídu konkrétního typu, který poskytl Xamarin.iOS.

Umožnilo také, aby některé rozhraní API bylo přesnější a snadno se používá, například:

Klasické

public virtual void SelectionDidChange (NSObject uiTextInput);

Jednotný

public virtual void SelectionDidChange (IUITextInput uiTextInput);

Takové rozhraní API je teď pro nás jednodušší, aniž by odkazoval na dokumentaci, a dokončování kódu v integrovaném vývojovém prostředí vám poskytne užitečnější návrhy založené na protokolu nebo rozhraní.

Protokol NSCoding

Naše původní vazba obsahovala .ctor(NSCoder) pro každý typ, i když protokol NSCoding nepodporuje. Pro kódování objektu byla v objektu Encode(NSCoder)NSObject k dispozici jedna metoda. Tato metoda by ale fungovala jenom v případě, že instance odpovídá protokolu NSCoding.

Na Unified API jsme tento problém opravili. Nová sestavení budou mít pouze , .ctor(NSCoder) pokud typ odpovídá NSCoding . Tyto typy teď mají také Encode(NSCoder) metodu , která odpovídá INSCoding rozhraní .

Nízký dopad: Ve většině případů tato změna neovlivní aplikace, protože starý, odebraný, konstruktory se nepoužíly.

Další Tipy

Další změny, o které byste měli vědět, jsou uvedené v tipech pro aktualizaci aplikací na Unified API.