microsoft / WinObjC

Objective-C for Windows
MIT License
6.24k stars 808 forks source link

Exception when calling [WSPFileSavePicker pickSaveFileAsyncWithSuccess:failure:] #1291

Open rupertdaniel opened 7 years ago

rupertdaniel commented 7 years ago

I'm having some trouble using WSPFileSavePicker, it seems to throw an exception whenever I call [WSPFileSavePicker pickSaveFileAsyncWithSuccess:failure:]

Here is how I'm setting it up:

self.fileSavePicker = [WSPFileSavePicker make];
self.fileSavePicker.suggestedStartLocation = WSPPickerLocationIdMusicLibrary;
self.fileSavePicker.defaultFileExtension = @".txt";
self.fileSavePicker.fileTypeChoices[@"Plain Text"] = @[@".txt"];
self.fileSavePicker.suggestedFileName = @"Test File";
[self.fileSavePicker pickSaveFileAsyncWithSuccess:^(WSStorageFile *file) {
} failure:nil];

Here is the stack trace I'm getting...

    OBJCUWP.DLL!RTMapViewKeyEnumerator<HSTRING__ *,HSTRING__ *,NSString,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *>::initWith(IInspectable * mapview) Line 2478  Objective-C++
    [External Code] 
    OBJCUWP.DLL!MutableDictionaryAdapterObj<ABI::Windows::Foundation::Collections::IMap<HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *>,DictionaryKeyEnumeratorAdapterObj<RTMapViewKeyEnumerator<HSTRING__ *,HSTRING__ *,NSString,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *> >,RTMapObj<HSTRING__ *,HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *,NSString,RTProxiedNSMutableArray,ABI::Windows::Foundation::Collections::IMap<HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *>,&dummyObjCCreator,&RTProxiedNSMutableArray_NSString_create> >::MutableDictionaryAdapterObj<ABI::Windows::Foundation::Collections::IMap<HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *>,DictionaryKeyEnumeratorAdapterObj<RTMapViewKeyEnumerator<HSTRING__ *,HSTRING__ *,NSString,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *> >,RTMapObj<HSTRING__ *,HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *,NSString,RTProxiedNSMutableArray,ABI::Windows::Foundation::Collections::IMap<HSTRING__ *,ABI::Windows::Foundation::Collections::IVector<HSTRING__ *> *>,&dummyObjCCreator,&RTProxiedNSMutableArray_NSString_create> >(IInspectable * container) Line 402   Objective-C++
    [External Code] 
    OBJCUWP.DLL!RTProxiedNSMutableDictionary_NSString_RTProxiedNSMutableArray_NSString_create(IInspectable * val) Line 577  Objective-C++
    OBJCUWP.DLL!-[WSPFileSavePicker fileTypeChoices](WSPFileSavePicker * self, objc_selector * _cmd) Line 356   Objective-C++
>   KVOBug.exe!-[ViewController update:](ViewController * const self, objc_selector * _cmd, id * sender) Line 172   Objective-C
    FOUNDATION.DLL!-[NSObject performSelector:withObject:withObject:](NSObject * self, objc_selector * _cmd, objc_selector * selector, id * obj1, id * obj2) Line 274   Objective-C++
    UIKIT.DLL!-[UIControl sendAction:to:forEvent:](UIControl * self, objc_selector * _cmd, objc_selector * sel, objc_object * target, UIEvent * event) Line 102 Objective-C++
    UIKIT.DLL!-[UIControl sendActionsForControlEvents:](UIControl * self, objc_selector * _cmd, unsigned int mask) Line 139 Objective-C++
    UIKIT.DLL!-[UIControl touchesEnded:withEvent:](UIControl * self, objc_selector * _cmd, id * touchSet, UIEvent * event) Line 432 Objective-C++
    UIKIT.DLL!-[UIButton touchesEnded:withEvent:](UIButton * self, objc_selector * _cmd, id * touchSet, UIEvent * event) Line 535   Objective-C++
    FOUNDATION.DLL!-[NSObject performSelector:withObject:withObject:](NSObject * self, objc_selector * _cmd, objc_selector * selector, id * obj1, id * obj2) Line 274   Objective-C++
    UIKIT.DLL!-[UIView _processPointerEvent:forTouchPhase:](UIView * self, objc_selector * _cmd, id * pointerEventArgs, UITouchPhase touchPhase) Line 525   Objective-C++
    UIKIT.DLL!__19-[UIView _initPriv]_block_invoke.3260(void * .block_descriptor, id * sender, id * e) Line 685 Objective-C++
    OBJCUWP.DLL!WUXIPointerEventHandler_shim::Invoke(IInspectable * arg0, Input::IPointerRoutedEventArgs * arg1) Line 344   Objective-C++
    [External Code]

I've tried not supplying the fileTypeChoices value, but that also throws an exception...

    OBJCUWP.DLL!wil::details::ReportFailure_Hr(const std::_Wrap_alloc<std::allocator<std::_Func_impl<<unnamed-tag>,std::allocator<int>,void,Syndication::RetrievalProgress> > > & callerReturnAddress) Line 3152    Objective-C++
    OBJCUWP.DLL!wil::details::in1diag5::_Objc_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4730  Objective-C++
    OBJCUWP.DLL!-[WSPFileSavePicker pickSaveFileAsyncWithSuccess:failure:](WSPFileSavePicker * self, objc_selector * _cmd, ..., ...) Line 398   Objective-C++
>   KVOBug.exe!-[ViewController update:](ViewController * const self, objc_selector * _cmd, id * sender) Line 174   Objective-C
    FOUNDATION.DLL!-[NSObject performSelector:withObject:withObject:](NSObject * self, objc_selector * _cmd, objc_selector * selector, id * obj1, id * obj2) Line 274   Objective-C++
    UIKIT.DLL!-[UIControl sendAction:to:forEvent:](UIControl * self, objc_selector * _cmd, objc_selector * sel, objc_object * target, UIEvent * event) Line 102 Objective-C++
    UIKIT.DLL!-[UIControl sendActionsForControlEvents:](UIControl * self, objc_selector * _cmd, unsigned int mask) Line 139 Objective-C++
    UIKIT.DLL!-[UIControl touchesEnded:withEvent:](UIControl * self, objc_selector * _cmd, id * touchSet, UIEvent * event) Line 432 Objective-C++
    UIKIT.DLL!-[UIButton touchesEnded:withEvent:](UIButton * self, objc_selector * _cmd, id * touchSet, UIEvent * event) Line 535   Objective-C++
    FOUNDATION.DLL!-[NSObject performSelector:withObject:withObject:](NSObject * self, objc_selector * _cmd, objc_selector * selector, id * obj1, id * obj2) Line 274   Objective-C++
    UIKIT.DLL!-[UIView _processPointerEvent:forTouchPhase:](UIView * self, objc_selector * _cmd, id * pointerEventArgs, UITouchPhase touchPhase) Line 525   Objective-C++
    UIKIT.DLL!__19-[UIView _initPriv]_block_invoke.3260(void * .block_descriptor, id * sender, id * e) Line 685 Objective-C++
    OBJCUWP.DLL!WUXIPointerEventHandler_shim::Invoke(IInspectable * arg0, Input::IPointerRoutedEventArgs * arg1) Line 344   Objective-C++
    [External Code] 

Am I doing some thing wrong in the setup of the WSPFileSavePicker instance or is there something broken internally?

rajsesh commented 7 years ago

@bbowman this looks different from the rt_dynamic_cast issue we saw elsewhere?

bbowman commented 7 years ago

Yeah looks different. fileTypeChoices appears to be a required parameter so the second callstack makes sense. The first one though I'll need to dig in to see if there is something wrong with the projections internals.

bbowman commented 7 years ago

Reassigning to @mukhole ... a first glance suggests a projections bug with how the iterator is being produced.

mukhole commented 7 years ago

The runtime class which implements "fileTypeChoices" does not implement IIterable interface and so this type cannot be enumerated. The exception is caused when we try to create an iterator for this type. This has been fixed now.

rajsesh commented 7 years ago

This was fixed with #1310

DHowett-MSFT commented 6 years ago

Reopening as per #2892.

edvv commented 6 years ago

@DHowett-MSFT Thank you for opening this again. It turns out that this works:

self.fileSavePicker.fileTypeChoices[@"Plain Text"] = @[@".txt"];

but attempting to access fileTypeChoices itself does not work, so for example this bombs:

NSLog(@"self.fileSavePicker.fileTypeChoices: %@", self.fileSavePicker.fileTypeChoices); // bombs

so, this does not work:

id fileChoices = self.fileSavePicker.fileTypeChoices; // bombs here

[fileChoices setValue:@[@".txt"] forKey:@"Plain Text"];

In any event, using the working pattern above is enough of a workaround.

Sincerely,

Ed