如何访问 Flutter SharedPrefences 中 iOS UserDefaults 存储的数据

问题描述 投票:0回答:3

我商店里已经有一个

iOS
应用程序,现在计划用新版本的 Flutter 来替换它
release

我想在 Flutter 代码中访问原生应用程序的

UserDefaults
数据。

使用 Flutter 文档中建议的方式,我得到了

null value
。我尝试过的是:

在我的

pubspec.yaml
文件中:

dependencies:
  shared_preferences: ^0.5.12+4

我是我的

home.dart
类文件,我正在导入标头:

import 'package:shared_preferences/shared_preferences.dart';

这就是我尝试从 iOS

 应用程序访问 
native
 应用程序中存储的数据的方式,我在 flutter 项目中使用相同的包 ID (包 ID) 来覆盖应用程序,并且它已成功覆盖。 

@override
void initState() {
    super.initState();
    getFromLocalMemory('user').then((value) =>
      userInfo = value
  );
}



Future<String> getFromLocalMemory(String key) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String user = prefs.getString(key);
    return user;
}

它总是返回 null。 而“user”键从 iOS 原生应用程序获取时有数据。

android ios flutter sharedpreferences nsuserdefaults
3个回答
4
投票

我们可以使用现有插件native_shared_preferences。它允许我们在

Android
上访问本机 SharedPreferences 和在
iOS
上访问本机 UserDefaults。 通过键“SomeKey”读取值的示例代码:

final someKey = "SomeKey";
var prefs = await NativeSharedPreferences.getInstance();
if (prefs.containsKey(someKey)) {
    print("Value for SomeKey: ${prefs.get(someKey)}");
}

0
投票

这种情况,我建议您使用平台渠道方式

平台渠道

iOS似乎不允许flutter框架访问NSUserDefaults,当它从一开始就没有创建它时,..

我希望它对你有用。


0
投票

可能为时已晚,但对于将来的搜索可能会有所帮助。 这是我从本机应用程序获取必要的令牌和一个 int 值的方法。

首先,您需要 path_provider 来查找必要的文件,plist_parser 用于 iO,因为 iO 将用户默认值存储为 .plist 文件,以及 xml 来读取 Android 中具有共享首选项的 .xml 文件。

如何查找 iO 原生值:

if (Platform.isIOS) {
  // Find the dir of the app.
  final appDocumentsDir = await getLibraryDirectory();
    // Create a list of contents in this dir, which includes files and dirs. 
    List contents = appDocumentsDir.listSync();
    // Find in the list the dir with user preferences
    Directory? prefsDir = contents.firstWhereOrNull((element) => element is Directory && element.path.contains('Preferences'));
    if (prefsDir != null) {
      // Get contents of the dir named 'Preferences'
      List subContents = prefsDir.listSync();
      // Find .plist file with package name of your app.
      File? prefsFile = subContents.firstWhereOrNull((element) => element is File && element.path.contains('com.your_app.plist'));
      if (prefsFile != null) {
        // Parse the file 
        final plist = PlistParser().parseBinaryFileSync(prefsFile.path);
        // With loop find necessary items
        for (final item in plist.entries) {
          if (item.key == 'access_token') {
            print('${item.value as String}');
            // your code to handle the value 
          }
          if (item.key == 'city_id') {
            print('${item.value as int}');
            // your code to handle the value 
          }
          // Here is an example to get stored data of Swift struct 
          if (item.key == 'selectedCity') {
            // Create decoder
            const asciiDecoder = AsciiDecoder();
            // Get ASCII value, which stored like [56, 104, 92 ...]
            final asciiValues = item.value;
            // Convert it to string.
            // It returns json string
            final cityJson = asciiDecoder.convert(asciiValues);
            // Convert json to the class with its factory.
            // You may use https://app.quicktype.io to convert JSON
            // to Flutter class and create necessary factories
            final city = City.fromRawJson(cityJson);
            // your code to handle the object of this class
          }
        }
      }
    }
  }

如何从 Android 中的共享首选项中获取值。

import 'package:xml/xml.dart' as xml;
// Name it somehow you like for example 'xml' as far as it conflicts with dart.io
// You will need dart.io for Platform

if (Platform.isAndroid) {
  // Find the dir of you app by package name
  final appDocumentsDir = Directory('/data/data/com.your_app');
  // Create a list of contents in this dir, which includes files and dirs. 
  List contents = appDocumentsDir.listSync();
  // Find in the list the dir with shared preferences
  Directory? prefsDir = contents.firstWhereOrNull((element) => element is Directory && element.path.contains('shared_prefs'));
  if (prefsDir != null) {
    // Get contents of the dir named shared_prefs
    List subContents = prefsDir.listSync();
    // Find .xml file with shared preferences.
    // Check the name of this file in native code, or
    // find it in Device Explorer of Android Studio.
    File? prefsFile = subContents.firstWhereOrNull((element) => element is File && element.path.contains('your_name.xml'));
    if (prefsFile != null) {
        // Create XML document
        final document = xml.XmlDocument.parse(prefsFile.readAsStringSync());
        // Loop from root to children
        for (final items in document.children) {
          // Loop for each child
          for (final item in items.childElements) {
            // Read item as Sting
            final itemString = item.outerXml;
            // Check for your name in prefs
            if (itemString.contains('access_token')) {
              // If prefs store it as String it will look like
              // '<string name="access_token">the token value</string>'
              // Get the value in this key
              final value = item.innerXml;
              // your code to handle the value
            }
            // For int or float you need to do something different.
            // Because prefs store it like '<int name="city_id" value="3" />'
            if (itemString.contains('city_id')) {
              // 'item.attributes' will return a list like 
              // [name="city_id", value="3"]
              // and you need to get second value and parse it to int
              final cityId = int.parse(item.attributes[1].value);
              // You code to handle the value 'cityId'
            }
          }
        }
      } 
    } 
  } 
}

.firstWhereOrNull 是来自 getX 非常有用的库的函数。 或者您可以使用下面的扩展。

extension IterableX<T> on Iterable<T> {
  T? firstWhereOrNull(bool Function(T) test) {
  T? firstItem;
  for (var item in this) {
    if (test(item)) {
      firstItem = item;
      break;
    }
  }
  return firstItem;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.