简体   繁体   中英

Xamarin Forms Visual Studio 2015 HttpClient requests not working on iOS

I'm rather new to Xamarin Forms/ Visual Studio but here is my current situation. I have a Xamarin Forms project in Visual Studio with Android, iOS, and Windows Phone subprojects. I have the following function Login:

    public async Task<Tuple<bool, object>> Login(LoginCredentials credentials)
    {
        var loginUrl = apiUrl + "/login";
        var json = JsonConvert.SerializeObject(credentials);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        try
        {
            Debug.WriteLine("start of try block");
            HttpResponseMessage response = await client.PostAsync(loginUrl, content);
            Debug.WriteLine("this will not print on iOS");
            string bodyStr = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                // code that does stuff with successful response
            } else
            {
                // code that does stuff with bad response
            }
        } catch (Exception e)
        {
            Debug.WriteLine(e);
            return new Tuple<bool, object>(false, e.Message);
        }
    }

As you can see from the Debug.WriteLine() 's, an exception is thrown on the line:

HttpResponseMessage response = await client.PostAsync(loginUrl, content);

The exception is System.NullReferenceException: Object reference not set to an instance of an object

However, this exception only occurs on iOS. Android and Windows Phone can both successfully make this request.

My first assumption was that it was Apple's ATS which would make sense since my server is just a dev instance not using https. So I pasted in

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

to the iOS project's Info.plist. Still no luck.

I also read a question elsewhere that said to make sure Visual Studio on Windows and Xamarin on the Mac are both up to date which I have made sure of as well.

Also apiUrl is not http://localhost I am using the IPs on my local network (since the Mac and iOS simulator are running on a different machine) which I have confirmed are correct.

If I had to guess at this point, I would say it's still something with the ATS settings not being set properly but I've been unable to confirm this. Not sure where to go from here. I'll continue to debug and add updates but any help would be very much appreciated.

Update:

As suggested by Oleg Bogdanov , my client instance is not instantiated properly only when running iOS.

When debugging iOS: iOS HttpClient 调试

When debugging Android: Android HttpClient 调试

Now the task becomes figuring out why this is occurring on iOS. Here is the client initialization code. I have tried both where it currently is and where it is commented.

public class API
{
    public HttpClient client = new HttpClient();
    public string apiUrl = "http://myApiUrl";

    public API()
    {
        //this.client = new HttpClient();
    }

    public async Task<Tuple<bool, object>> Login(LoginCredentials credentials)
    {
        // login function code
    }
}

I'll keep debugging this and post another update when I have any new developments. As usual, any help greatly appreciated.

I found the solution here .

I ran NuGet Install-Package Microsoft.Net.Http to the Portable project and it is working now.

I don't think there is any with ATS. I have created one POC using localhost and shared local server . Please check following code which is working for my POC

For POST request

try
    {
        HttpClient client = new HttpClient();
        var uri = new Uri("http://localhost/RegisterDevice");
        string data = "{\"username\": \"ADMIN\",\"password\": \"123\"}";
        var content = new StringContent(data, Encoding.UTF8, "application/json");

        HttpResponseMessage response = null;
        response = await client.PostAsync(uri, content);
        Util.HideLoading();
        if (response.IsSuccessStatusCode)
        {
            System.Diagnostics.Debug.WriteLine(@"Success");
        }
        else
        {
            System.Diagnostics.Debug.WriteLine(@"Fail");                
        }
    }
    catch (Exception ex)
    {

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM