Bug 24961 - Unable to cast object of type NSUrlSessionTask to NSUrlSessionUploadTask
Summary: Unable to cast object of type NSUrlSessionTask to NSUrlSessionUploadTask
Status: VERIFIED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: XI 8.4.0
Hardware: PC Mac OS
: Normal normal
Target Milestone: 8.6.x (services rel)
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-12-01 13:46 UTC by Anubhav Ranjan
Modified: 2015-02-22 11:28 UTC (History)
10 users (show)

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


Attachments
Sample Project (278.08 KB, application/octet-stream)
2014-12-01 13:46 UTC, Anubhav Ranjan
Details
Sample iOS project along with an ASP.NET Web API 2 project (42 bytes, text/plain)
2014-12-02 16:03 UTC, Danny Cabrera
Details
Xcode console output (11.62 KB, text/plain)
2014-12-02 16:04 UTC, Danny Cabrera
Details


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 Anubhav Ranjan 2014-12-01 13:46:12 UTC
Created attachment 8923 [details]
Sample Project

One of our customer is facing issue in casting object of type NSUrlSessionTask to NSUrlSessionUploadTask.
Description:

We have a project that uses the iOS Background Transfer by calling
NSUrlSessionUploadTask. The problem we are having is when calling
NSUrlSession.GetTasksAsync, it will intermittently throw an unhandled
exception and crash the app. It seems that the binded API is not casting
properly and occasionaly crashes the app. Is this something that can be
fixed with a workaround and does this need to get submitted to Bugzilla? 

Error: Unable to cast object of type 'MonoTouch.Foundation.NSUrlSessionTask'
to type 'MonoTouch.Foundation.NSUrlSessionUploadTask'

Same issue reported in the forums:
http://forums.xamarin.com/discussion/26447/unable-to-cast-object-of-type-nsu
rlsessiontask-to-nsurlsessionuploadtask#latest

Example code we are using:

private async Task<List<NSUrlSessionUploadTask>> GetTasks()
{
    List<NSUrlSessionUploadTask> taskList = new
    List<NSUrlSessionUploadTask> ();
    try {
        if (_session != null) {
            var tasks = await
            _session.GetTasksAsync ();

            foreach (var task in tasks.UploadTasks) {
                taskList.Add(task);
            }
        } 
    } 
    catch (Exception ex) {
        Console.WriteLine ("GetTasks EXCEPTION " + ex.Message + " - " + ex.StackTrace);
    }
    return taskList;
}
Comment 1 Danny Cabrera 2014-12-01 14:25:32 UTC
Is there any temp workaround that can be applied?

DannyC
Comment 4 Danny Cabrera 2014-12-02 16:03:33 UTC
Created attachment 8941 [details]
Sample iOS project along with an ASP.NET Web API 2 project

This zip contains an iOS project along with a ASP.NET Web API 2 project. Simply change the variable "filePath" on SimpleBackgroundUploadWebAPI\SimpleBackgroundUploadWebAPI\Controllers\FileController.cs file to point to a local directory and compile. On the iOS project change the variable "webApiAddress" in the AppDelegate's FinishedLaunching method to point to your Web API address to test.

To get the error I tap the "Start file upload" button on the screen and then I minimize the app. Minimizing the app will make the AppDelegate's DidEnterBackground call ProcessUpload() that will check for pending tasks before starting a new one and that should trigger the error. I will also be attaching the console output with the SIGABRT.

DannyC
Comment 5 Danny Cabrera 2014-12-02 16:04:45 UTC
Created attachment 8942 [details]
Xcode console output
Comment 6 Rolf Bjarne Kvinge [MSFT] 2014-12-03 13:18:28 UTC
I can reproduce, thanks for the test case.

This is a consequence of us trying to make the ObjC API type-safe, and Apple hacking around the little type safety ObjC provides.
Comment 7 Rolf Bjarne Kvinge [MSFT] 2014-12-03 13:36:33 UTC
Fixed.

Unfortunately there is no workaround for the moment.

maccore/master: 2989ee0daa56cf39ba7c4102090cb1e99aebc954
monotouch/master: c63efd01ef2775d1f5e0932bd93639bfe9213bb2
Comment 8 Danny Cabrera 2014-12-03 14:31:49 UTC
Thanks Rolf, is there any update or patch that I can apply?
Comment 9 Rolf Bjarne Kvinge [MSFT] 2014-12-04 04:56:53 UTC
@Danny, there is nothing simple that can be done.

The problem is in the call to GetTasksAsync: the internal callback we provide for iOS has the wrong parameter types, so we end up with InvalidCastExceptions at runtime.

One potential workaround would be to create a native ObjC library that wraps the call to the native [NSURLSession getTasksWithCompletionHandler:] method.

In broad strokes it would be something like this (untested code, this will probably not compile without a few fixes)

(C code)
typedef void (*Callback) (NSArray *data, NSArray *upload, NSArray *download);
void
get_session_tasks (NSURLSession *session, Callback callback)
{
    [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *allDownloadTasks)
    {
        callback (dataTasks, uploadTasks, downloadTasks);
    }];
}

(C# code)

delegate void Callback (IntPtr data, IntPtr upload, IntPtr download);
[DllImport ("__Internal")]
static extern get_session_tasks (IntPtr session, Callback callback);

[MonoPInvokeCallback (typeof (Callback))]
static void TasksCallback (IntPtr data, IntPtr upload, IntPtr download)
{
    var dataArray = Runtime.GetNSObject<NSArray> (data);
    var uploadArray = Runtime.GetNSObject<NSArray> (upload);
    var downloadArray = Runtime.GetNSObject<NSArray> (download);
    // do something with the arrays
}

static Callback callback = TasksCallback;

static void GetTasksWorkaround (NSUrlSession session)
{
    get_session_tasks (session.Handle, callback);
}
Comment 10 Danny Cabrera 2014-12-05 09:45:23 UTC
Thanks Rolf, honestly don't even know where to begin applying the changes above. Any idea when this will roll-out to Stable?

Thanks,
DannyC
Comment 11 Rolf Bjarne Kvinge [MSFT] 2014-12-05 10:11:20 UTC
@Danny, the next release after 8.6 (most likely early/mid February - Alphas/Betas will come out mid/late January).
Comment 12 Danny Cabrera 2014-12-05 10:23:36 UTC
Is there someone from support that can assist in helping me implement the potential workaround in the meantime?
Comment 13 Rolf Bjarne Kvinge [MSFT] 2014-12-05 10:54:13 UTC
@Danny, please email support and ask (you can find the address to e-mail in your Xamarin Store account: https://store.xamarin.com/account/my/subscription)
Comment 14 Danny Cabrera 2014-12-05 10:56:07 UTC
Will do, thanks once again Rolf.
Comment 15 Nuno Henrique 2015-01-26 12:26:04 UTC
Any news on this bug? I checked release 8.6 notes and it doesn't seem to be fixed...can anyone confirm?
Comment 16 Rolf Bjarne Kvinge [MSFT] 2015-01-26 13:12:52 UTC
@Nuno, according to comment #11 this will be included in the next major release after 8.6, however the timeline from that comment is wrong (the next major release is still a few months away), so I'm reopening this bug to see if we can get it into a service release.
Comment 17 Rolf Bjarne Kvinge [MSFT] 2015-01-26 13:13:28 UTC
Candidate for a 8.6 service release.
Comment 18 Danny Cabrera 2015-01-26 15:21:33 UTC
Thanks for the update Rolf
Comment 19 Rolf Bjarne Kvinge [MSFT] 2015-01-29 08:28:21 UTC
Closing again, we're tracking the next service release internally.
Comment 22 Abhishek 2015-01-30 11:06:52 UTC
As per comment 21, I have checked this issue using XVS 5.0.389.0 (917baa9) in master lane and observed that this issue still exist i.e. I am not getting method "GetTasks2Async ();" in NSUrlSession as shown in screencast : 
http://www.screencast.com/t/xi5wrdBkX

As of now I am reopening this issue and please let me know with which build should I check to verify this issue.
Comment 24 Abhishek 2015-01-30 15:02:33 UTC
I have again checked this issue with XI 8.9.0.9437 ,now I am able to run the attach project. And I am able to cast the line no 178,i.e. 

uploadTask = taskList [0];

to 

uploadTask = (NSUrlSessionUploadTask)taskList [0];

I observe that When I click on the "start file upload" Button thread start but after some time it just give message in the application output "The Request Time Out" 

I am not sure what should be the expected behavior.

Please let me know if I have to check some else to verify this issue.
Comment 26 Danny Cabrera 2015-02-10 10:33:29 UTC
Hi @Rolf, don't see [24961] in the 8.6 release notes. Assuming it wasn't included in this release? http://developer.xamarin.com/releases/ios/xamarin.ios_8/xamarin.ios_8.6/
Comment 27 Rolf Bjarne Kvinge [MSFT] 2015-02-10 10:38:48 UTC
@Danny, the fix is not in 8.6.1, but we're trying to make it go into 8.6.2.
Comment 28 Danny Cabrera 2015-02-10 10:41:40 UTC
@Rolf I was happy for a split second. :( The inevitable question, any time frame on 8.6.2?
Comment 29 Rolf Bjarne Kvinge [MSFT] 2015-02-10 10:45:35 UTC
@Danny, current estimate is beginning of March.
Comment 30 Danny Cabrera 2015-02-10 11:50:54 UTC
Thanks for the update
Comment 32 Ram Chandra 2015-02-11 12:09:24 UTC
I have checked this issue with following build :

Mac OS X 10.9.5
Xamarin Studio: 5.7.1 (build 17)
Mono 3.12.0 ((detached/de2f33f)
GTK+ 2.24.23 (Raleigh theme)
Package version: 312000076
Xcode 6.1 (6604)
Build 6A1052d
Xamarin.iOS : 8.9.1.44 (Business Edition)
Hash: 5482a19
Branch: master
Build date: 2015-01-31 13:50:55-0500
=== Build Information ===
Release ID: 507010017
Git revision: 0bc7d3550b6b088ac25b08dcf7bbe73bcc8658b3
Build date: 2015-02-03 19:43:29-05
Xamarin addins: f7b7d34419c9ec24501bfa7c658e80a6305613e0

Observations: 

Case 1:  Sample Application (without any changes) + stable (X.iOS: 8.4.0.47)  = FAIL (Expected Behavior)

Result:
> Unhandled managed exception: Unable to cast object of type 'MonoTouch.Foundation.NSUrlSessionTask' to type 'MonoTouch.Foundation.NSUrlSessionUploadTask'. (System.InvalidCastException)

ApplicationOutput: https://gist.github.com/Rajneesh360Logica/8df7e7a803195b44c8fb


Case 2: Original code + master (X.iOS : 8.9.1.44) = FAIL (Expected Result)

Result:
> Unhandled managed exception:
Unable to cast object of type 'MonoTouch.Foundation.NSUrlSessionTask' to type 'MonoTouch.Foundation.NSUrlSessionUploadTask'.

Application Output: https://gist.github.com/Rajneesh360Logica/384a9c8853d8f865b949


Case 3: Sample Application ( use GetTasks2Async() + (NSUrlSessionUploadTask)taskList [0]; ) + master(X.iOS : 8.9.1.44 )  = PASS  (Fixed)

Result:  
> “PrepareUpload Ex: Unable to cast object of type 'MonoTouch.Foundation.NSUrlSessionTask' to type 'MonoTouch.Foundation.NSUrlSessionUploadTask'.”

Application Output:  https://gist.github.com/Rajneesh360Logica/3cc901c0e82afb423cee

Screencast: http://www.screencast.com/t/PaVBN6H9

This issue has been fixed. Hence I am closing this issue.
Comment 33 Sebastien Pouliot 2015-02-11 15:21:01 UTC
Backported in SR2 in c1dba895f6acf338ed9f6062492c572679ac8358
Comment 37 Danny Cabrera 2015-02-22 11:14:20 UTC
Sebastien,

Was this part of Xamarion.iOS 8.6.1.26 out on Stable? The release notes were updated but reflect this bug as fixed on 8.6.2.

http://developer.xamarin.com/releases/ios/xamarin.ios_8/xamarin.ios_8.6/
Comment 38 Sebastien Pouliot 2015-02-22 11:26:01 UTC
@Danny, the release notes are correct, this is fixed in 8.6.2. Release notes were updated at the same time as 8.6.2 became available in the alpha channel (they are not limited to stable). Unless regressions are found in SR2 the exact same build will be promoted to beta and stable over the next weeks (and release notes won't changes).
Comment 39 Danny Cabrera 2015-02-22 11:28:26 UTC
Thanks