如何从 Xamarin 中的 iOS DropInteraction 读取 pdfdoc

Posted

技术标签:

【中文标题】如何从 Xamarin 中的 iOS DropInteraction 读取 pdfdoc【英文标题】:How to read a pdfdoc from a iOS DropInteraction in Xamarin 【发布时间】:2021-12-06 07:25:06 【问题描述】:

就像post 一样,我想通过应用间拖放交互接收 pdf 文档。当我将我的 pdf 文件拖到我的组件上时,IUIDropSession 包含一个标识符 com.adobe.pdfPerformDrop 也被调用,但 LoadPdfs 不是。应用程序崩溃。为什么?

[Export("dropInteraction:canHandleSession:")]
public bool CanHandleSession(UIDropInteraction interaction, IUIDropSession session)

  return session.CanLoadObjects(typeof(PDFDocument)); // This returns true


[Export("dropInteraction:sessionDidUpdate:")]
public UIDropProposal SessionDidUpdate(UIDropInteraction interaction, IUIDropSession session)

  return new UIDropProposal(UIDropOperation.Copy);


[Export("dropInteraction:performDrop:")]
public void PerformDrop(UIDropInteraction interaction, IUIDropSession session)

  session.LoadObjects<PDFDocument>(LoadPdfs); // CRASH WHEN EXECUTING THIS LINE


private void LoadPdfs(PDFDocument[] items)

  // This is not called

PdfDocument 是这个类的位置

class PDFDocument : NSObject, INSItemProviderReading

  string identifier;
  NSData data;

  public PDFDocument(NSData pdfData, string typeIdentifier)
  
     data = pdfData;
     identifier = typeIdentifier;
  

  [Export("objectWithItemProviderData:typeIdentifier:error:")]
  static public INSItemProviderReading GetObject(NSData data, string indentifier, NSError error)
  
     return new PDFDocument(data, indentifier);
  

  [Export("readableTypeIdentifiersForItemProvider")]
  static public string[] ReadableTypeIdentifiers  => new string[]
  
     "com.adobe.pdf"
  ;

  [Export("withItemProviderData")]
  public static object WithItemProviderData(NSData data, string typeIdentifier)
    => new PDFDocument(data, typeIdentifier);

崩溃:

=================================================================
    Native Crash Reporting
=================================================================
Got a segv while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

=================================================================
    Native stacktrace:
=================================================================
    0x105c485ac - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.ios.app/Frameworks/Mono.framework/Mono : mono_dump_native_crash_info
    0x105c3e724 - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/Frameworks/Mono.framework/Mono : mono_handle_native_crash
    0x105c4ca2c - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/Frameworks/Mono.framework/Mono : mono_sigsegv_signal_handler_debug
    0x1e0b1fd50 - /usr/lib/system/libsystem_platform.dylib : <redacted>
    0x104e29a34 - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/TestFilePicker.iOS : xamarin_get_block_descriptor
    0x104e2976c - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/TestFilePicker.iOS : xamarin_get_block_descriptor
    0x104e296b4 - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/TestFilePicker.iOS : xamarin_get_block_descriptor
    0x100d41aac - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/TestFilePicker.iOS : 
    0x100d418c8 - /private/var/containers/Bundle/Application/6363E6AA-015A-4276-8203-4C138D1F9A22/TestFilePicker.iOS.app/TestFilePicker.iOS : 
    0x1898b7db4 - /System/Library/Frameworks/Foundation.framework/Foundation : <redacted>
    0x189927030 - /System/Library/Frameworks/Foundation.framework/Foundation : <redacted>
    0x187d4e2ec - /usr/lib/system/libdispatch.dylib : <redacted>
    0x187d4f2f0 - /usr/lib/system/libdispatch.dylib : <redacted>
    0x187cf554c - /usr/lib/system/libdispatch.dylib : <redacted>
    0x187cf5ff0 - /usr/lib/system/libdispatch.dylib : <redacted>
    0x187cffae4 - /usr/lib/system/libdispatch.dylib : <redacted>
    0x1e0b2af38 - /usr/lib/system/libsystem_pthread.dylib : _pthread_wqthread
    0x1e0b2aaa4 - /usr/lib/system/libsystem_pthread.dylib : start_wqthread

=================================================================

【问题讨论】:

这看起来不像 LoadObjects - docs.microsoft.com/es-es/dotnet/api/… 的正确方法签名 是的,它是一种扩展方法。 @Jason 你知道如何在你引用的文档中指定 LoadObjects 的第一个参数吗? 【参考方案1】:

尝试设置原始方法签名而不是扩展方法。

session.LoadObjects(new Class(typeof(PDFDocument)), (INSItemProviderReading[] items)=>

     PDFDocument[] docs = items as PDFDocument[];
);

参考

https://developer.apple.com/documentation/uikit/drag_and_drop/making_a_view_into_a_drop_destination?language=objc.


更新

尝试简单地使用下面的代码来看看它是否有效。

[Export("dropInteraction:performDrop:")]
public void PerformDrop(UIDropInteraction interaction, IUIDropSession session)

    var label = interaction == oddDropInteraction ? OddNumbersLabel : EvenNumbersLabel;
    session.LoadObjects(new Class(typeof(NSString)),strings =>
    
        ///
    );

参考

https://devblogs.microsoft.com/xamarin/drag-and-drop-apis-for-xamarin-apps/

【讨论】:

啊,这解决了如何从Type 转换为ObjCRuntime.Class。但是方法LoadPdfs 仍然没有被调用。一定与不知道 INSItemProviderWriting 是什么对象有关。 RegisteredTypeIdentifiers 是:com.apple.DocumentManager.FPItem.Filecom.adobe.pdf 尝试使用字符串列表作为method signature查看是否到达完成,参考devblogs.microsoft.com/xamarin/… 您发布的@ColeX 链接中的示例无法编译,但将new Class(typeof(NSString)) 指定为第一个参数在调用完成操作的意义上是有效的。 session.LoadObjects(new Class(typeof(NSString)), x =&gt; Debug.WriteLine(x); ); x 是 INSItemProviderReading 类型。 好的,我已经修改了我的代码。

以上是关于如何从 Xamarin 中的 iOS DropInteraction 读取 pdfdoc的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin / iOS - 如何从硬件键盘禁用选项卡键码

如何从 Xamarin Forms 项目调用 Android 和 iOS 项目中可用的方法?

iOS Braintree Dropin ui,抛出未声明的标识符“BTAppSwitch”

如何在 Xamarin Forms iOS 中的特定页面上导航?

如何从 Xamarin iOS 中选择和打开可用的导航应用程序?

如何在 Xamarin(iOS) 中将按钮从右向左移动