Flutter URL Scheme管理插件schemake的使用
Flutter URL Scheme管理插件schemake的使用
Schemake 是一个用于从声明性规范中描述模式的包。这些规范可以用于验证数据、生成代码或其他模式,如JSON Schema等。
Schemake的基本用法
示例1:定义和验证简单对象
import 'package:schemake/schemake.dart';
import 'dart:convert';
const person = Objects('Person', {
'name': Property(Strings()),
'age': Property(Nullable(Ints())),
});
void main() {
// 验证并转换JSON字符串到Map
final joe = person.convert(jsonDecode('{"name": "Joe"}'));
print(joe['name']); // 输出: Joe
print(joe['age']); // 输出: null
// 尝试转换不合法的数据将抛出异常
try {
person.convert(jsonDecode('{"name": "Joe", "age": "foo"}'));
} catch (e) {
print(e);
}
}
支持的数据类型
Schemake 类型 | Dart 类型 |
---|---|
Ints |
int |
Floats |
double |
Bools |
bool |
Strings |
String |
Arrays(T) |
List<S> |
ObjectsBase<C> |
C |
Objects |
Map<String, Object?> |
Maps(T) |
Map<String, S> |
Nullable(T) |
S? |
Validatable(T) |
S |
定义复杂的对象
class MyType {
final String example;
const MyType({required this.example});
}
const myTypes = Objects('MyTypes', {
'example': Property(Strings()),
});
class MyTypes extends ObjectsBase<MyType> {
const MyTypes() : super('MyType');
@override
MyType convert(Object? input) {
final map = input as Map<String, Object?>;
checkRequiredProperties(map.keys);
return MyType(
example: convertProperty(const Strings(), 'example', map),
);
}
@override
Converter<Object?, Object?>? getPropertyConverter(String property) =>
switch (property) {
'example' => const Strings(),
_ => null,
};
@override
Iterable<String> getRequiredProperties() => const {'example'};
}
使用Dart代码生成器
import 'package:schemake/dart_gen.dart' as dg;
import 'package:schemake/schemake.dart';
const person = Objects('Person', {
'name': Property(Strings()),
'age': Property(Nullable(Ints())),
});
void main() {
print(dg.generateDartClasses([person],
options: const dg.DartGeneratorOptions(methodGenerators: [
...dg.DartGeneratorOptions.defaultMethodGenerators,
dg.DartToJsonMethodGenerator(),
dg.DartFromJsonMethodGenerator(),
])));
}
生成的Dart类示例:
class Person {
final String name;
final int? age;
const Person({
required this.name,
this.age,
});
static Person fromJson(Object? value) => ...;
Map<String, Object?> toJson() => ...;
@override
String toString() => 'Person{name: "$name", age: $age}';
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name &&
age == other.age;
@override
int get hashCode => name.hashCode ^ age.hashCode;
}
JSON 和 YAML 处理
import 'package:yaml/yaml.dart';
void main() {
Person aPerson = Person.fromJson(loadYaml('name: Mary'));
// 打印: Person{name: "Mary", age: null}
print(aPerson);
}
完整示例 Demo
以下是一个完整的示例,展示如何使用Schemake定义一个复杂对象,并生成对应的Dart类。
import 'dart:io';
import 'package:schemake/dart_gen.dart';
import 'package:schemake/schemake.dart';
import 'package:yaml/yaml.dart';
const personSchema = Objects('Person', {
'name': Property(Strings()),
'age': Property(Nullable(Ints())),
'job': Property(Nullable(Strings())),
'friends': Property(Arrays<String, Strings>(Strings()))
});
void main() {
final yaml = loadYaml('''
name: Joe Doe
age: 42
friends: [ "Mary", "Fred" ]
''');
Map<String, Object?> joe = personSchema.convert(yaml);
print('// Full name: ${joe['name']}');
print('// Age: ${joe['age']}');
print('// Job: ${joe['job'] ?? "unknown"}');
final friends = joe['friends'] as List<String>;
print('// Friends: ${friends.join(', ')}');
try {
personSchema.convert(loadYaml('name: Fred'));
} on MissingPropertyException catch (e) {
stderr.writeln('Missing properties: ${e.missingProperties}');
}
print(generateDartClasses([personSchema],
options: const DartGeneratorOptions(methodGenerators: [
...DartGeneratorOptions.defaultMethodGenerators,
DartToJsonMethodGenerator(),
DartFromJsonMethodGenerator(),
])));
print(r'''
void main() {
final person = Person(name: 'Joe Doe', age: 42, job: "Developer", friends: ['Mary']);
print(jsonEncode(person));
final otherPerson = Person.fromJson(
'{"name": "Mary Jane", "friends": ["Joe"]}');
print(otherPerson.toJson());
}
''');
}
更多关于Flutter URL Scheme管理插件schemake的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter URL Scheme管理插件schemake的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中管理URL Scheme可以使用schemake
插件来实现。schemake
是一个帮助定义和管理URL Scheme的插件,尽管需要注意的是,schemake
本身并不是一个广泛知名的Flutter插件(可能是自定义的或特定项目中的插件),但我们可以基于Flutter中常见的URL Scheme管理方式来提供一个类似的实现案例。
Flutter中管理URL Scheme通常涉及以下步骤:
-
在iOS项目中配置URL Scheme:
- 编辑
ios/Runner/Info.plist
文件,添加自定义的URL Scheme。
- 编辑
-
在Android项目中配置URL Scheme:
- 编辑
android/app/src/main/AndroidManifest.xml
文件,添加intent-filter来声明URL Scheme。
- 编辑
-
在Flutter代码中处理URL:
- 使用
dart:ui
中的window.defaultRouteName
或者url_launcher
插件来接收和处理URL。
- 使用
下面是一个示例,展示如何在Flutter应用中配置和处理URL Scheme:
1. 配置iOS URL Scheme
编辑ios/Runner/Info.plist
文件,添加如下内容:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>mycustomscheme</string>
</array>
</dict>
</array>
2. 配置Android URL Scheme
编辑android/app/src/main/AndroidManifest.xml
文件,在<activity>
标签内添加intent-filter:
<activity
android:name=".MainActivity"
android:label="flutter_app"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="mycustomscheme" android:host="*" />
</intent-filter>
</activity>
3. 在Flutter代码中处理URL
使用window.defaultRouteName
来获取启动时的URL Scheme:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
String initialRoute = window.defaultRouteName ?? '/';
return MaterialApp(
title: 'Flutter URL Scheme Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: initialRoute,
routes: {
'/': (context) => HomeScreen(),
'/deep-link': (context) => DeepLinkScreen(url: initialRoute),
// Add more routes as needed
},
onGenerateRoute: (settings) {
// Custom route handling if needed
return MaterialPageRoute(builder: (context) => HomeScreen());
},
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Text('This is the Home Screen'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Simulate opening the app with a deep link
// Note: This is just for demonstration. In a real app, this would be handled by the OS.
Navigator.pushNamed(context, '/deep-link?path=some/deep/link');
},
tooltip: 'Open Deep Link',
child: Icon(Icons.open_in_new),
),
);
}
}
class DeepLinkScreen extends StatelessWidget {
final String url;
DeepLinkScreen({required this.url});
@override
Widget build(BuildContext context) {
Uri uri = Uri.parse(url);
String path = uri.pathSegments.isNotEmpty ? uri.pathSegments.join('/') : 'No Path';
Map<String, String> queryParams = uri.queryParameters;
return Scaffold(
appBar: AppBar(
title: Text('Deep Link Screen'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('URL: $url'),
Text('Path: $path'),
Text('Query Parameters: ${queryParams.toString()}'),
],
),
),
);
}
}
在上面的代码中,我们定义了两个路由:/
和 /deep-link
。当应用通过URL Scheme(如mycustomscheme://some/deep/link
)启动时,window.defaultRouteName
将包含这个URL,然后我们可以根据URL解析出路径和查询参数,并在相应的屏幕上显示这些信息。
请注意,上述代码是一个基本的示例,实际项目中可能需要根据具体需求进行更多的配置和处理。