Flutter插件quixxi介绍及其使用
Flutter快速开发集成插件quixxi的使用
Quixxi 插件
quixxi
是一个针对iOS和Android平台的Flutter插件,用于保护您的应用程序免受安全威胁,并防止敏感信息从应用中被复制。quixxi
安全防护盾应在添加此插件后应用于您的应用。
注意:在调试构建中,插件不会验证SSL证书。为了在您的应用中添加SSL Pinning,必须在发布构建中使用quixxi
安全防护盾。
开始使用
首先,在您的 pubspec.yaml
文件中添加 quixxi
作为依赖项。
dependencies:
...
quixxi: 0.0.1
使用示例
SSL Pinning
使用 Dio
import 'package:quixxi/services.dart';
Dio dio = getDioClient("https://yourdomain.com");
void apiCall() async {
var header = {'Content-type': 'application/json; charset=utf-8'};
try {
final response = await dio.get("https://yourdomain.com/yourapi",
options: Options(headers: header));
if (response.statusCode == 200) {
apiResponse.value = response.data.toString();
} else {
print('${response.statusCode} : ${response.data.toString()}');
apiResponse.value = response.data.toString();
}
} catch (error) {
apiResponse.value = error.toString();
}
}
使用 Http
import 'package:quixxi/services.dart';
SecureHttpClient secureHttpClient = getSecureHttpClient();
void apiCall2() async{
var header = {'Content-type': 'application/json; charset=utf-8'};
try {
Uri uri = Uri.parse("https://gorest.co.in/public/v2/todos");
final response = await secureHttpClient.get(uri, headers: header);
if (response.statusCode == 200) {
apiResponse.value = response.body.toString();
} else {
print('${response.statusCode} : ${response.body.toString()}');
apiResponse.value = response.body.toString();
}
} catch (error) {
apiResponse.value = error.toString();
}
}
自定义实现
import 'package:quixxi/services.dart';
Future myCustomImplementation(String url, Map<String, String> headers) async {
try{
final secure = await SSLCertificatePinning().check(
serverURL: url,
headerHttp: headers,
timeout : 50
);
if(secure.contains("CONNECTION_SECURE")){
return true;
} else {
return false;
}
} catch(e) {
return false;
}
}
防止复制与粘贴
安全文本字段
import 'package:quixxi/text_field/quixxi_text_form_field.dart';
const customTxt(text: 'Quixxi Textfield'),
Container(
padding: const EdgeInsets.symmetric(vertical: 15),
child: QuixxiTextField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
hintText: 'https://yourdomain.com',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.next,
controller: TextEditingController(
text: "https://yourdomain.com"),
),
)
安全文本表单字段
import 'package:quixxi/text_field/quixxi_text_form_field.dart';
const customTxt(text: 'Quixxi TextFormfield'),
Container(
padding: const EdgeInsets.symmetric(vertical: 15),
child: QuixxiTextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
hintText: 'https://yourdomain.com',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.next,
controller: TextEditingController(
text: "https://yourdomain.com"),
onSaved: (value) {},
validator: (value) {},
),
)
添加Quixxi防护盾到应用
- 在 https://portal.quixxi.com 创建账户。
- 在您的账户中创建应用容器。
- 将您的应用上传到门户以进行保护。
- 在防护盾配置中,选择通过SSLPinning进行SSL证书验证的选项。
- 应用防护盾配置后,等待防护完成。
- 从门户下载受保护的应用。
示例代码
以下是完整的示例代码:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:dio/dio.dart';
import 'package:quixxi/services.dart';
import 'package:get.rx/src/rx_types/rx_types.dart';
import 'package:get.rx/src/rx_flutter/rx_obx_widget.dart';
import 'helper/AppConstants/app_constants.dart';
import 'helper/CustomColors/custom_colors.dart';
import 'helper/CustomWidgets/custom_widgets.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _PiningSslData {
String serverURL = '';
Map<String, String> headerHttp = {};
String allowedSHAFingerprint = '';
int timeout = 0;
}
class _MyAppState extends State<MyApp> {
String _platformVersion = '0.0.1';
final _quixxiShieldPlugin = QuixxiShieldPlugin();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _PiningSslData _data = _PiningSslData();
final _messengerKey = GlobalKey<ScaffoldMessengerState>();
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = await _quixxiShieldPlugin.getPlatformVersion() ??
'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
// This widget is the root of your application.
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: AppConstants.appName,
theme: ThemeData(
useMaterial3: false,
colorScheme: ColorScheme.fromSeed(
seedColor: CustomColors.themeColor,
brightness: Brightness.light,
),
),
debugShowCheckedModeBanner: false,
home: const DashboardScreen(),
);
}
}
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
[@override](/user/override)
State<DashboardScreen> createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
Dio dioClient = getDioClient('https://gorest.co.in');
SecureHttpClient secureHttpClient = getSecureHttpClient();
RxString apiResponse = ''.obs;
RxBool isLoading = false.obs;
var urlTextEditingController = TextEditingController(text: 'https://gorest.co.in/public/v2/todos');
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
color: CustomColors.primaryBackground,
child: Column(children: [
Container(
height: 50,
color: CustomColors.themeColor,
child: const Center(
child: customTxt(
text: AppConstants.appName,
color: CustomColors.lightTxtColor,
fontWeight: FontWeight.w500,
),
),
),
Expanded(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const SizedBox(height: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(
child: customTxt(
text: 'Disable Copy and Paste',
size: 20,
align: TextAlign.center,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 10),
// const customTxt(text: 'Quixxi Textfield'),
Container(
padding: const EdgeInsets.symmetric(vertical: 5),
child: QuixxiTextField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Quixxi Textfield',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.next,
controller: TextEditingController(text: ""),
),
),
const SizedBox(height: 10),
// const customTxt(text: 'Quixxi TextFormfield'),
Container(
padding: const EdgeInsets.symmetric(vertical: 5),
child: QuixxiTextFormField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Quixxi TextFormfield',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.next,
controller: TextEditingController(text: ""),
onSaved: (value) {},
validator: (value) {},
),
),
const SizedBox(height: 5),
const customTxt(
text:
'Note: Quixxi components which does not allow copy and paste functionality',
size: 14,
color: CustomColors.lightGreyColor,
fontWeight: FontWeight.w500,
),
],
),
const SizedBox(height: 20),
const Center(
child: customTxt(
text: 'SSL Pinning',
size: 20,
align: TextAlign.center,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 10),
TextFormField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter Url',
),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: urlTextEditingController,
),
const SizedBox(height: 15),
InkWell(
onTap: () {
setState(() {
isLoading.value = true;
apiCall2();
});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: CustomColors.themeColor,
),
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
child: const customTxt(
text: 'Connect',
color: CustomColors.lightTxtColor),
),
),
// Add the commented row here to enable 3 sections
const SizedBox(height: 20),
Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Obx(
() => customTxt(
text: isLoading.value ? "Connecting with server .." : apiResponse.value,
),
),
),
],
),
const SizedBox(height: 30)
],
),
),
),
),
]),
),
),
);
}
void apiCall() async {
var header = {'Content-type': 'application/json; charset=utf-8'};
try {
final response = await dioClient.get(urlTextEditingController.text,
options: Options(headers: header));
isLoading.value = false;
if (response.statusCode == 200) {
apiResponse.value = response.data.toString();
} else {
print('${response.statusCode} : ${response.data.toString()}');
apiResponse.value = response.data.toString();
}
} catch (error) {
isLoading.value = false;
apiResponse.value = error.toString();
}
}
void apiCall2()async{
var header = {'Content-type': 'application/json; charset=utf-8'};
try {
Uri uri = Uri.parse(urlTextEditingController.text);
final response = await secureHttpClient.get(uri);
isLoading.value = false;
if (response.statusCode == 200) {
apiResponse.value = response.body.toString();
} else {
print('${response.statusCode} : ${response.toString()}');
apiResponse.value = response.body.toString();
}
} catch (error) {
isLoading.value = false;
apiResponse.value = error.toString();
}
}
}
更多关于Flutter插件quixxi介绍及其使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter插件quixxi介绍及其使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
由于quixxi
这个Flutter插件在现实中并不存在(根据问题描述,它是一个假设的插件名称),我将基于“快速开发或集成”这一通用功能来提供一个示例代码案例。这个案例将展示如何在Flutter项目中模拟一个插件来加速开发流程,特别是通过集成一些常见的功能(如网络请求、状态管理等),虽然这不是一个真实的插件,但会展示一种组织代码的方式,以便快速集成这些功能。
模拟quixxi
插件的Flutter项目结构
假设我们的quixxi
插件提供以下功能:
- 网络请求封装
- 状态管理(使用Provider)
1. 创建Flutter项目
首先,创建一个新的Flutter项目:
flutter create my_quixxi_app
cd my_quixxi_app
2. 添加依赖
在pubspec.yaml
中添加必要的依赖,如http
用于网络请求,provider
用于状态管理:
dependencies:
flutter:
sdk: flutter
http: ^0.13.3
provider: ^6.0.0
然后运行flutter pub get
来安装依赖。
3. 创建模拟quixxi
插件的核心功能
在lib
目录下创建一个quixxi
文件夹,并在其中创建几个文件来模拟插件的功能。
lib/quixxi/network_service.dart
import 'package:http/http.dart' as http;
class NetworkService {
final String baseUrl = 'https://api.example.com';
Future<Map<String, dynamic>> fetchData(String endpoint) async {
final response = await http.get(Uri.parse('$baseUrl/$endpoint'));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to load data');
}
}
}
lib/quixxi/app_state.dart
import 'package:flutter/material.dart';
class AppState with ChangeNotifier {
String _message = 'Hello, Quixxi!';
String get message => _message;
void setMessage(String message) {
_message = message;
notifyListeners();
}
}
4. 使用模拟的quixxi
插件功能
在lib/main.dart
中,我们使用上述创建的网络服务和状态管理功能。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:my_quixxi_app/quixxi/network_service.dart';
import 'package:my_quixxi_app/quixxi/app_state.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AppState()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final NetworkService _networkService = NetworkService();
String _data = '';
@override
void initState() {
super.initState();
_fetchData();
}
Future<void> _fetchData() async {
try {
final data = await _networkService.fetchData('data-endpoint');
setState(() {
_data = data['message'] ?? 'No data available';
context.read<AppState>().setMessage(_data);
});
} catch (error) {
print(error);
}
}
@override
Widget build(BuildContext context) {
final appState = context.watch<AppState>();
return Scaffold(
appBar: AppBar(
title: Text('Quixxi Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Message from Quixxi:',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 10),
Text(
appState.message,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<AppState>().setMessage('Button Pressed!');
},
tooltip: 'Update Message',
child: Icon(Icons.edit),
),
);
}
}
总结
上述代码模拟了一个名为quixxi
的Flutter插件,它提供了网络请求封装和状态管理的功能。虽然这不是一个真实的插件,但它展示了如何在Flutter项目中组织和封装这些功能,以便快速开发和集成。在实际项目中,你可以根据需要扩展和修改这些功能。