Práce s nativními typy v multiplatformních aplikacích

tento článek popisuje použití nových typů iOS Unified API Native types (nint, nuint, nfloat) v aplikaci pro víc platforem, kde je kód sdílený se zařízeními bez iOS, jako je Android nebo Windows Phone operačních systémech.

Nativní typy 64 typů fungují s rozhraními API pro iOS a Mac. pokud píšete sdílený kód, který běží na androidu nebo Windows, bude nutné spravovat převod sjednocených typů na běžné typy .net, které můžete sdílet.

Tento dokument popisuje různé způsoby, jak pracovat s Unified API ze svého sdíleného a společného kódu.

Kdy použít nativní typy

Rozhraní Xamarin. iOS a Xamarin. Mac Unified API pořád obsahují intuintfloat datové typy, stejně jako RectangleFSizeFPointF typy a. Tyto existující datové typy by se měly dál používat v jakémkoli sdíleném kódu pro různé platformy. Nové nativní datové typy by se měly používat jenom při volání rozhraní API pro Mac nebo iOS, kde se vyžadují podpora typů pro architekturu.

V závislosti na povaze kódu je možné, že se může stát, že kód pro různé platformy bude potřebovat pracovat s nintnuintnfloat datovými typy a. Například: knihovna, která zpracovává transformace na čtvercová data, která dříve používala System.Drawing.RectangleF ke sdílení funkcí mezi verzemi aplikace Xamarin. iOS a Xamarin. Android, by se musela aktualizovat, aby zpracovávala nativní typy v iOS.

Způsob zpracování těchto změn závisí na velikosti a složitosti aplikace a na používanou formu sdílení kódu, jak je uvedeno v následujících oddílech.

Požadavky na sdílení kódu

Jak je uvedeno v dokumentu možnosti sdílení kódu , existují dva hlavní způsoby sdílení kódu mezi projekty pro různé platformy: sdílené projekty a přenosné knihovny tříd. Které ze dvou typů se použily, omezí možnosti, které máme při zpracování nativních datových typů v kódu pro různé platformy.

Přenositelné projekty knihovny tříd

Přenosná knihovna tříd (PCL) umožňuje zaměřit se na platformy, které chcete podporovat, a používat rozhraní k poskytování funkcí specifických pro konkrétní platformu.

vzhledem k tomu, že je typ Project PCL kompilován dolů na .DLL a a nemá žádný smysl Unified API, budete muset dál používat stávající datové typy ( int , uintfloat ) ve zdrojovém kódu PCL a typ přetypování volání tříd a metod pcl do front-endové aplikace. Například:

using NativePCL;
...

CGRect rect = new CGRect (0, 0, 200, 200);
Console.WriteLine ("Rectangle Area: {0}", Transformations.CalculateArea ((RectangleF)rect));

Sdílené projekty

typ Project sdíleného prostředku umožňuje organizovat zdrojový kód v samostatném projektu, který pak bude zahrnut a zkompilován do jednotlivých aplikací front-end specifických pro konkrétní platformu, a použít #if direktivy kompilátoru podle potřeby pro správu požadavků specifických pro platformu.

Velikost a složitost mobilních aplikací front-end, které využívají sdílený kód, spolu s velikostí a složitostí sdíleného kódu, je nutné vzít v úvahu při volbě metody podpory pro nativní datové typy v Project sdíleného prostředku pro různé platformy.

V závislosti na těchto faktorech mohou být implementovány následující typy řešení pomocí if __UNIFIED__ ... #endif direktiv kompilátoru pro zpracování Unified API specifických změn kódu.

Použití duplicitních metod

Vezměte v úvahu příklad knihovny, která provádí transformace na pravoúhlých datech uvedených výše. Pokud knihovna obsahuje jenom jednu nebo dvě velmi jednoduché metody, můžete se rozhodnout vytvořit duplicitní verze těchto metod pro Xamarin. iOS a Xamarin. Android. Například:

using System;
using System.Drawing;

#if __UNIFIED__
using CoreGraphics;
#endif

namespace NativeShared
{
    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        #if __UNIFIED__
            public static nfloat CalculateArea(CGRect rect) {

                // Calculate area...
                return (rect.Width * rect.Height);

            }
        #else
            public static float CalculateArea(RectangleF rect) {

                // Calculate area...
                return (rect.Width * rect.Height);

            }
        #endif
        #endregion
    }
}

Ve výše uvedeném kódu, protože CalculateArea rutina je velmi jednoduchá, použili jsme podmíněnou kompilaci a vytvořili samostatnou Unified API verzi metody. Na druhé straně, pokud knihovna obsahuje mnoho rutin nebo několik komplexních rutin, toto řešení nebude možné, protože by se mohlo jednat o problém udržení všech metod, které jsou synchronizované pro změny nebo opravy chyb.

Použití přetížení metod

V takovém případě může být řešením vytvoření verze přetížení metod pomocí 32 datových typů, aby nyní převzal CGRect jako parametr nebo návratovou hodnotu, převedli tuto hodnotu na RectangleF (s vědomím, že převod z nfloat na float je ztrátový převod) a zavolá původní verzi rutiny, která provede skutečnou práci. Například:

using System;
using System.Drawing;

#if __UNIFIED__
using CoreGraphics;
#endif

namespace NativeShared
{
    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        #if __UNIFIED__
            public static nfloat CalculateArea(CGRect rect) {

                // Call original routine to calculate area
                return (nfloat)CalculateArea((RectangleF)rect);

            }
        #endif

        public static float CalculateArea(RectangleF rect) {

            // Calculate area...
            return (rect.Width * rect.Height);

        }

        #endregion
    }
}

Znovu, toto řešení je vhodné, pokud ztráta přesnosti neovlivní výsledky pro konkrétní potřeby vaší aplikace.

Použití direktiv aliasu

V oblastech, kde je ztrátou přesnosti problém, další možné řešení je použití direktiv pro using Vytvoření aliasu pro nativní a CoreGraphics datové typy zahrnutím následujícího kódu do horní části souborů sdíleného zdrojového kódu a převodem všech potřebných intuint nebo float hodnot na nintnuint nebo nfloat :

#if __UNIFIED__
    // Mappings Unified CoreGraphic classes to MonoTouch classes
    using RectangleF = global::CoreGraphics.CGRect;
    using SizeF = global::CoreGraphics.CGSize;
    using PointF = global::CoreGraphics.CGPoint;
#else
    // Mappings Unified types to MonoTouch types
    using nfloat = global::System.Single;
    using nint = global::System.Int32;
    using nuint = global::System.UInt32;
#endif

Takže náš ukázkový kód pak bude:

using System;
using System.Drawing;

#if __UNIFIED__
    // Map Unified CoreGraphic classes to MonoTouch classes
    using RectangleF = global::CoreGraphics.CGRect;
    using SizeF = global::CoreGraphics.CGSize;
    using PointF = global::CoreGraphics.CGPoint;
#else
    // Map Unified types to MonoTouch types
    using nfloat = global::System.Single;
    using nint = global::System.Int32;
    using nuint = global::System.UInt32;
#endif

namespace NativeShared
{

    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        public static nfloat CalculateArea(RectangleF rect) {

            // Calculate area...
            return (rect.Width * rect.Height);

        }
        #endregion
    }
}

Všimněte si, že jsme tuto metodu změnili CalculateArea tak, aby vracela nfloat místo standardu float . To bylo provedeno tak, že se při pokusu o implicitní převod výsledku výpočtu (od vynásobení obou hodnot typu nfloat ) do návratové hodnoty neobjeví Chyba kompilace float .

Pokud je kód kompilován a spuštěn na zařízení, které není Unified API, using nfloat = global::System.Single; mapuje na, nfloatSingle který bude implicitně převeden na float Povolení náročné aplikace front-end pro volání CalculateArea metody beze změny.

Používání převodů typů v aplikaci front-end

V případě, že aplikace front-end několik pouze volání do vaší sdílené knihovny kódu, může jiné řešení opustit knihovnu beze změny a zatypování do aplikace Xamarin. iOS nebo Xamarin. Mac při volání existující rutiny. Například:

using NativeShared;
...

CGRect rect = new CGRect (0, 0, 200, 200);
Console.WriteLine ("Rectangle Area: {0}", Transformations.CalculateArea ((RectangleF)rect));

Pokud nenáročné aplikace poskytuje stovky volání do sdílené knihovny kódu, nemusí být vhodné řešení.

V závislosti na architektuře naší aplikace můžeme pomocí jednoho nebo více výše uvedených řešení v našem kódu pro různé platformy podporovat nativní datové typy (v případě potřeby).

Aplikace Xamarin. Forms

Aby bylo možné používat Xamarin. Forms pro uživatelská rozhraní pro různé platformy, které se budou sdílet s aplikací Unified API, je nutné provést následující:

  • celé řešení musí používat verzi 1.3.1 (nebo vyšší) balíčku NuGet Xamarin. Forms.
  • pro všechny vlastní sekreslovat Xamarin. iOS použijte stejné typy řešení, které jsou uvedené výše, podle toho, jak je kód uživatelského rozhraní sdílený (sdílený Project nebo PCL).

Stejně jako v případě standardní aplikace pro více platforem by v případě většiny situací měly být v jakémkoli sdíleném kódu pro různé platformy použity existující 32 datové typy. Nové nativní datové typy by se měly používat jenom při volání rozhraní API pro Mac nebo iOS, kde se vyžaduje podpora typů pro architekturu.

Další podrobnosti najdete v dokumentaci k naší aktualizaci existujících aplikací Xamarin. Forms .

Souhrn

V tomto článku jsme se seznámili s tím, kdy používat nativní datové typy v aplikaci Unified API a jejich důsledky pro různé platformy. Nabízíme několik řešení, která se dají použít v situacích, kdy se nové nativní datové typy musí používat v knihovnách pro víc platforem. Také jsme si poznamenali stručnou příručku k podpoře sjednocených rozhraní API v aplikacích Xamarin. Forms pro více platforem.