[Foundation] NSUrlSession's Create*Task methods may return a base class of the type the headers claim. Fixes #37175.

https://bugzilla.xamarin.com/show_bug.cgi?id=37175

NSUrlSession's Create*Task methods may return an object of the wrong
type (NSUrlSessionTask instead of NSUrl[Data|Download|Upload]SessionTask),
so we need to bypass our type check when creating the managed object,
otherwise we end up throwing InvalidCastExceptions randomly. We will
return the type that is declared on the headers so if the native side
returns a cat and headers says it barks we'll we make it bark :).
This commit is contained in:
Alex Soto 2016-09-23 21:37:33 -05:00
Родитель 7845caa577
Коммит 72f6d0a232
2 изменённых файлов: 128 добавлений и 0 удалений

Просмотреть файл

@ -5855,54 +5855,69 @@ namespace XamCore.Foundation
#endif
[Export ("dataTaskWithRequest:")]
[ForcedType]
NSUrlSessionDataTask CreateDataTask (NSUrlRequest request);
[Export ("dataTaskWithURL:")]
[ForcedType]
NSUrlSessionDataTask CreateDataTask (NSUrl url);
[Export ("uploadTaskWithRequest:fromFile:")]
[ForcedType]
NSUrlSessionUploadTask CreateUploadTask (NSUrlRequest request, NSUrl fileURL);
[Export ("uploadTaskWithRequest:fromData:")]
[ForcedType]
NSUrlSessionUploadTask CreateUploadTask (NSUrlRequest request, NSData bodyData);
[Export ("uploadTaskWithStreamedRequest:")]
[ForcedType]
NSUrlSessionUploadTask CreateUploadTask (NSUrlRequest request);
[Export ("downloadTaskWithRequest:")]
[ForcedType]
NSUrlSessionDownloadTask CreateDownloadTask (NSUrlRequest request);
[Export ("downloadTaskWithURL:")]
[ForcedType]
NSUrlSessionDownloadTask CreateDownloadTask (NSUrl url);
[Export ("downloadTaskWithResumeData:")]
[ForcedType]
NSUrlSessionDownloadTask CreateDownloadTask (NSData resumeData);
[Export ("dataTaskWithRequest:completionHandler:")]
[ForcedType]
[Async (ResultTypeName="NSUrlSessionDataTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionDataTask CreateDataTask (NSUrlRequest request, [NullAllowed] NSUrlSessionResponse completionHandler);
[Export ("dataTaskWithURL:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDataTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionDataTask CreateDataTask (NSUrl url, [NullAllowed] NSUrlSessionResponse completionHandler);
[Export ("uploadTaskWithRequest:fromFile:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDataTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionUploadTask CreateUploadTask (NSUrlRequest request, NSUrl fileURL, NSUrlSessionResponse completionHandler);
[Export ("uploadTaskWithRequest:fromData:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDataTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionUploadTask CreateUploadTask (NSUrlRequest request, NSData bodyData, NSUrlSessionResponse completionHandler);
[Export ("downloadTaskWithRequest:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDownloadTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionDownloadTask CreateDownloadTask (NSUrlRequest request, [NullAllowed] NSUrlDownloadSessionResponse completionHandler);
[Export ("downloadTaskWithURL:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDownloadTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionDownloadTask CreateDownloadTask (NSUrl url, [NullAllowed] NSUrlDownloadSessionResponse completionHandler);
[Export ("downloadTaskWithResumeData:completionHandler:")]
[ForcedType]
[Async(ResultTypeName="NSUrlSessionDownloadTaskRequest", PostNonResultSnippet = "result.Resume ();")]
NSUrlSessionDownloadTask CreateDownloadTaskFromResumeData (NSData resumeData, [NullAllowed] NSUrlDownloadSessionResponse completionHandler);

Просмотреть файл

@ -50,5 +50,118 @@ namespace MonoTouchFixtures.Foundation {
Assert.That (task.TaskIdentifier, Is.GreaterThanOrEqualTo (0), "taskIdentifier");
}
}
[Test]
public void NSUrlSessionDownloadTaskTest ()
{
TestRuntime.AssertXcodeVersion (6, 0);
using (var ur = new NSUrlRequest ()) {
NSUrlSessionDownloadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDownloadTask (ur), "Should not throw InvalidCastException");
Assert.IsNotNull (task, "task should not be null");
Assert.IsInstanceOfType (typeof (NSUrlSessionDownloadTask), task, "task should be an instance of NSUrlSessionDownloadTask");
}
using (var ur = new NSUrlRequest ()) {
NSUrlSessionDownloadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDownloadTask (ur, null), "Should not throw InvalidCastException 2");
Assert.IsNotNull (task, "task should not be null 2");
Assert.IsInstanceOfType (typeof (NSUrlSessionDownloadTask), task, "task should be an instance of NSUrlSessionDownloadTask 2");
}
using (var ur = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionDownloadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDownloadTask (ur), "Should not throw InvalidCastException 3");
Assert.IsNotNull (task, "task should not be null 3");
Assert.IsInstanceOfType (typeof (NSUrlSessionDownloadTask), task, "task should be an instance of NSUrlSessionDownloadTask 3");
}
using (var ur = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionDownloadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDownloadTask (ur, null), "Should not throw InvalidCastException 4");
Assert.IsNotNull (task, "task should not be null 4");
Assert.IsInstanceOfType (typeof (NSUrlSessionDownloadTask), task, "task should be an instance of NSUrlSessionDownloadTask 4");
}
}
[Test]
public void NSUrlSessionDataTaskTest ()
{
TestRuntime.AssertXcodeVersion (6, 0);
using (var ur = new NSUrlRequest ()) {
NSUrlSessionDataTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDataTask (ur), "Should not throw InvalidCastException");
Assert.IsNotNull (task, "task should not be null");
Assert.IsInstanceOfType (typeof (NSUrlSessionDataTask), task, "task should be an instance of NSUrlSessionDataTask");
}
using (var ur = new NSUrlRequest ()) {
NSUrlSessionDataTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDataTask (ur, null), "Should not throw InvalidCastException 2");
Assert.IsNotNull (task, "task should not be null 2");
Assert.IsInstanceOfType (typeof (NSUrlSessionDataTask), task, "task should be an instance of NSUrlSessionDataTask 2");
}
using (var ur = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionDataTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDataTask (ur), "Should not throw InvalidCastException 3");
Assert.IsNotNull (task, "task should not be null 3");
Assert.IsInstanceOfType (typeof (NSUrlSessionDataTask), task, "task should be an instance of NSUrlSessionDataTask 3");
}
using (var ur = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionDataTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateDataTask (ur, null), "Should not throw InvalidCastException 4");
Assert.IsNotNull (task, "task should not be null 4");
Assert.IsInstanceOfType (typeof (NSUrlSessionDataTask), task, "task should be an instance of NSUrlSessionDataTask 4");
}
}
[Test]
public void NSUrlSessionUploadTaskTest ()
{
TestRuntime.AssertXcodeVersion (6, 0);
using (var ur = new NSUrlRequest ()) {
NSUrlSessionUploadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateUploadTask (ur), "Should not throw InvalidCastException");
Assert.IsNotNull (task, "task should not be null");
Assert.IsInstanceOfType (typeof (NSUrlSessionUploadTask), task, "task should be an instance of NSUrlSessionUploadTask");
}
using (var data = NSData.FromString ("Hola"))
using (var ur = new NSUrlRequest ()) {
NSUrlSessionUploadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateUploadTask (ur, data), "Should not throw InvalidCastException 2");
Assert.IsNotNull (task, "task should not be null 2");
Assert.IsInstanceOfType (typeof (NSUrlSessionUploadTask), task, "task should be an instance of NSUrlSessionUploadTask 2");
}
using (var ur = new NSUrlRequest ())
using (var url = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionUploadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateUploadTask (ur, url), "Should not throw InvalidCastException 3");
Assert.IsNotNull (task, "task should not be null 3");
Assert.IsInstanceOfType (typeof (NSUrlSessionUploadTask), task, "task should be an instance of NSUrlSessionUploadTask 3");
}
using (var ur = new NSUrlRequest ())
using (var url = new NSUrl ("https://www.microsoft.com")) {
NSUrlSessionUploadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateUploadTask (ur, url, (data, response, error) => { }), "Should not throw InvalidCastException 4");
Assert.IsNotNull (task, "task should not be null 4");
Assert.IsInstanceOfType (typeof (NSUrlSessionUploadTask), task, "task should be an instance of NSUrlSessionUploadTask 4");
}
using (var ur = new NSUrlRequest ())
using (var data = NSData.FromString ("Hola")) {
NSUrlSessionUploadTask task = null;
Assert.DoesNotThrow (() => task = NSUrlSession.SharedSession.CreateUploadTask (ur, data, (d, response, error) => { }), "Should not throw InvalidCastException 5");
Assert.IsNotNull (task, "task should not be null 5");
Assert.IsInstanceOfType (typeof (NSUrlSessionUploadTask), task, "task should be an instance of NSUrlSessionUploadTask 5");
}
}
}
}