Flutter iOS文件共享-无法打开共享文件 [英] Flutter iOS File Sharing - Cannot Open Shared File

查看:207
本文介绍了Flutter iOS文件共享-无法打开共享文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am building a flutter app for iOS. I have created a file type that my app and another app can share back and forth. I am using the flutter receive_sharing_intent library to achieve this. To test it, I made all the necessary changes to my info.plist file to handle my custom file type, I placed an example file of that file type in the downloads folder of my device (testing on ipad), and I click on it from there to open it up in my app. The OS knows that my app can handle it. So, my app opens, it is receives the path of the shared file, but my app can't open the file. Here is the code in my main.dart that is handling reception of the file:

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上文件中的downloads文件夹.我选择位于其中的example.fbg文件(我的自定义文件类型).我的应用程序打开.

Scenario: I run the application. I go into my downloads folder in files on the ipad. I select my example.fbg file located there (my custom file type). My app opens up.

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

In the above code it blows up when I try to list the contents of the directory. I put this in here (after previously catching the directory path and hard coding it) to test to make sure I was even getting the right location. dirExists is true but I can't list the files in it. The error I get is:

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),我会得到:

If I take that line out and continue down to the opening of the file (readAsStringSync) I get:

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)

我不确定为什么它不能让我访问此文件.我缺少权限的东西吗?让我知道是否需要在问题中包含更多信息,我会进行更新.

I'm not sure why it won't let me access this file. Is there a permissions thing I'm missing? Let me know if I need to include more information in the question and I will update.

推荐答案

最后找到了解决方法,并使用

Finally found a work around and got it working using this answer. What I ended up doing was opening the file in the app delegate, saving the file to the apps documents directory, then passing that url to the Flutter application. I opened the iOS module in xcode and changed the AppDelegate.swift to the following:

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]
}
}

希望这对以后的人有帮助.

Hope this helps someone in the future.

这篇关于Flutter iOS文件共享-无法打开共享文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆