Forum Xamarin Xamarin.iOS

HttpClient object does not works second time on Xamarin.iOS

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

I use HttpClient object for PostAsync. I need to add BackgroundSessionConfiguration for iOS while I am creating HttpClient object. So I changed my code like this:

var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("my.app.identifier");
_client = new HttpClient (new NSUrlSessionHandler (configuration));

This works when I send first request with PostAsync. But when I send request second time, it doesn't work.

I did it for Login Operation like this: (It works first time but if I logout and login again, it doesn't work.)

public class LoginService
    {
        private HttpClient _client;

        public LoginService()
        {
            if (_client == null)
                {
                    _client = Helper.CreateHttpClientLogin(_client);
                }
        }

    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;
        }
}

public class Helper
{
    public static HttpClient CreateHttpClientLogin(HttpClient _client)
    {
            if (Device.RuntimePlatform == Device.iOS)
                {
                    var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration("my.app.identifier");
                    _client = new HttpClient(new NSUrlSessionHandler(configuration));
                }
                else
                {
                    //_client = new HttpClient(new System.Net.Http.HttpClientHandler());
                    HttpClientHandler handler = new HttpClientHandler();
                    handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
                    _client = new HttpClient(handler);
                }

            return _client;
        }
}

And I have this code on AppDelegate: (I don't know but maybe it causes the bug)

public static Action BackgroundSessionCompletionHandler;
public override void HandleEventsForBackgroundUrl(UIApplication application, string sessionIdentifier, Action completionHandler)
{
    // We get a completion handler which we are supposed to call if our transfer is done.
    BackgroundSessionCompletionHandler = completionHandler;
}

What must I do for this?

Answers

  • matrixlukanmatrixlukan Member ✭✭✭
    edited September 15

    Always create a new HttpClient object instead of a singleton. The HttpClient object should be transient so that each client object is immutable.
    I hope this solves your issue

  • pelinalpppelinalpp Member ✭✭✭
    edited September 21

    Actually it didn't worked for me but I have controled after your suggestion, when creates HttpClient object. And I realized I create it every login/logout operation. That's why I edited it to be create once. And it worked. So thank you for your suggestion. But now I have other error. This error occurs on iPhone 7 Plus devices. iOS version is: 13.6 but I tried it on iPad 13.6, it worked on iPad. That's why I don't think it is associated with iOS version.

    My new error:

    System.Net.Http.HttpRequestException: unknown error ---> Foundation.NSErrorException: Error Domain=NSURLErrorDomain Code=-1 "unknown error" UserInfo={NSErrorFailingURLStringKey=https://myurl/en/Api/Login, NSErrorFailingURLKey=https://myurl/en/Api/Login, _NSURLErrorRelatedURLSessionTaskErrorKey=(
        "BackgroundDataTask <7AA0C63B-B69F-4836-815F-0D3164E0EFDA>.<1>"
    ), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundDataTask <7AA0C63B-B69F-4836-815F-0D3164E0EFDA>.<1>, NSLocalizedDescription=unknown error}
       --- End of inner exception stack trace ---
      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 
      at FileOrbis.Services.LoginService.Login (FileOrbis.Models.RequestModels.LoginRequest request) [0x00084] in C:\Users\...
    

    I don't know it is associated or not but I have this configuration on info.plist:

        <key>NSAppTransportSecurity</key>
        <dict>
            <key>NSAllowsArbitraryLoads</key>
            <true/>
        </dict>
    

    I encountered with this when I search "NSErrorFailingURLStringKey"

Sign In or Register to comment.