Bug 37175 - NSUrlSession.CreateDownloadTask throws InvalidCastException on real device iPhone6, iOS9.2(13C75)
Summary: NSUrlSession.CreateDownloadTask throws InvalidCastException on real device iP...
Status: VERIFIED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll (show other bugs)
Version: XI 9.4 (iOS 9.2)
Hardware: Macintosh Other
: --- normal
Target Milestone: (C9)
Assignee: Alex Soto [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2015-12-20 19:10 UTC by luc+xamarin
Modified: 2016-11-10 14:25 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED FIXED

Description luc+xamarin 2015-12-20 19:10:21 UTC
Hello,

I am experiencing strange InvalidCastException in my application. 
This bug happens only on real device and was not reproduced in the emulator.
My device is iphone6 ios9.2 (13C75).

Would you please have a look, It feels like this bug is yours.
Let me know.
Regards
Luc

--

Please consider the following code :
var downloadmanager = new MyDownloadManager();

var downloadqueue = new NSOperationQueue {
	MaxConcurrentOperationCount = 1
};

string sessionidentifier = "myapp.download.images";
NSUrlSession nsurlsession = null;
using (var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (sessionidentifier)) {
	nsurlsession = NSUrlSession.FromConfiguration (configuration, downloadmanager, downloadqueue);
}

foreach (var image in bigimages) { // about 2000 images around 100k each

   using (var url = NSUrl.FromString (image.Url))
   using (var request = NSUrlRequest.FromUrl (url)) {

      var task = NSUrlSessionDownloadTask (request); // throws InvalidCastException, after a few creation.
      ...
    }
}


----

System.InvalidCastException: Unable to cast object of type 'Foundation.NSUrlSessionTask' to type 'Foundation.NSUrlSessionDownloadTask'
  at ObjCRuntime.Runtime.GetNSObject[T] (IntPtr ptr) <0x10015a650 + 0x00258> in <filename unknown>:0 
  at Foundation.NSUrlSession.CreateDownloadTask (Foundation.NSUrlRequest request) [0x0001c] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/build/ios/native/Foundation/NSUrlSession.g.cs:240 
  at MyApp.MyDownloadManager.NSUrlSessionDownloadTask (Foundation.NSUrlRequest request) [0x00013] in ../MyApp/Iphone/MyApp/Sync/MyDownloadManager.cs:136 


---

=== Xamarin Studio ===

Version 5.10.1 (build 6)
Installation UUID: 32c1199d-cf1f-4098-ad19-5b592b046e78
Runtime:
	Mono 4.2.1 (explicit/6dd2d0d)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 402010102

=== Xamarin.Profiler ===

Version: 0.24.0.0
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 7.2 (9548)
Build 7C68

=== Xamarin.iOS ===

Version: 9.4.0.0 (Business Edition)
Hash: 7322991
Branch: master
Build date: 2015-12-08 16:20:29-0500

=== Xamarin.Android ===

Version: 6.0.0.34 (Starter Edition)
Android SDK: /Users/q/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		2.3   (API level 10)
		4.0.3 (API level 15)
		4.4   (API level 19)
		5.1   (API level 22)

SDK Tools Version: 24.1.2
SDK Platform Tools Version: 22
SDK Build Tools Version: 21.1.2

Java SDK: /usr
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)

=== Xamarin Android Player ===

Not Installed

=== Xamarin.Mac ===

Not Installed

=== Build Information ===

Release ID: 510010006
Git revision: 0b60eecdb531933734519c13257d16a780274aab
Build date: 2015-12-04 20:28:20-05
Xamarin addins: 9876fd7c9837977178411ec7375b4352c0a0d6af
Build lane: monodevelop-lion-cycle6-baseline

=== Operating System ===

Mac OS X 10.11.2
Darwin n00b132 15.2.0 Darwin Kernel Version 15.2.0
    Fri Nov 13 19:56:56 PST 2015
    root:xnu-3248.20.55~2/RELEASE_X86_64 x86_64
Comment 1 luc+xamarin 2015-12-20 19:15:54 UTC
var task = NSUrlSessionDownloadTask (request); 
should be 
nsurlsession.CreateDownloadTask (request);



I use the following workaround until this bug gets fixed :

NSUrlSessionDownloadTask NSUrlSessionDownloadTask(NSUrlRequest request) {

   int bugcounter = 0;
   NSUrlSessionDownloadTask task = null;
   while (task == null) {
      try {
         Thread.Sleep (100);
         task = _session.CreateDownloadTask (request);
      } catch (InvalidCastException ) {
         // Xamarin.Ios bug ?
         bugcounter++;
         if (bugcounter > 5) {
	   throw ;
      }
    }
   }

   return task;
}
Comment 2 Rolf Bjarne Kvinge [MSFT] 2015-12-21 10:25:49 UTC
This is probably related to bug #24961, where the iOS API is returning objects of the wrong type.

You're calling this method on NSURLSession [1]:

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request

which clearly states that it will return an NSURLSessionDownloadTask instance, but yet it returns a NSURLSessionTask, which is a superclass (and thus not convertible to NSURLSessionDownloadTask).

This works fine in Objective-C, where there are no type checks, but we try to be type-safe, and that end up causing trouble in the binding when the API is lying to us.

[1] https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/occ/instm/NSURLSession/downloadTaskWithRequest:
Comment 3 luc+xamarin 2015-12-21 12:39:25 UTC
Dear Rolf, I do agree with your analysis.

Would you please fix this bug for the other NSURLSession classes as well :

NSURLSessionUploadTask   - Already fixed (as per bug #24961)
NSURLSessionDownloadTask - This bug report
NSURLSessionDataTask     - Does this one needs a fix also ?
NSURLSessionTask         - Shouldn't be affected.

Best regards,
Luc
Comment 4 Rolf Bjarne Kvinge [MSFT] 2016-01-13 17:55:39 UTC
@Luc, I have a potential fix, but I haven't been able to reproduce the InvalidCastException, so I don't know if the fix is complete or not (here's my test project: https://github.com/rolfbjarne/bug37175) - could you share your project with us so that I can verify my fix?
Comment 5 Alex Soto [MSFT] 2016-09-26 16:34:10 UTC
Fixed in xamarin-macios/master @ 912ab01d1eb68a668d058bcb67e7e3f088a1dd95
Comment 7 Naqeeb 2016-11-10 14:25:09 UTC
I have checked this issue with C9 build on physical device iOS 9.3.5 and observed that it is working fine. Here is the screencast for the same: http://www.screencast.com/t/KuIH78kd3

Environment info: https://gist.github.com/NaqeebAnsari/eb92b1cda2ad52a1cbce78e1cc30e6c5

Hence closing this issue.