NSURLSession GET 请求:DidCompleteWithError - 错误为空

Posted

技术标签:

【中文标题】NSURLSession GET 请求:DidCompleteWithError - 错误为空【英文标题】:NSURLSession GET Request: DidCompleteWithError - error is null 【发布时间】:2018-04-16 09:21:10 【问题描述】:

目前我正在尝试从已弃用的 NSUrlConnection 切换到 NSUrlSession。 我试图实现的是通过 GET 请求调用 IIS Webservice,然后处理 XML 答案。 我有两个问题:

    如果答案太长,DidReceiveData 中的 NSData 对象不包含所有内容。答案在 1036 个字符后被裁剪。 一切都完成后,当我已经处理接收到的数据(不管它是否被裁剪)时,DidCompleteWithError 被调用。其中的“error”参数为空,所以我不知道为什么调用它以及如何处理它。因此,即使我收到了 DidReceiveData 中的所有数据并且一切正常,也会调用 DidCompleteWithError。

这是我的代码,不胜感激。提前致谢!

public class WebserviceCallerios : IWebServiceCaller
    
        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());
            
    

【问题讨论】:

【参考方案1】:

如果答案太长,DidReceiveData 中的 NSData 对象不包含所有内容。答案在 1036 个字符后被裁剪。

DidReceiveData会被触发多次返回小数据。您必须创建全局变量来存储数据。但你的意思是数据一次超过 1036 个字符?

一切都完成后,当我已经处理接收到的数据(不管它是否被裁剪),DidCompleteWithError 被调用。其中的“error”参数为空,所以我不知道为什么调用它以及如何处理它。因此,即使我收到了 DidReceiveData 中的所有数据并且一切正常,也会调用 DidCompleteWithError。

无论请求成功与否,DidCompleteWithError总是在收到所有数据后调用。报错null表示请求成功。

【讨论】:

太棒了!这行得通。我添加了一个字符串变量“answerCache”,在 DidReceiveData 中我只将接收到的数据附加到该变量。在 DidCompleteWithError 中,我检查错误是否为空。如果是,我调用我完成的方法并告诉它一切正常并将整个 answerCache 变量传递给它。

以上是关于NSURLSession GET 请求:DidCompleteWithError - 错误为空的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发网络篇—发送GET和POST请求(使用NSURLSession)

NSURLSession的GET和POST请求的封装

NSURLSession数据解析的get请求和post请求步骤

网络编程 利用NSURLSession发送GET POST请求

NSURLSession GET 请求:DidCompleteWithError - 错误为空

iOS开发网络篇—发送GET和POST请求(使用NSURLSession)