NSURLSession GET 请求:DidCompleteWithError - 错误为空
NSURLSession GET Request: DidCompleteWithError - error is null
目前我正在尝试从已弃用的 NSUrlConnection 切换到 NSUrlSession。
我试图实现的是通过 GET 请求调用 IIS Web 服务,然后处理 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());
}
}
}
If the answer is too long the NSData object in DidReceiveData does not contain everything. The answer is cropped after 1036 characters.
DidReceiveData
会多次触发,return小数据。您必须创建全局变量来存储数据。但是你的意思是数据一次超过 1036 个字符?
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.
无论请求成功与否,DidCompleteWithError
总是在收到所有数据后调用。错误null
表示您请求成功。
目前我正在尝试从已弃用的 NSUrlConnection 切换到 NSUrlSession。 我试图实现的是通过 GET 请求调用 IIS Web 服务,然后处理 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());
}
}
}
If the answer is too long the NSData object in DidReceiveData does not contain everything. The answer is cropped after 1036 characters.
DidReceiveData
会多次触发,return小数据。您必须创建全局变量来存储数据。但是你的意思是数据一次超过 1036 个字符?
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.
无论请求成功与否,DidCompleteWithError
总是在收到所有数据后调用。错误null
表示您请求成功。