Flutter深度选择插件deep_pick的使用
Flutter深度选择插件deep_pick的使用
deep_pick
是一个用于简化手动JSON解析的Dart包,它提供了一种类型安全的API来处理JSON数据。以下是关于如何在Flutter项目中使用deep_pick
插件的详细介绍。
添加依赖
首先,在您的pubspec.yaml
文件中添加deep_pick
作为依赖:
dependencies:
deep_pick: ^1.0.0
然后运行以下命令以安装该包:
$ dart pub add deep_pick
使用示例
示例代码
下面是一个完整的示例,展示了如何使用deep_pick
从JSON响应中解析值。我们将创建一个名为Shoe
的数据类,并展示如何从JSON结构中提取信息并映射到这个类。
定义数据类
class Shoe {
const Shoe({
required this.id,
required this.name,
this.manufacturer,
required this.tags,
required this.price,
});
factory Shoe.fromPick(RequiredPick pick) {
final newApi = pick.fromContext('newApi').asBoolOrFalse();
final pricePick = pick('price');
return Shoe(
id: pick('id').asStringOrThrow(),
name: pick('name').asStringOrThrow(),
manufacturer: newApi
? pick('manufacturer').asStringOrThrow()
: pick('manufacturer').asStringOrNull(),
tags: pick('tags').asListOrEmpty((it) => it.asStringOrThrow()),
price: () {
if (pricePick.isAbsent) return 'Not for sale';
return pricePick.asStringOrNull() ?? 'Price available soon';
}(),
);
}
final String id;
final String name;
final String? manufacturer;
final List<String> tags;
final String price;
@override
String toString() {
return 'Shoe{id: $id, name: "$name", price: "$price", tags: $tags}';
}
}
解析JSON
接下来是主函数,展示了如何使用deep_pick
来解析JSON数据:
import 'dart:convert';
import 'package:deep_pick/deep_pick.dart';
const String rawJson = '''
{
"shoes": [
{
"id": "421",
"name": "Nike Zoom Fly 3",
"manufacturer": "nike",
"tags": ["nike", "JustDoIt"]
},
{
"id": "532",
"name": "adidas Ultraboost",
"manufacturer": "adidas",
"tags": ["adidas", "ImpossibleIsNothing"],
"price": null
}
]
}
''';
Future<void> main() async {
final json = jsonDecode(rawJson);
// 深度选择嵌套值
final firstTag = pick(json, 'shoes', 1, 'tags', 0).asStringOrThrow();
print(firstTag); // 输出: adidas
// 获取可能为null的值
final manufacturer = pick(json, 'shoes', 0, 'manufacturer').asStringOrNull();
print(manufacturer); // 输出: nike
// 将字符串转换为不同类型的值
final id = pick(json, 'shoes', 0, 'id');
print(id.asIntOrNull()); // 输出: 421
print(id.asDoubleOrNull()); // 输出: 421.0
print(id.asStringOrNull()); // 输出: "421"
// 解析列表
final tags = pick(json, 'shoes', 0, 'tags')
.asListOrEmpty((it) => it.asStringOrThrow());
print(tags); // 输出: [nike, JustDoIt]
// 解析映射
final shoe = pick(json, 'shoes', 0).required().asMapOrThrow();
print(shoe); // 输出: {id: 421, name: Nike Zoom Fly 3, tags: [nike, JustDoIt]}
// 映射对象到Dart对象
final firstShoe = pick(json, 'shoes', 0).letOrNull((p) => Shoe.fromPick(p));
print(firstShoe);
// 输出: Shoe{id: 421, name: "Nike Zoom Fly 3", price: "Price available soon", tags: [nike, JustDoIt]}
// 处理不存在的值
final thirdShoe = pick(json, 'shoes', 2).letOrNull((p) => Shoe.fromPick(p));
print(thirdShoe); // 输出: null
// 解析整个列表
final shoes = pick(json, 'shoes').asListOrEmpty((p) => Shoe.fromPick(p));
print(shoes);
// 输出: [
// Shoe{id: 421, name: "Nike Zoom Fly 3", price: "Price available soon", tags: [nike, JustDoIt]},
// Shoe{id: 532, name: "adidas Ultraboost", price: "Not for sale", tags: [adidas, ImpossibleIsNothing]}
// ]
// 访问超出范围的值
final puma = pick(json, 'shoes', 1);
print(puma.isAbsent); // 输出: true
print(puma.value); // 输出: null
// 加载来自API的数据
final stats = await getStats();
print(stats.requests);
}
Future<CounterApiStats> getStats() async {
final response = await http.get(Uri.parse('https://api.countapi.xyz/stats'));
final json = jsonDecode(response.body);
// 解析单个字段
final int? requests = pick(json, 'requests').asIntOrNull();
final int keys_created = pick(json, 'keys_created').asIntOrThrow();
final int? keys_updated = pick(json, 'keys_updated').asIntOrNull();
final String? version = pick(json, 'version').asStringOrNull();
print(
'requests $requests, keys_created $keys_created, '
'keys_updated: $keys_updated, version: "$version"',
);
// 解析完整对象
final CounterApiStats stats = CounterApiStats.fromPick(pick(json).required());
// 解析列表
final List<CounterApiStats> multipleStats = pick(json, 'items')
.asListOrEmpty((pick) => CounterApiStats.fromPick(pick));
print(multipleStats); // 总是输出 [], 因为countapi没有items
return stats;
}
class CounterApiStats {
const CounterApiStats({
required this.requests,
required this.keys_created,
required this.keys_updated,
this.version,
});
final int requests;
final int keys_created;
final int keys_updated;
final String? version;
factory CounterApiStats.fromPick(RequiredPick pick) {
return CounterApiStats(
requests: pick('requests').asIntOrThrow(),
keys_created: pick('keys_created').asIntOrThrow(),
keys_updated: pick('keys_updated').asIntOrThrow(),
version: pick('version').asStringOrNull(),
);
}
}
通过以上代码,您可以了解如何使用deep_pick
插件进行JSON解析,包括如何处理嵌套值、不同类型之间的转换、解析列表和映射对象等。希望这些示例能帮助您更好地理解和使用deep_pick
。
更多关于Flutter深度选择插件deep_pick的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter深度选择插件deep_pick的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,deep_pick
是一个在 Flutter 中用于深度选择(Deep Linking)和数据解析的插件。通过它,你可以很方便地解析从 URL 传递的复杂数据。以下是一个如何使用 deep_pick
插件的基本示例代码案例。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 deep_pick
依赖:
dependencies:
flutter:
sdk: flutter
deep_pick: ^x.y.z # 请使用最新版本号
2. 导入插件
在你的 Dart 文件中导入 deep_pick
:
import 'package:deep_pick/deep_pick.dart';
3. 配置路由
你需要配置路由以处理深度链接。这通常使用 flutter_navigator
或类似的库,但 deep_pick
允许你轻松解析从 URL 中提取的数据。
4. 解析 URL 数据
假设你有一个 URL 如下:
https://example.com/deeplink?user={id:123,name:JohnDoe}&post={id:456,title:HelloFlutter}
你可以使用 deep_pick
来解析这个 URL 的数据:
import 'package:flutter/material.dart';
import 'package:deep_pick/deep_pick.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Deep Linking Example'),
),
body: Center(
child: DeepLinkExample(),
),
),
);
}
}
class DeepLinkExample extends StatefulWidget {
@override
_DeepLinkExampleState createState() => _DeepLinkExampleState();
}
class _DeepLinkExampleState extends State<DeepLinkExample> {
Map<String, dynamic> parsedData = {};
@override
void initState() {
super.initState();
// 模拟从 URL 获取的数据(通常这数据会从应用启动参数中获取)
String url = "https://example.com/deeplink?user={id:123,name:JohnDoe}&post={id:456,title:HelloFlutter}";
_parseDeepLink(url);
}
void _parseDeepLink(String url) async {
try {
// 使用 deep_pick 解析 URL
Map<String, dynamic> deepLinkData = await DeepPick.parse(url);
setState(() {
parsedData = deepLinkData;
});
print("Parsed Data: $parsedData");
} catch (e) {
print("Error parsing deep link: $e");
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Parsed User Data:"),
if (parsedData.containsKey('user'))
Text("ID: ${parsedData['user']['id']}, Name: ${parsedData['user']['name']}")
else
Text("No user data parsed"),
Text("Parsed Post Data:"),
if (parsedData.containsKey('post'))
Text("ID: ${parsedData['post']['id']}, Title: ${parsedData['post']['title']}")
else
Text("No post data parsed"),
],
);
}
}
注意事项
- 实际应用中:URL 通常不会在代码中硬编码,而是从应用启动参数中读取。例如,你可以使用
window.defaultRouteName
或getInitialLink
等方法获取启动时的 URL。 - 安全性:解析来自 URL 的数据时要小心,确保进行必要的验证和清理,以防止安全问题。
- 实际数据格式:URL 编码可能因不同需求而有所不同,请确保数据格式和编码方式与
deep_pick
的解析能力相匹配。
通过这个示例,你可以看到如何使用 deep_pick
插件解析复杂的 URL 数据,并将其应用在你的 Flutter 应用中。