Flutter iOS 文件共享 - 无法打开共享文件

Flutter iOS File Sharing - Cannot Open Shared File

我正在为 iOS 构建一个 flutter 应用程序。我创建了一个文件类型,我的应用程序和另一个应用程序可以来回共享。我正在使用 flutter receive_sharing_intent 库来实现这一点。为了测试它,我对我的 info.plist 文件进行了所有必要的更改以处理我的自定义文件类型,我将该文件类型的示例文件放在我设备的下载文件夹中(在 ipad 上测试) ,然后我从那里单击它以在我的应用程序中将其打开。 OS 知道我的应用程序可以处理它。所以,我的应用程序打开,它接收到共享文件的路径,但我的应用程序无法打开该文件。这是我的 main.dart 中处理文件接收的代码:

StreamSubscription _intentDataStreamSubscription =
    ReceiveSharingIntent.getTextStream().listen((String value) {
      setState(() {
        try{

        //This was added to test and make sure the directory actually exists. 
        //The value for the directory path was added after I ran it once to capture where the shared file was coming from.
        Directory dir = Directory("/private/var/mobile/Containers/Shared/AppGroup/7DD4B316-3D73-4339-9B11-7516DE52F6FC/File Provider Storage/Downloads/");
        bool dirExists = dir.existsSync();
        
        var files = dir.listSync();
        File drawingFile = File.fromUri(Uri.parse(value));
        bool fileExists = drawingFile.existsSync();

        var contents = drawingFile.readAsStringSync();
        DrawingCanvas canvas = DrawingCanvas.fromFileContents(contents);
        DrawingCanvasBloc canvasBloc = DrawingCanvasBloc(canvas);

        Navigator.of(context).push(MaterialPageRoute(builder: (context) => CanvasScreen(canvasBloc)));
        }
        catch(e){
          log(e.toString());
        }
      });
    }, onError: (err) {
      print("getLinkStream error: $err");
    });

场景:我运行申请。我进入 ipad 上文件中的下载文件夹。我 select 我的 example.fbg 文件位于那里(我的自定义文件类型)。我的应用打开了。

在上面的代码中,当我尝试列出目录的内容时,它爆炸了。我把它放在这里(在之前捕获目录路径并对其进行硬编码之后)进行测试以确保我什至获得了正确的位置。 dirExists 是真的,但我无法列出其中的文件。我得到的错误是:

FileSystemException: Directory listing failed, path = '/private/var/mobile/Containers/Shared/AppGroup/7DD4B316-3D73-4339-9B11-7516DE52F6FC/File Provider Storage/Downloads/' (OS Error: Operation not permitted, errno = 1)

如果我删除该行并继续打开文件 (readAsStringSync),我得到:

FileSystemException: Cannot open file, path = '/private/var/mobile/Containers/Shared/AppGroup/7DD4B316-3D73-4339-9B11-7516DE52F6FC/File Provider Storage/Downloads/example.fbg' (OS Error: Operation not permitted, errno = 1)

我不确定为什么它不允许我访问此文件。我缺少权限吗?如果我需要在问题中包含更多信息,请告诉我,我会更新。

终于找到了解决方法并使用 我最终做的是在应用程序委托中打开文件,将文件保存到应用程序文档目录,然后将其传递 url 到 Flutter 应用程序。我在 xcode 中打开了 iOS 模块并将 AppDelegate.swift 更改为以下内容:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
 ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    var drawingFilename = ""
    do {
        let isAcccessing = url.startAccessingSecurityScopedResource()
        var error: Error? = nil
        let path = url.path
        
        let string = try String(contentsOf: url)
        drawingFilename = (url.path as NSString).lastPathComponent
        print(drawingFilename)
       
        let filename = getDocumentsDirectory().appendingPathComponent(drawingFilename)

        do {
            try string.write(to: filename, atomically: true, encoding: String.Encoding.utf8)
        } catch {
            // failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding
        }
        if isAcccessing {
            url.stopAccessingSecurityScopedResource()
        }
      if #available(iOS 9.0, *) {
          return super.application(app, open: filename, options: options)
      } else {
         return false
      }
    } catch {
        print("Unable to load data: \(error)")
        return false
    }

    
      
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}
}

希望这对以后的人有所帮助。