Flutter离线优先与REST支持插件brick_offline_first_with_rest的使用
Flutter离线优先与REST支持插件brick_offline_first_with_rest的使用
OfflineFirstWithRestRepository
简化了与 OfflineFirstRepository
的 REST 集成。它包含一个串行队列,用于在单独的 SQLite 数据库中跟踪 REST 请求,只有在从主机收到响应后(即设备失去互联网连接)才会移除请求。参见 OfflineFirstWithRest#reattemptForStatusCodes
。
OfflineFirstWithRest
域使用与 OfflineFirst
相同的所有配置和注解。
模型
ConnectOfflineFirstWithRest
@ConnectOfflineFirstWithRest
装饰可以被一个或多个提供程序序列化的模型。离线优先在类级别上没有配置,仅扩展由其提供程序持有的配置:
@ConnectOfflineFirstWithRest(
restConfig: RestSerializable(),
sqliteConfig: SqliteSerializable(),
)
class MyModel extends OfflineFirstModel {}
从REST端点生成模型
提供了一个实用类,可使从JSON API生成模型变得简单。给定一个端点,转换器将推断字段类型并生成一个类。例如,以下内容会被保存到项目的 lib
目录中,并运行 dart lib/converter_script.dart
:
// lib/converter_script.dart
import 'package:brick_offline_first/rest_to_offline_first_converter.dart';
const BASE = "http://0.0.0.0:3000";
const endpoint = "$BASE/users";
final converter = RestToOfflineFirstConverter(endpoint: endpoint);
void main() {
converter.saveToFile();
}
// => dart lib/converter_script.dart
在模型生成后,检查是否有 List<dynamic>
和 null
类型。虽然转换器很聪明,但它并不比你更聪明。
测试
响应可以从 OfflineFirstWithRest
存储库中进行模拟。为方便起见,可以使用文件数据来模拟来自API的JSON响应:
// test/models/api/user.json
{
"user": { "name" : "Thomas" }
}
// test/models/user_test.dart
import 'package:brick_sqlite/testing.dart';
import 'package:my_app/brick/repository.dart';
void main() {
group("MySqliteProvider", () {
late MyRepository repository;
setUpAll(() async {
repository = MyRepository(
restProvider: RestProvider(
client: StubOfflineFirstWithRest.fromFiles('http://0.0.0.0:3000', {
'users': 'api/user.json'
}).client,
)
);
await repository.initialize()
});
});
}
默认情况下,对于 upsert
和 get
方法,返回相同的响应,唯一的变化在于状态码。但是,可以为不同的方法配置响应:
StubOfflineFirstWithRest(
baseEndpoint: 'http://0.0.0.0:3000',
responses: [
StubOfflineFirstRestResponse.fromFile('users', 'api/user.json', StubHttpMethod.get),
StubOfflineFirstRestResponse.fromFile('users', 'api/user-post.json', StubHttpMethod.post),
],
)
不使用文件进行模拟
虽然将响应存储在文件中可以很方便且减少代码混乱,但也可以直接定义响应:
StubOfflineFirstWithRest(
baseEndpoint: 'http://0.0.0.0:3000',
responses: [
StubOfflineFirstRestResponse('users', '{"name":"Bob"}'),
StubOfflineFirstRestResponse('users', '{"name":"Alice"}'),
],
)
处理端点变化
端点的变化必须明确声明。例如,/user
、/users
、/users?by_first_name=Guy
都是不同的。实例化时,指定任何预期的变化:
StubOfflineFirstRestResponse<User>(
endpoints: ["user", "users", "users?by_first_name=Guy"]
)
模拟多个模型
很少会只有一个模型需要模拟。可以高效地使用 StubOfflineFirstWithRest
对应用程序中的所有类进行模拟:
setUpAll() async {
final config = {
User: ['user', 'users'],
// 即使是个别成员端点也必须声明以获取关联
// REST 端点是手动配置的,所以内容可能会有所不同
Hat: ['hat/1', 'hat/2', 'hats'],
};
final responses = config.entries.map((modelConfig) {
return modelConfig.value.map((endpoint) {
return StubOfflineFirstRestResponse.fromFile(
'api/${modelConfig.key.toString().toLowerCase()}.json',
endpoint: endpoint,
);
});
}).expand((e) => e);
final client = StubOfflineFirstWithRest(
baseEndpoint: 'http://0.0.0.0:3000',
responses: responses,
).client;
}
更多关于Flutter离线优先与REST支持插件brick_offline_first_with_rest的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter离线优先与REST支持插件brick_offline_first_with_rest的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用brick_offline_first_with_rest
插件来实现离线优先与REST支持的一个基本示例。这个插件允许你的应用在没有网络连接时依然能够访问数据,并在网络恢复时同步数据。
首先,确保你已经在pubspec.yaml
文件中添加了brick_offline_first_with_rest
依赖:
dependencies:
flutter:
sdk: flutter
brick_offline_first_with_rest: ^latest_version # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤配置和使用该插件:
- 初始化离线存储和REST客户端
import 'package:flutter/material.dart';
import 'package:brick_offline_first_with_rest/brick_offline_first_with_rest.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Offline First with REST Demo'),
),
body: OfflineFirstDemo(),
),
);
}
}
class OfflineFirstDemo extends StatefulWidget {
@override
_OfflineFirstDemoState createState() => _OfflineFirstDemoState();
}
class _OfflineFirstDemoState extends State<OfflineFirstDemo> {
late OfflineFirstDatabase _database;
late OfflineFirstRestClient _client;
@override
void initState() {
super.initState();
// 初始化数据库(离线存储)
_database = OfflineFirstDatabase.init(
databaseName: 'my_database',
tables: [
OfflineFirstTable.init(
tableName: 'items',
columns: [
OfflineFirstColumn.init('id', OfflineFirstColumnType.integer, isPrimaryKey: true, autoIncrement: true),
OfflineFirstColumn.init('name', OfflineFirstColumnType.text),
OfflineFirstColumn.init('value', OfflineFirstColumnType.integer),
],
),
],
);
// 初始化REST客户端
_client = OfflineFirstRestClient.init(
baseUrl: 'https://api.example.com',
endpoints: [
OfflineFirstEndpoint.init(
endpointName: 'items',
path: '/items',
methods: [
OfflineFirstHttpMethod.get,
OfflineFirstHttpMethod.post,
OfflineFirstHttpMethod.put,
OfflineFirstHttpMethod.delete,
],
table: 'items',
mappers: {
'get': (Map<String, dynamic> json) => Item.fromJson(json),
'post': (Item item) => item.toJson(),
'put': (Item item) => item.toJson(),
},
),
],
database: _database,
);
}
@override
Widget build(BuildContext context) {
// 你的UI代码
return Center(
child: Text('离线优先与REST支持示例'),
);
}
}
class Item {
int id;
String name;
int value;
Item({required this.id, required this.name, required this.value});
factory Item.fromJson(Map<String, dynamic> json) {
return Item(
id: json['id'] as int,
name: json['name'] as String,
value: json['value'] as int,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'value': value,
};
}
}
- 使用离线优先功能
一旦初始化完成,你可以使用_database
和_client
来进行数据操作。例如,获取数据:
Future<List<Item>> fetchItems() async {
List<Map<String, dynamic>> itemsJson = await _client.get('items');
List<Item> items = itemsJson.map((json) => Item.fromJson(json)).toList();
return items;
}
添加数据:
Future<void> addItem(Item item) async {
await _client.post('items', item);
}
更新数据:
Future<void> updateItem(Item item) async {
await _client.put('items', item);
}
删除数据:
Future<void> deleteItem(int id) async {
await _client.delete('items', {'id': id});
}
- 同步数据
当网络恢复时,你可以手动或自动触发数据同步。通常,插件会处理大部分同步逻辑,但你可能需要监听网络状态变化来触发同步。
void syncData() async {
await _client.syncAll();
}
请注意,上述代码是一个简化的示例,实际项目中你可能需要处理更多的错误情况、添加更多的UI组件以及根据具体需求进行自定义。此外,brick_offline_first_with_rest
插件的具体API和用法可能会随着版本更新而变化,请参考最新的官方文档和示例代码。