Я создаю флаттер-приложение для iOS. Я создал тип файла, которым мое приложение и другое приложение могут обмениваться между собой. Для этого я использую библиотеку flutter receive_sharing_intent. Чтобы проверить это, я внес все необходимые изменения в свой файл info.plist для обработки моего пользовательского типа файла, я поместил пример файла этого типа в папку загрузок моего устройства (тестирование на iPad) и я нажимаю на него. оттуда, чтобы открыть его в моем приложении. ОС знает, что мое приложение может с этим справиться. Итак, мое приложение открывается, оно получает путь к общему файлу, но мое приложение не может открыть файл. Вот код в моем 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");
});
Сценарий: я запускаю приложение. Я захожу в папку с загрузками в файлах на айпаде. Я выбираю мой файл 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. Я открыл модуль iOS в xcode и изменил 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]
}
}
Надеюсь, это поможет кому-то в будущем.