Xamarin: FirebaseMessaging update = breaking production

Az alapvető probléma az az, hogy az Apple megszünteti Áprilistól a UIWebView használatát, és minden olyan binárist, ami ezt az implementációt tartalmazza, elfogják utasítani a Store-ba való publikálásnál. Erre léptek egyet a Xamarin fejlesztők, és kijelentették, hogy a Xamarin Forms 4.4-től felfelé megváltoztatták WebView implementációt iOS-en , hogy az új iOS VKWebView implementációját használja. Felfrissítettem minden csomagot úgy, hogy 4.4 legyen a Forms verzió, de ez nem hozta a várt eredményt, mert a csomagba ugyanúgy belecsomagolja a fordító a UIWebView-t. Erről egy Microsoftos srác blogján olvastam, hogy a visszafelé kompatibilitás miatt a linkerbe is belekellet nyúlniuk (https://devblogs.microsoft.com/xamarin/uiwebview-deprecation-xamarin-forms/), de hoyg hatása legyen az alkalmazásra csak a Xamarin Forms 4.5 verziójától érvényes. Viszont a Xamarin Forms 4.5-ös verziójába behozták Androidhoz az AndroidX libraryt, aminek a hatására egy csomó androidos szívás jött cserébe, mert a visszafelé kompatibilitás miatt az android 10 alatti libekhez is kellenek NuGet csomagok, és az android 10 és feletti AndroidX könyvtárakhoz is kellenek NuGet csomagok, úgyhogy végtelen NuGet installba kezdtem. Nem maradt már végül olyan csomag a Solutionben, amit ne kellett volna a függőségek miatt updatelni. Ezzel csak az volt a baj, hogy mivel minden csomag frissült, a Xamarin Firebase iOS bindingban pedig el van szúrva jelenleg is valami, méghozzá az, hogy az appokat az apple kapásból visszautasítja, mert olyan metódusnevet használ az egyik Xamarin.Firebase.IOS framework, ami blacklistes az apple szerint, éppen ezért a te appodat élből dobják vissza. Erre persze nekünk a PushNotificationök miatt van szükségünk, ezért nem hagyhatjuk figyelmen kívül a funkcionalitást egy kis időre. Szerencsére mások is észrevették, hogy ez a hiba nem jó így, és a hiba már ki is van javítva, de a pull request ott áll még a Xamarin előtt, mert a srác 16 órája még módosítást eszközölt a kódban. (https://github.com/xamarin/GoogleApisForiOSComponents/pull/388https://github.com/xamarin/GoogleApisForiOSComponents/pull/388)

Erre még rájött az, hogyha minden csomagot a Pre-Releasere updatelsz, vagy csak szimplán hagyod a 4.5-ös Formsot, a hozzáfrissített Xamarin.IOSFirebase implementációval hogy iOS-re releasebe forduljon, lazán kifordítja az appot, és miután elindul az app kivágja a usert a főképernyőre. Szerencsére debug windowban ott a hiba, hogy : “dyld: symbol ‘OBJC_CLASS$_GULUserDefaults’ not found, expected in ‘/private/var/containers/Bundle/Application/ID/APPLICATIONNAME/Frameworks/GoogleUtilities.framework/GoogleUtilities’, dyld: symbol ‘OBJC_CLASS$_GULUserDefaults’ not found, expected in ‘/private/var/containers/Bundle/Application/ID/APPLICATIONNAME/Frameworks/GoogleUtilities.framework/GoogleUtilities’, ” ami remélhetőleg szintén javítva lesz ebben a pull requestben, mert ez már a Google frameworkje miatt lehet (abból sejtem, mert ezt már maga az XCode mondja, és nem a VisualStudio/Xamarin)

Úgyhogy egyetlen megoldásunk az maradt, hogy az ügyfélnek úgy tesszük ki testflightra az appokat, hoyg elviseljük az Apple warningjait, hogy deprecated a UIWebView. Aztán mivel ez egy időzített bomba, hamarosan berobban, és majd nem fogják ezeket elfogadni, akkor viszont a Xamarin.IOS.Firebase csomag frissítésétől fogunk függeni.

This content has 4 years. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.

Xamarin Forms 4.5 Update

Sziasztok. Ebben a posztban a Xamarin Forms 4.5 update tapasztalatokat szeretném veletek megosztani. Mivel ez egy nagy update, az AndroidX libekkel, és iOS fronton a UIWebView deprecation javításával, ezért megérdemel egy posztot.

Első lépés: Unloadold az Androidos projektjeidet Windowson.
Lehet hogy ez csak nálam gázos, de amikor a TargetFrameworkot szeretném állítani, belefagy a VisualStudio az állításba. Így én Unloadolom az androidos projektjeimet és átállítom a csoproj fájlban kézzel a target frameworkot. Ez a csproj edit pont kapóra is jön, mert nugeteket is kell hozzáadnunk (nem csak frissítenünk) android esetén.
10-es TargetFramework beállítása XML-ben:

    <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>

Aztán kelleni fognak akövetkező NuGet-ek, adjuk őket hozzá a csproj fájlba a references headnél:

<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.1.0-rc1" />
 <PackageReference Include="Xamarin.AndroidX.Browser" Version="1.0.0-rc1" />
 <PackageReference Include="Xamarin.Google.Android.Material" Version="1.0.0-rc1" />
 <PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0-rc1" />

Mentés után reloadolhatjuk a Solution Explorerben a projekteket, érdemes ezután egy Restore NuGet packagest nyomni a Solutionre.

Második lépés: Xamarin Android package update
Mivel nem fogjuk tudni addig feltelepíteni a Xamarin Forms package-t, ameddig nincs fent a latest Xamarin.Android.* csomagból minden, ezért frissítenünk kell azokat is, ha kell egyesével.. Ha van frissítés a Xamarin.AndroidX csomagokhoz, akkor azokat is érdemes frissíteni.

2.5: Nincs frissítés conflict nélkül: Teljesen kikészülök ettől a NuGet helltől, ez függ ettől, az attól.. Lényeg a lényeg: Személyes tapsztalatom szerint, ajánlatos, ha nincs consolidate package a solutionben, és azok csak egy verzióra vannak a 4.5-től. Itt beleértve a Xamarin.Essentials, Xamarin.Forms.Maps csomagot is, amiktől igazán rémálom az update.

3. Lépés: Telepíts ha tudsz! Ideális esetben, Xamarin.Forms csomagon egy frissítés. Ha nem ideális, mert hát miért is lenne az, akkor végigvered egyesével, hogy melyik projekt miért függ ettől a verziótól, és mit kell még frissítened pluszba

This content has 4 years. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.

Xamarin iOS: FirebaseMessaging NuGet frissítés

Hibajelenség: Az alkalmazás lefordul, és deployolódik az iOS-t futtató telefonra, de az indítás után azonnal bezárul, és a debugger nem veszi ezt észre.

Hibaüzenet az OutputWindow-ban

dyld: symbol '_OBJC_CLASS_$_GULUserDefaults' not found, expected in '/private/var/containers/Bundle/Application/ID/APPLICATIONNAME/Frameworks/GoogleUtilities.framework/GoogleUtilities', needed by '/private/var/containers/Bundle/Application/ID/APPLICATIONNAME/Frameworks/FirebaseMessaging.framework/FirebaseMessaging'

Clean solution nem oldja meg a problémát.

Nálam a bin és az obj mappák manuális törlése megoldotta a problémát a DEBUG buildhez, de akinek továbbra is problémája adódik ezzel az próbálja ki a következő módszereket:
https://stackoverflow.com/questions/57131541/issue-with-nuget-package-xamarin-firebase-ios-cloudmessaging-3-1-2

Azonban Release módban ugyanúgy nem működik az alkalmazás.

This content has 4 years. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.

Xamarin Forms: Custom Rendererek más assemblyből

A Xamarin Forms a CustomRenderer Attribútumot csak a betöltött referenciák között keresi. Ez azt jelenti, hogyha egy másik projektben található a customrenderer, akkor annak a projektnek kifordított dll-jének már a Forms.Init előtt be kell töltődnie. Jó megoldás lehet, ha létrehozunk egy statikus osztályt, aminek a statikus Initalize metódusára ráhívunk Android esetén az onCreate, iOS esetén pedig az AppDelegate FinishedLauching függvényében.

public static class Initainer
{
    public static void Initalize()
    {
        Console.WriteLine("Initainer is initializing Custom renderers")
    }
}
This content has 4 years. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.

Xamarin Forms: Auto magasságú ListView

Formsban, ha egy ListView HorizontalOptions, VerticalOptions tulajdonságait Fill-re állítjuk, és a ListView egy Grid sorában van mondjuk, amelynek a Height-je Auto, a lista le fogja foglalni a Grid által kínált összes helyet. Ez azért van, mert a ListView measure-nél még nem tudja hogy milyen listaelemek milyen listaelem formátummal fognak megjelenni benne. Így elveszítjük a lehetőséget a dinamikus megjelenítésre, mert a felületünk szét fog csúszni.

Ennek a problémakörnek megoldásaképpen készítettem egy olyan ListView-t, amely képes a listaelemek tényleges lemért magassága után újraméretezni a lista magasságát. Ez a lista, mindig a benne található elemek magassága méretűre fog nyúlni. Meg lehet még fűszerezni annyival, hogy a Separatorok magasságát is beleszámolja, illetve hogy legyen egy maximálisan engedett magassága is, én ezt nem tettem meg, de jó kiindulási alap.

 public class AutoHeightListView : ListView
    {
        public AutoHeightListView()
        {
        }

        protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            // ItemsSource változásakor 
            if (propertyName == nameof(ListView.ItemsSource))
            {
                if(ItemsSource != null)
                {
                    // Kikérjük a ListView feltemapltezett celljeit.
                    IEnumerable<PropertyInfo> pInfos = (this as ItemsView<Cell>).GetType().GetRuntimeProperties();
                    var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");

                    if (templatedItems != null)
                    {
                        var cells = templatedItems.GetValue(this);
                        if(cells is Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell> cellsCasted)
                        {
                            if(cellsCasted.Count != 0)
                            {
                                ((ViewCell)cellsCasted.Last()).View.SizeChanged += FirstElementHeightChanged;
                            }
                        }
                    }
                }
            }
        }

        double prevHeight = 0;

        private void FirstElementHeightChanged(object sender, EventArgs e)
        {
            SetHeightRequestByCellsHeight();
        }

        /// <summary>
        /// Megméri minden sor Viewcell magasságát, és az egész listview magasságát ezeknek az összegére állítja be.
        /// </summary>
        private void SetHeightRequestByCellsHeight()
        {
            double calculatedHeight = 0;

            // Kikérjük a ListView feltemapltezett celljeit.
            IEnumerable<PropertyInfo> pInfos = (this as ItemsView<Cell>).GetType().GetRuntimeProperties();
            var templatedItems = pInfos.FirstOrDefault(info => info.Name == "TemplatedItems");

            if (templatedItems != null)
            {
                var cells = templatedItems.GetValue(this);
                foreach (ViewCell cell in cells as Xamarin.Forms.ITemplatedItemsList<Xamarin.Forms.Cell>)
                {
                    calculatedHeight += cell.View.Height;
                }
            }

            if (calculatedHeight == prevHeight)
                return;

            prevHeight = calculatedHeight;
            HeightRequest = calculatedHeight;
        }
    }
This content has 4 years. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.