Общий доступ к файлам Flutter iOS — не удается открыть общий файл

Я создаю флаттер-приложение для 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)

Я не уверен, почему он не позволит мне получить доступ к этому файлу. Есть ли какие-то разрешения, которые мне не хватает? Дайте мне знать, если мне нужно включить дополнительную информацию в вопрос, и я обновлю.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 940
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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]
}
}

Надеюсь, это поможет кому-то в будущем.

Другие вопросы по теме