Forum Xamarin.iOS
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Xamarin.iOS PostAsync on Background

pelinalpppelinalpp Member ✭✭✭
edited September 9 in Xamarin.iOS

I try to login my xamarin forms app with radius. My radius login flow is:
1) I send request to my login api
2) Radius app gets my request and it sends notification
3) I click allow in this notification. After I can login.

My problem is:
When I try to login with android, I receive notification like this:

So that I can click approve from notification and I can login successfully.

But when I try to login with iOS, I receive notification like this:

I can't see approve or deny option on notification. So I have to open notification like this:

After I can click approve. But when I open notification detail, app goes background and my login PostAsync method send me this exception:

System.Threading.Tasks.TaskCanceledException: A task was canceled.
  at System.Net.Http.NSUrlSessionHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x001d4] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.20.2.2/src/Xamarin.iOS/Foundation/NSUrlSessionHandler.cs:527 
  at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) [0x0017e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:506 

My login api request method is:

public async Task<LoginResponse<LoginDataResponse>> Login(LoginRequest request)
        {
            LoginResponse<LoginDataResponse> responseModel = new LoginResponse<LoginDataResponse>();
            try
            {
                string json = JsonConvert.SerializeObject(request);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                var jsonBody = await _client.PostAsync(App.ServiceURL.Login_Url, content);
                string jsonstr = await jsonBody.Content.ReadAsStringAsync();

                if (jsonstr == null || jsonstr == "")
                {
                    responseModel.Success = false;
                    responseModel.Status = 0;
                    responseModel.Message = AppResources.UnknownHostException;
                }
                else
                    responseModel = (LoginResponse<LoginDataResponse>)JsonConvert.DeserializeObject(jsonstr, typeof(LoginResponse<LoginDataResponse>));
            }
            catch (Exception ex)
            {
                string text = ex.ToString();
                responseModel.Status = 0;
                AppResources.Culture = CrossMultilingual.Current.CurrentCultureInfo;
                responseModel.Message = AppResources.UnknownHostException;
            }
            return responseModel;
        }

When I click notification on ios, login request throw above error with catch.

How can I continue PostAsync on background?

Best Answer

  • pelinalpppelinalpp Member ✭✭✭
    edited September 9 Accepted Answer

    I saw this. But it is not suitable for me. Because i didn't implement push notification (So I haven't DidReceiveRemoteNotification method).
    My api method does it for me. (My login method communicates with Radius app. Then my api returns response. I just trigger login method and wait response.)

    And thank you anyway for your answer. But I found a solution after dealing with this problem for hours. I add a configuration to HttpClient object for iOS. This configuration is:

    if(Device.RuntimePlatform == Device.iOS)
    {
        var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("my.app.identifier");
        configuration.AllowsCellularAccess = false;
        _client = new HttpClient (new NSUrlSessionHandler (configuration));
    }
    else
    {
        //android codes
    }
    

    And I use this client object for PostAsync. It works for me.

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai

    app goes background and my login PostAsync method send me this exception

    When a notification comes on iOS, the DidReceiveRemoteNotification will be called. To avoid this issue, try to use the MessagingCenter to execute the code.

    public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
    {
        MessagingCenter.Send<object>(this, "Notification");
    }
    

    Check the link:
    https://forums.xamarin.com/discussion/comment/400181/#Comment_400181

  • pelinalpppelinalpp Member ✭✭✭
    edited September 9 Accepted Answer

    I saw this. But it is not suitable for me. Because i didn't implement push notification (So I haven't DidReceiveRemoteNotification method).
    My api method does it for me. (My login method communicates with Radius app. Then my api returns response. I just trigger login method and wait response.)

    And thank you anyway for your answer. But I found a solution after dealing with this problem for hours. I add a configuration to HttpClient object for iOS. This configuration is:

    if(Device.RuntimePlatform == Device.iOS)
    {
        var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("my.app.identifier");
        configuration.AllowsCellularAccess = false;
        _client = new HttpClient (new NSUrlSessionHandler (configuration));
    }
    else
    {
        //android codes
    }
    

    And I use this client object for PostAsync. It works for me.

Sign In or Register to comment.