You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin iOS中通过DropInteraction跨应用拖放接收PDF文档时应用崩溃的原因排查

问题诊断与修复方案

看起来你遇到的是Xamarin.iOS中跨应用拖放PDF时,因INSItemProviderReading协议实现不规范导致的崩溃问题,我来帮你拆解问题并给出修复方案:

核心问题根源

崩溃的本质是**PDFDocument类对INSItemProviderReading协议的实现不符合Apple官方规范**,导致Xamarin无法正确完成托管代码到原生Objective-C的绑定转换,最终触发内存访问错误(segv)。具体问题点如下:

  • objectWithItemProviderData:typeIdentifier:error:方法的签名错误:参数名写错(indentifier少了一个't'),且返回值类型、错误参数处理不符合协议要求
  • 多余的WithItemProviderData导出方法干扰了Xamarin的绑定逻辑
  • 不规范的协议实现导致LoadObjects<T>的block回调无法正常生成,进而引发崩溃

修复后的完整代码

修正PDFDocument类实现

严格遵循INSItemProviderReading协议的要求来实现:

class PDFDocument : NSObject, INSItemProviderReading
{
    public NSData Data { get; }
    public string TypeIdentifier { get; }

    public PDFDocument(NSData pdfData, string typeIdentifier)
    {
        Data = pdfData;
        TypeIdentifier = typeIdentifier;
    }

    // 严格匹配协议的方法签名:参数名、返回值、错误处理都要符合要求
    [Export("objectWithItemProviderData:typeIdentifier:error:")]
    static public PDFDocument GetObject(NSData data, string typeIdentifier, out NSError error)
    {
        error = null;
        try
        {
            return new PDFDocument(data, typeIdentifier);
        }
        catch (Exception ex)
        {
            // 可选:自定义错误信息
            error = new NSError(new NSString("com.your.app.pdf.error"), 1, 
                new NSDictionary { { NSError.LocalizedDescriptionKey, ex.Message } });
            return null;
        }
    }

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

保持拖放交互逻辑(可选添加异常捕获)

[Export("dropInteraction:canHandleSession:")]
public bool CanHandleSession(UIDropInteraction interaction, IUIDropSession session)
{
    return session.CanLoadObjects(typeof(PDFDocument));
}

[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)
{
    try
    {
        session.LoadObjects<PDFDocument>(LoadPdfs);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"拖放执行错误: {ex.Message}");
        // 可选:添加UI提示告知用户拖放失败
    }
}

private void LoadPdfs(PDFDocument[] items)
{
    if (items?.Length == 0) return;
    
    // 处理加载完成的PDF文档
    foreach (var pdf in items)
    {
        Console.WriteLine($"成功加载PDF: 类型标识={pdf.TypeIdentifier}, 数据大小={pdf.Data.Length}字节");
        // 这里可以添加你的业务逻辑,比如显示PDF内容等
    }
}

额外调试建议

如果修复后仍有问题,可以尝试以下排查手段:

  1. 先测试小体积PDF文件,排除大文件内存过载问题
  2. 尝试绕开LoadObjects<T>的回调,手动处理NSItemProvider(适合调试排查):
[Export("dropInteraction:performDrop:")]
public async void PerformDrop(UIDropInteraction interaction, IUIDropSession session)
{
    foreach (var item in session.Items)
    {
        var provider = item.ItemProvider;
        if (provider.HasItemConformingToTypeIdentifier("com.adobe.pdf"))
        {
            try
            {
                var pdfData = await provider.LoadDataAsync("com.adobe.pdf");
                var pdfDoc = new PDFDocument(pdfData, "com.adobe.pdf");
                // 处理PDF文档
            }
            catch (Exception ex)
            {
                Console.WriteLine($"手动加载PDF错误: {ex.Message}");
            }
        }
    }
}
  1. 确保你的Xamarin.iOS项目使用的是稳定版本,避免版本兼容性问题

内容的提问来源于stack exchange,提问作者Ivo Krugers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:12:49