Forum Xamarin.iOS

NSUrlSession GET Request calls DidCompleteWithError but error is null

TobeTobe DEMember ✭✭

Hi,

currently I'm trying to switch from the deprecated NSUrlConnection to NSUrlSession. What I try to achieve is to call an IIS Webservice via GET requests and then handle the XML answers. I have two problems:

  1. If the answer is too long the NSData object in DidReceiveData does not contain everything. The answer is cropped after 1036 characters.
  2. After everything is done and while im already handling the received data (wether or not it was cropped), DidCompleteWithError is called. The "error" parameter in it is null so I have no idea why this is called and how to handle that. So even when I received all the data in DidReceiveData and everything is fine DidCompleteWithError is called.
    Here is my code, every help is appreciated. Thanks in advance!

     private NSMutableUrlRequest request;
            public NSUrlSessionDataTask dataTask;
            private Action<bool, string> completed;
            private string antwort;
            private NSUrlSession session;
            public NSOperationQueue myQueue;
    
            public void Invoke(string sUrl)
            {
                session = null;
                antwort = null;
                completed = null;
                myQueue = new NSOperationQueue();
    
                session = NSUrlSession.FromConfiguration(NSUrlSessionConfiguration.DefaultSessionConfiguration, (INSUrlSessionDelegate)new SessionDelegate((erfolg, body) => { completed(erfolg, body); }), myQueue);
                completed += WebserviceCallerIOS_Completed;
    
                try
                {
                    request = CreateNativePostRequest(sUrl);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    completed(false, "Error creating request: " + e);
                }
    
                dataTask = session.CreateDataTask(request);
                dataTask.Resume();
            }
    
            NSMutableUrlRequest CreateNativePostRequest(string url)
            {
                string converted = ((NSString)url).CreateStringByAddingPercentEscapes(NSStringEncoding.UTF8);
                var nsurl = NSUrl.FromString(converted);
    
                if (nsurl == null)
                    throw new Exception("Invalid URL, could not create NSUrl from: '" + url + "'.");
    
                var req = new NSMutableUrlRequest(nsurl) {HttpMethod = "GET"};
                return req;
            }
    
    private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
            {
                private Action<bool, string> completed_callback;
                private NSData retData;
                private int status_code;
    
                public SessionDelegate(Action<bool, string> completed)
                {
                    completed_callback = completed;
                    retData = new NSData();
                }
    
    
                public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
                {
                    var http_response = response as NSHttpUrlResponse;
                    if (http_response == null)
                    {
                        Console.WriteLine("Received non HTTP url response: '{0}'", response);
                        status_code = -1;
                        return;
                    }
    
    
                    status_code = (int)http_response.StatusCode;
    
                    if (status_code == 200)
                {
                    completionHandler(NSUrlSessionResponseDisposition.Allow);
                }
                else 
                {
                    completionHandler(NSUrlSessionResponseDisposition.Cancel);
                }
            }
    
    
                public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
                {
                    completed_callback(false, error?.LocalizedDescription);
                }
    
    
                public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
                {
                    retData = data;
                    dataTask.Suspend();
                    Console.WriteLine(retData);
                    completed_callback(true, retData.ToString());
                }
        }
    

    }

Best Answer

  • TobeTobe DE ✭✭
    Accepted Answer

    Cole Xia answered to me in my StackOverflow post, see here:

    Here is the rewritten code, if anyone is interested:

    private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
            {
                private Action<bool, string> completed_callback;
                private string answerCache;
                private int status_code;
    
                public SessionDelegate(Action<bool, string> completed)
                {
                    completed_callback = completed;
                    answerCache = "";
                }
    
    
                public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
                {
                    var http_response = response as NSHttpUrlResponse;
                    if (http_response == null)
                    {
                        Console.WriteLine("Received non HTTP url response: '{0}'", response);
                        status_code = -1;
                        return;
                    }
    
    
                    status_code = (int)http_response.StatusCode;
    
                    if (status_code == 200)
                    {
                        completionHandler(NSUrlSessionResponseDisposition.Allow);
                    }
                    else
                    {
                        completionHandler(NSUrlSessionResponseDisposition.Cancel);
                    }
                }
    
    
                public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
                {
                    if (error != null)
                    {
                        completed_callback(false, error.LocalizedDescription);
                    }
                    else
                    {
                        completed_callback(true, answerCache);
                    }
                }
    
    
                public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
                {
                    Console.WriteLine("*** " + dataTask.Progress.LocalizedDescription);
                    Console.WriteLine(data);
                    answerCache += data.ToString();
                }
    }
    

Answers

  • TobeTobe DEMember ✭✭
    Accepted Answer

    Cole Xia answered to me in my StackOverflow post, see here:

    Here is the rewritten code, if anyone is interested:

    private class SessionDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
            {
                private Action<bool, string> completed_callback;
                private string answerCache;
                private int status_code;
    
                public SessionDelegate(Action<bool, string> completed)
                {
                    completed_callback = completed;
                    answerCache = "";
                }
    
    
                public override void DidReceiveResponse(NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
                {
                    var http_response = response as NSHttpUrlResponse;
                    if (http_response == null)
                    {
                        Console.WriteLine("Received non HTTP url response: '{0}'", response);
                        status_code = -1;
                        return;
                    }
    
    
                    status_code = (int)http_response.StatusCode;
    
                    if (status_code == 200)
                    {
                        completionHandler(NSUrlSessionResponseDisposition.Allow);
                    }
                    else
                    {
                        completionHandler(NSUrlSessionResponseDisposition.Cancel);
                    }
                }
    
    
                public override void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
                {
                    if (error != null)
                    {
                        completed_callback(false, error.LocalizedDescription);
                    }
                    else
                    {
                        completed_callback(true, answerCache);
                    }
                }
    
    
                public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
                {
                    Console.WriteLine("*** " + dataTask.Progress.LocalizedDescription);
                    Console.WriteLine(data);
                    answerCache += data.ToString();
                }
    }
    
Sign In or Register to comment.