XLabs 2.0 pre release

rmarinhormarinho PTMember, Insider, Beta Xamurai
edited January 2015 in Xamarin.Forms

Hi everyone there's a new set of nugets for XLabs (aka Xamarin Forms Labs) on the wild. this is the 2.0 version where there are a lot of breaking changes, and a decoupling on some of the specific Xamarin Forms features.
There's no classic support, only the new unified.

There's no upgrade process via nuget, you will have to remove the old packages and install some new ones

You will now have to add XLabs Forms package that will install other 2 dependencies XLabs Platform and XLabs Core.

You will have to use DependencyService.Register<>() on your platforms packages to register XLabs Services.

There are a lot of namespace changes , so you will have to fix your code.

This is a new prerelease and in early testing.

Please provide feedback on github .

«1

Posts

  • Hi .

    I 'm updating packages Xlabs to prerelease3 and got the following error when I add the IOS Xlabs.Forms package

    Unable to resolve dependency XLabs.Platform.iOS (≥ 2.0.0-pre2).

    I have already added the package Xamarin.Platform pre3

  • SKallSKall USMember ✭✭✭✭

    I believe I got things fixed now. @bialguoss‌, can you try updating (pre6)? Some minor issue with WP8 (XLabs.Platform.WP8 reference not added automatically) but everything else (installing XLabs.Forms) seemed to work ok.

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭

    If I install pre7 the XLabs.Ioc is not installed in iOS project, so I have no SimpleContainer().

  • SKallSKall USMember ✭✭✭✭

    You can just install XLabs.Ioc by itself. I will fix this in the final release.

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭
    edited January 2015

    Thanx, this works. But I have now another problem.....with IGeolocator.
    var geolocator = DependencyService.Get<IGeolocator>();

    returns always null. Is this an known issue ?

  • SKallSKall USMember ✭✭✭✭
    edited January 2015

    DependencyService is a class in XF and IGeolocator is located in XLabs.Platform that has no dependency to XF (by design). You would have to register the IGeolocator either with DependencyService or IResolver within your project.

  • Ok, thanks, I try it

  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭
    edited January 2015

    Hi. I'm using the lastest release of XLabs and it seems that the CheckBox is broken. VerticalOptions and HorizontalOptions are no longer assignable. Could not resolve SetBinding() and Argument type "XLabs.Forms.Controls.CheckBox" is not assignable to parameter type "Xamarin.Forms.View". Just seen that CalendarView has the same problem
    I looked throught the source code and it inherits from View

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭
    edited January 2015

    @Skall I do not really understand what you mean. Formerly with 1.2 I just had to do :
    var resolverContainer = new SimpleContainer(); resolverContainer.Register<XLabs.Platform.Device.IDevice> (t => AppleDevice.CurrentDevice);
    in iOS project and a

    var geolocator = DependencyService.Get<IGeolocator>();

    in Forms project. Is there now another way to register Location services ?

  • Hi, I installed the prerelease8 and everything ok, except the deployment to a terminal.
    The error is
    / Users / Capstesia / Projects / PruebaXamarin / iOS / MTOUCHTASK : MT2002 Error : Failed to resolve " Xamarin.Forms.BindableProperty Xamarin.Forms.BindableProperty::Create(System.Linq.Expressions.Expression1<System.Func2<!!0,!!1>>,!!1,Xamarin.Forms.BindingMode,Xamarin.Forms.BindableProperty/ValidateValueDelegate1<!!1>,Xamarin.Forms.BindableProperty/BindingPropertyChangedDelegate1<!!1>,Xamarin.Forms.BindableProperty/BindingPropertyChangingDelegate1<!!1>,Xamarin.Forms.BindableProperty/CoerceValueDelegate1<!!1>)" reference from " Xamarin.Forms.Core , Version = 1.2.3.0 , Culture = neutral , PublicKeyToken = null " ( MT2002 ) ( PruebaXamarin.iOS )

  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭

    SimpleContainer is part of the IoC library. Register the service in MainActivity.cs in your android project like this: resolverContainer.Register<IGeolocator>(t => t.Resolve<Geolocator>()). In your shared code you should use Resolver.Resolve<IGeolocator>()

  • FredyWengerFredyWenger CHInsider ✭✭✭✭✭

    @skall:
    I think, all XF-users will have to update to XF 1.3.1.xx in the near time...
    Do you (the team) plan to post an official update to .labs in NuGet and update the project-information's (how to install/register labs -> see link below) in the near time?
    https://github.com/XLabs/Xamarin-Forms-Labs

    Thanks for a short feedback.

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭

    @RaphaelSchindler‌

    In my iOS project I do a :
    var resolverContainer = new SimpleContainer(); resolverContainer.Register<XLabs.Platform.Device.IDevice> (t => AppleDevice.CurrentDevice); Resolver.SetResolver(resolverContainer.GetResolver());
    in my shared project :

    var geolocator = DependencyService.Get<IGeolocator>(); geolocator.PositionChanged += OnPositionChanged; geolocator.StartListening(30000, 0, true);

    this works with formerly versions of Forms and XLabs. But with the current version DependencyService.Get returns always null. Thats the point I don't understand.

  • rmarinhormarinho PTMember, Insider, Beta Xamurai

    Guys , now you will have to register all services before using them, they aren't register by default in the Xamarin Forms DependencyService like they were before.

    @FredyWenger‌ the official update is out in pre release..

    We will update the documentation as possible

  • rmarinhormarinho PTMember, Insider, Beta Xamurai

    @AxelStallknecht‌ you will now need to do this in your iOS project:

    DependencyService.Register<Geolocator>();

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭

    @rmarinho‌ After your posting I read your first posting again.....sorry...for my questions....I haven't read that, so it had to become clear...earlier. ;)

    But.....I added
    DependencyService.Register<IGeolocator>();
    to my iOS Project.

    In the Forms project I get an System.MissingMethodException (Cannot create an abstract class XLabs.Platform.Services.GeoLocation.IGeolocator) at

    var geolocator = DependencyService.Get<IGeolocator>();

  • rmarinhormarinho PTMember, Insider, Beta Xamurai

    You should register on iOS the implementation:

    DependencyService.Register<Geolocator>();

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭

    @rmarinho‌ Oh yes.....now it works !!! A BIG THANKS to you and all other developers for working on XLabs and supporting users !!!!! Great great Job, guys !!!!

  • SKallSKall USMember ✭✭✭✭

    @AxelStallknecht‌, in general you should avoid using DependencyService for items other than Xamarin Forms renderers. For others you should consider using the static Resolver class which is a wrapper around IResolver interface (implemented by your choice of the Ioc containers). See the post by @RaphaelSchindler‌ above for an example.

  • AxelStallknechtAxelStallknecht DEUniversity ✭✭

    @SKall‌ OK.....Thanks for your hint.

  • bvehsebvehse USMember
    edited February 2015

    Hi guys, thanks for your great work.

    Using
    DependencyService.Register<Geolocator> ();
    and
    geolocator = DependencyService.Get<IGeolocator> ();

    works fine on iOS. But on Android this still returns null.

    I also tried the following:

    var resolverContainer = new SimpleContainer ();
    resolverContainer.Register<IGeolocator> (t => t.Resolve<Geolocator> ());
    Resolver.SetResolver (resolverContainer.GetResolver());
    

    and

    geolocator = Resolver.Resolve<IGeolocator> ();

    But this causes the following exception to be thrown:

    System.Diagnostics.Debugger.Mono_UnhandledException (ex={System.InvalidOperationException: IResolver has not been set. Please set it by calling Resolver.SetResolver(resolver) method.

    I did setup the Resolver as stated above.

    Do you have any advice on what I could do differently? Thanks a lot!

    RESOLVED: After removing all NuGet packages and restoring them, restarting XamarinStudio and doing a clean build it works now (using the DependencyService).

  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭

    @bvehse Can you post the code from your MainActivity.cs and AppDelegate.cs

  • bvehsebvehse USMember
    edited February 2015

    Hi @RaphaelSchindler, thanks for responding so quickly.

    As I wrote at the end of my post, I was able to resolve the issue. It seems to have been a case of wrong dependencies being compiled or used from cache.

    For completeness-sake I'll attach my implementation using the DependencyService for further reference:

    MainActivity.cs (Android)

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
    
        Xamarin.Forms.Forms.Init (this, bundle);
        Xamarin.FormsMaps.Init(this, bundle);
    
        //register XLabs Geolocator service
        DependencyService.Register<Geolocator> ();
    
        [...]
    }
    

    AppDelegate (iOS)

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        Forms.Init ();
        FormsMaps.Init();
    
        //register XLabs Geolocator service
        DependencyService.Register<Geolocator> ();
    
        [...]
    }
    

    LocationHelper (Shared PCL)

        if (geolocator == null) {
                //retrieve XLabs Geolocator service
                geolocator = DependencyService.Get<IGeolocator> ();
                geolocator.PositionChanged += OnPositionChanged;
                geolocator.PositionError += OnListeningError;
                geolocator.StartListening (30000, 0, true);
        }
    

    Using Resolver (see code in my earlier post) like @SKall‌ advised didn't work for me. Resolver.Resolve<IGeolocator> () always returned null.

  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭
    edited February 2015

    @bvehse Ok I haven't seen your edit. Great that it works now :smile:
    For the Resolver, which should be used for XLabs.Services does your MainActivity.cs inherit from XFormsApplicationDroid?

  • bvehsebvehse USMember
    edited February 2015

    @RaphaelSchindler It does. I really should have posted the whole class after all:

        [Activity (Label = "XYZ", MainLauncher = true, ConfigurationChanges =
    ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
        public class MainActivity : XFormsApplicationDroid
        {
                protected override void OnCreate (Bundle bundle)
                {
                    base.OnCreate (bundle);
    
                    Xamarin.Forms.Forms.Init (this, bundle);
                    Xamarin.FormsMaps.Init(this, bundle);
    
                    //register XLabs Geolocator service
                    DependencyService.Register<Geolocator> ();
    
                    SetPage (App.GetMainPage ());
                }
        }
    
  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭

    @bvehse I've tested it in my application with the GeoLocator and Resolver and it does just return null. So this is a bug in XLabs. I think you should tell them about that. https://github.com/XLabs/Xamarin-Forms-Labs/issues

  • bvehsebvehse USMember

    @RaphaelSchindler Thanks a lot for checking it out! I really appreciate it and I'll submit an issue after getting some lunch. ;-)

  • bvehsebvehse USMember

    @RaphaelSchindler I've opened an issue regarding the Resolver returning null for the Geolocator service here https://github.com/XLabs/Xamarin-Forms-Labs/issues/637

  • SKallSKall USMember ✭✭✭✭

    I just tested this with the latest NuGet packages and everything works fine. Below is the code to set the Geolocator from Android's side.

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
    
            var container = new SimpleContainer();
    
            container.Register<IGeolocator, Geolocator>();
    
            Resolver.SetResolver(container.GetResolver());
    
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    
  • On iOS I still am unable to clear the issue where geolocator.IsGeolocationEnabled is always false, using either the Dependency Service or Resolver implementations. I do have both NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription set in the plist.

    The code was working before in the old version. The app would prompt for permission to use the location, but the current version does no such thing.

    Has anyone actually gotten the Geolocator to work on iOS with the current version?

    Thanks.

  • LuckyDayLuckyDay USMember ✭✭✭

    @SikkuDevelopers Yep. At some point there was a change where calling StartListening (or whatever that method is called, not sure if thats it exactly off the top of my head) no longer calls CLLocationManager.RequestAuthorization on iOS. So you need to do that yourself. Personally I like the change as it means I have more control over when that dialog is presented to the user.

  • RaphaelSchindlerRaphaelSchindler USMember ✭✭✭

    @SikkuDevelopers Try this code in your AppDelegate.cs: .Register<IGeolocator>(new Geolocator()) and in the PCL Resolver.Resolve<IGeolocator>(); that did work for me.

  • Junior.4184Junior.4184 USMember ✭✭

    I am getting this error
    container.Register<IGeolocator, Geolocator>()

    Error 16 'Geolocator' is a 'namespace' but is used like a 'type'

  • SKallSKall USMember ✭✭✭✭

    @Junior.4184 that sounds like a namespace clash. Is the code you're calling from inside a namespace that contains "Geolocator"?

  • Junior.4184Junior.4184 USMember ✭✭

    using System;

    using Android.App;
    using Android.Content;
    using Android.Locations;
    using Android.Content.PM;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Android.OS;
    using Xamarin.Forms;
    using XLabs.Platform.Services.Geolocation;
    using XLabs.Ioc;

    namespace App1.Droid
    {
    [Activity(Label = "App1", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Theme = App.LightTheme)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
    protected override void OnCreate(Bundle bundle)
    {
    base.OnCreate(bundle);

            var container = new SimpleContainer();
    
            container.Register<IGeolocator, Geolocator>();
    
            Resolver.SetResolver(container.GetResolver());
    
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
    

    }

  • SKallSKall USMember ✭✭✭✭
    edited February 2015

    Can you try this:

    container.Register<IGeolocator, global::XLabs.Platform.Services.Geolocation.Geolocator>();
    
  • Junior.4184Junior.4184 USMember ✭✭

    Thank you very much Sami. Using Resolver always return nulll

  • RickWhalley.8591RickWhalley.8591 GBMember, University

    Hi Sami,
    I am working on a simple project to fetch the current location of the android mobile device (HTC One M8).
    I have started off with XAMARIN FORMS (PCL) project and followed the steps you have mentioned above in OnCreate() of DROID MainActivity function.

    But the code below gives some unexpected results.

    override void OnAppearing()
    {
    var geo = DependencyService.Get();
    }

    (geo.IsGeoLocationAvailable , geo.IsListening, geo.SupportsHeading are always FALSE)

    Am I missing anything here? I have added Xamarin.Forms.Labs and Acr.XamForms.Mobile packages (in PCL, Droid projects) through Nuget.

    Many thanks,
    Venkat V R.

  • CaioshinCaioshin ITMember ✭✭
    edited July 2015

    Hello guys, I landed here looking for a way to have the geolocator plugin working on my xamarin Forms app.
    I just need to obtain position from GPS: I can obtain it without problems under Android simply awaiting the GetPositionAsync in this way:

    async public static Task<Geolocator.Plugin.Abstractions.Position> CurrentLocationAsync()
    {
    var locator = CrossGeolocator.Current;
    Geolocator.Plugin.Abstractions.Position position = null;
    locator.DesiredAccuracy = 500;

            if (locator.IsGeolocationAvailable)
                position = await locator.GetPositionAsync(timeout: 20000);
    
            return position;
        }
    

    but under iOS it doesn't works.
    I already added the Keys in my info.plist file:

    NSLocationAlwaysUsageDescription
    NSLocationWhenInUseUsageDescription

    and I modified my code registering the geolocator in my AppDelegate.cs file on ios project:

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {

            var container = new SimpleContainer();
            DependencyService.Register<IGeolocator, global::XLabs.Platform.Services.Geolocation.Geolocator>();
            Resolver.SetResolver(container.GetResolver());
    
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
    
    
            return base.FinishedLaunching(app, options);
        } 
    

    and trying to use it in my portable project in this way:

    async public static Task<Geolocator.Plugin.Abstractions.Position> CurrentLocationIOS()
    {
    IGeolocator geolocator = null;
    Geolocator.Plugin.Abstractions.Position position = null;
    geolocator = DependencyService.Get();
    if (geolocator != null)
    {
    if (geolocator.IsGeolocationEnabled)
    {
    try
    {
    if (!geolocator.IsListening)
    geolocator.StartListening(1000, 1000);

                        var task = await geolocator.GetPositionAsync(10000, CancellationToken.None);
    
                        if (task != null)
                        {
                            position = task;
                        }
                    }
                    catch { ; }
                }
            }
            return position;
        }
    

    the problem is that geolocator is always unkown.

    Another strange thing is that I never received a popup asking me that my app would like to use GPS position.

    Where's the mistake?

    Thank you

  • SKallSKall USMember ✭✭✭✭

    var container = new SimpleContainer(); DependencyService.Register<IGeolocator, global::XLabs.Platform.Services.Geolocation.Geolocator>();

    should be:

    var container = new SimpleContainer(); container.Register<IGeolocator, global::XLabs.Platform.Services.Geolocation.Geolocator>();

    And then:

    geolocator = DependencyService.Get();

    to

    geolocator = Resolver.Resolve<IGeolocator>();

Sign In or Register to comment.