Search code examples
c#iosxamarinxamarin.formsxamarin.essentials

How I can fix the warning about locationManagerDidChangeAuthorization and authorizationStatus in #Xamarin.Forms?


First of all, I did a little research but only found for Swift a native iOS answer.

The complete warning says:

This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the `-locationManagerDidChangeAuthorization:` callback and checking `authorizationStatus` first.

I have read that could be because I am using an async, away call; as well. I have read about the iOS version also: StackOverFlow/73805219 How I can fix this in Xamarin forms?

I must say that I am using Geolocalization from #Xamarin.Forms.Essentials to get the current longitud and latitude in an async function that I send by #MessaginCenter.

async Task StoringNoteAsync()
        {
            Location location = await _geolocation.GetCurrentLocation();


            NoteSelected = NoteSelected ?? new Note();


            NoteSelected.Title      = Title;
            NoteSelected.Content    = Content;
            NoteSelected.CreatedAt  = DateTime.Now;
            NoteSelected.iNoteType  = (int)SelectedNoteType;
            NoteSelected.Longitude  = location.Longitude;
            NoteSelected.Latitude   = location.Latitude;


            //_noteService.SaveNote( NoteSelected );


            MessagingCenter.Instance.Send( this, "upsert", NoteSelected );


            await _navigation.PopAsync();
        }

Solution

  • Sounds like you are on the UI thread, and need to run code on a different thread.

    Use Task.Run to get to a background thread.

    Since you are in an async method, and you are already running on MainThread, do it like this:

    async Task MyMethod()
    {
        // "await", so that "additional code" below is not run until this code finishes.
        // "async" is only needed if code in block uses "await".
        await Task.Run( async () =>
        {
            // code that needs to run on a background thread...
        });
    
        // additional code, that needs to run on the original thread...
        ...
    }
    

    ALTERNATIVE TO EXPLICITLY RUN ADDITIONAL CODE ON MAIN THREAD

    async Task MyMethod()
    {
        // (This part is same as first code snippet.)
        // "await", so that "additional code" below is not run until this code finishes.
        // "async" is only needed if code in block uses "await".
        await Task.Run( async () =>
        {
            // code that needs to run on a background thread...
            // e.g. long-running logic that does not touch UI.
        });
    
        // (This part is explicitly run on MainThread.)
        // "async" is only needed if code in block uses "await".
        await MainThread.InvokeOnMainThreadAsync( async () =>
        {
            // code that needs to run on MainThread (affects UI)...
        });
    }