I encountered a PathAccessException
when using Flutter for iOS development.
PathAccessException: Cannot open file, path = '/private/var/mobile/Containers/Shared/AppGroup/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myDir/mySubDir/filename' (OS Error: Operation not permitted, errno = 1)
I use the Shared App Group directory to save the files.
This is my Flutter code (simplified):
class SharedStorage {
static Future<List<String>> readAllFiles() async {
List<String> result = [];
Iterable<File>? dataFiles = await getFileListFromSharedDirectory();
if (dataFiles != null && dataFiles.isNotEmpty) {
for (File file in dataFiles) {
String data = await readFromFile(file);
result.add(data);
}
}
return result;
}
static Future<Iterable<File>?> getFileListFromSharedDirectory() async {
// Gets shared directory path from iOS native code
String? dirPath = await channel.invokeMethod("getSharedDirectoryPath");
if(dirPath != null) {
Directory dir = Directory(dirPath);
List<FileSystemEntity> entities = await dataFileDir.list().toList();
final Iterable<File> files = entities.whereType<File>();
return files;
}
return null;
}
static Future<String> readFromFile(File file) async {
try {
String content = await file.readAsString();
return content;
} on Exception catch (e) {
print("Catch Exception: ${e.toString()}");
}
return "";
}
static Future<void> saveToFile(File file, String data) async {
try {
await file.writeAsString(data, mode: FileMode.write, flush: true);
} on Exception catch (e) {
print("Catch Exception: ${e.toString()}");
}
}
}
I have gotten the PathAccessException
in the readFromFile(file)
method where called await file.readAsString()
.
This error only occurs on certain iPhones. Is this related to the missing permissions of the app or the user’s own settings on the iPhone?
Below is the content of myApp.entitlements
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.company.my_project</string>
<string>group.com.company.my_project.my_sub_project</string>
</array>
</dict>
</plist>