MST

星途 面试题库

面试题:Flutter SharedPreferences跨平台一致性及数据安全

考虑到Flutter是跨平台框架,在不同平台(如Android和iOS)使用SharedPreferences时,如何保证数据存储格式、访问权限等方面的一致性?同时,怎样确保存储数据的安全性,防止数据泄露?
12.6万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

保证数据存储格式和访问权限一致性

  1. 使用统一的接口抽象:在Flutter中,可以创建一个抽象类来封装SharedPreferences的操作,针对不同平台实现具体的操作类。例如:
abstract class SharedPreferencesHelper {
  Future<void> setString(String key, String value);
  Future<String?> getString(String key);
  // 其他类似的方法
}

class AndroidSharedPreferencesHelper implements SharedPreferencesHelper {
  @override
  Future<void> setString(String key, String value) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(key, value);
  }

  @override
  Future<String?> getString(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key);
  }
}

class IOSSharedPreferencesHelper implements SharedPreferencesHelper {
  // 类似的实现,在iOS上可能需要使用不同的存储方式,但接口保持一致
}
  1. 数据格式标准化:在存储数据时,尽量使用通用的数据格式。例如,对于复杂数据结构,使用JSON进行序列化和反序列化。
class User {
  final String name;
  final int age;

  User(this.name, this.age);

  Map<String, dynamic> toJson() => {
    'name': name,
    'age': age
  };

  factory User.fromJson(Map<String, dynamic> json) => User(
    json['name'],
    json['age']
  );
}

// 存储
Future<void> saveUser(User user) async {
  final helper = getSharedPreferencesHelper(); // 获取对应平台的helper
  final json = user.toJson();
  await helper.setString('user', jsonEncode(json));
}

// 读取
Future<User?> loadUser() async {
  final helper = getSharedPreferencesHelper();
  final jsonStr = await helper.getString('user');
  if (jsonStr != null) {
    final json = jsonDecode(jsonStr);
    return User.fromJson(json);
  }
  return null;
}
  1. 访问权限管理
    • 在Android中,确保在AndroidManifest.xml中配置适当的权限,例如:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 在iOS中,在Info.plist中配置相应的权限说明,例如:
<key>NSUserDefaultsRequiresAsynchronousAccess</key>
<true/>

同时,在Flutter代码中,通过上述抽象接口来访问数据,避免直接在不同平台的特定代码中处理权限,以保持一致性。

确保存储数据的安全性,防止数据泄露

  1. 数据加密:在存储数据前对敏感数据进行加密。可以使用encrypt库进行加密。
import 'package:encrypt/encrypt.dart';

final key = Key.fromLength(32);
final iv = IV.fromLength(16);
final encrypter = Encrypter(AES(key));

// 加密数据
Future<void> saveEncryptedString(String key, String value) async {
  final encrypted = encrypter.encrypt(value, iv: iv);
  final helper = getSharedPreferencesHelper();
  await helper.setString(key, encrypted.base64);
}

// 解密数据
Future<String?> loadDecryptedString(String key) async {
  final helper = getSharedPreferencesHelper();
  final encryptedStr = await helper.getString(key);
  if (encryptedStr != null) {
    final encrypted = Encrypted.fromBase64(encryptedStr);
    return encrypter.decrypt(encrypted, iv: iv);
  }
  return null;
}
  1. 限制访问范围
    • 仅在必要的地方访问SharedPreferences数据,避免在多个不必要的地方获取数据。
    • 在应用的架构设计上,将SharedPreferences的访问逻辑集中在少数几个模块中,便于管理和控制访问权限。
  2. 应用加固
    • 在Android上,可以使用ProGuard或R8进行代码混淆,防止反编译获取数据访问逻辑。
    • 在iOS上,启用App Thinning和Bitcode,并且确保应用在发布前进行了安全扫描。