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]
}
}
希望这对以后的人有所帮助。
我正在为 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)
我不确定为什么它不允许我访问此文件。我缺少权限吗?如果我需要在问题中包含更多信息,请告诉我,我会更新。
终于找到了解决方法并使用
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]
}
}
希望这对以后的人有所帮助。