How to read file as String in Flutter that has been written to filesystem using NSKeyedArchiver in iOS?

272

As of writing this answer, there are no plugins to read the file, that has been previously written to the filesystem using NSKeyedArchiver in iOS. The way to read the file is to write custom platform-specific code.

So the iOS platform code on Swift will be something like the following:

private func callGetUserIdFromNativeApp(result: @escaping FlutterResult) {
    var account: FTAccountModel?
    let fm = FileManager.default
    let urls = fm.urls(for: .documentDirectory, in: .userDomainMask)
    if (!urls.isEmpty) {
        let file = urls[0].appendingPathComponent("Accounts.data", isDirectory: false)
        
        if (fm.fileExists(atPath: file.path)) {
            if let accountArray: [FTAccountModel] = NSKeyedUnarchiver.unarchiveObject(withFile: file.path) as? [FTAccountModel] {
        
                if (!accountArray.isEmpty) {
                    account = accountArray[0]
                }
            }
        }
    }
    
    if let userId: Int = account?.userId {
        result(String(userId))
    } else {
        result(nil)
    }
}

And the flutter part will use MethodChannel to invoke the native code:

static const MethodChannel _channel = const MethodChannel("CHANNEL_NAME");

static Future<String> getUserIdFromNativeIos() async {
  try {
    return await _channel.invokeMethod("METHOD_NAME");
  } catch (e){
    return _failedString();
  }
}
Share:
272
Sergio
Author by

Sergio

Passionate Android/Flutter developer. I use Android SDK, Flutter Framework, Java, Kotlin, Dart in my daily routine. Love to learn new technologies and happy to help other programmers on stackoverflow.

Updated on December 29, 2022

Comments

  • Sergio
    Sergio over 1 year

    After updating iOS native app with an app written on Flutter I want to read a file from filesystem on iOS device using Dart. The file I want to read has been previously written to filesystem using this ObjectiveC code:

    - (void)setAccount:(FTAccountModel *)account {
        _account = account;
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        path = [path stringByAppendingPathComponent:AccountModelPath];
        if (account) {
            NSArray * array = @[account];
            [array writeToFile:path atomically:YES];
            [NSKeyedArchiver archiveRootObject:array toFile:path];
        }
    }
    

    I've tried the following approach in Flutter using path_provider package:

    final appDocDir = await getApplicationDocumentsDirectory();
    final accountDataFile = File('${appDocDir.path}/$_iosAccountDataFile');
    String contents = await accountDataFile.readAsString();
    print("contents: $contents");
    

    But I get an error when calling readAsString() method:

    FileSystemException: Failed to decode data using encoding 'utf-8', path = '/var/mobile/Containers/Data/Application/FBCB4862-E5EA-4C93-8C2E-3DF1F00A8645/Documents/AccountModel.data'
    

    How to read file on iOS device using Dart and Flutter, that has been written using NSKeyedArchiver?

    • Abdel
      Abdel over 2 years
      did you found a solution for you question, I'm having the same problem