Flutter造轮子系列:flutter_permission_kit
前言
在之前的博客中,我介绍过一个名为 PermissionsSwiftUI的 Swift 包,它是基于 SwiftUI 的 iOS 权限管理方案,设计简洁且功能全面。最初我尝试直接适配 PermissionsSwiftUI 来满足 Flutter 项目中 iOS 权限请求的需求,希望能快速复用它的核心功能和 UI 设计。但在实际开发过程中,发现直接适配存在诸多限制和兼容性问题。
因此,我决定从头打造一个专门针对 Flutter 的 iOS 权限管理插件——flutter_permission_kit。这个插件参考了 PermissionsSwiftUI 的设计灵感,结合 Flutter 的开发特点,提供了一个统一的权限请求接口和多种 UI 样式(包括Alert 和Modal),并且自动适配系统深色模式,保证在 iOS 15 及以上系统环境下的良好体验。
功能
权限 | 描述 | 使用的iOS框架 |
---|---|---|
Camera | Photo and video capture | AVFoundation |
Photos | Photo library access | Photos |
Microphone | Audio recording | AVFoundation |
Speech Recognition | Voice-to-text conversion | Speech |
Contacts | Address book access | Contacts |
Notifications | Push notifications | UserNotifications |
Location | GPS and location services | CoreLocation |
Calendar | Calendar events access | EventKit |
Tracking | App tracking transparency | AppTrackingTransparency |
Reminders | Reminders app access | EventKit |
Bluetooth | Bluetooth device access | CoreBluetooth |
Apple Music | Music library access | MediaPlayer |
Siri | Siri integration | Intents |
预览
安装
将以下内容添加到项目的 pubspec.yaml 文件中:
dependencies:
flutter_permission_kit: ^1.0.1
然后运行:
flutter pub get
iOS 设置
修改 Info.plist 文件
在 ios/Runner/Info.plist 中添加所需的权限描述信息:
<!-- 相机权限 -->
<key>NSCameraUsageDescription</key>
<string>我们需要访问你的相机以拍摄照片</string>
<!-- 照片库权限 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>我们需要访问你的照片以保存头像</string>
<!-- 麦克风权限 -->
<key>NSMicrophoneUsageDescription</key>
<string>我们需要访问你的麦克风以录制语音</string>
<!-- 语音识别权限 -->
<key>NSSpeechRecognitionUsageDescription</key>
<string>我们需要访问你的语音以进行转写</string>
<!-- 通讯录权限 -->
<key>NSContactsUsageDescription</key>
<string>我们需要访问你的联系人以帮助你找到朋友</string>
<!-- 定位权限 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要访问你的位置以显示附近内容</string>
<!-- 日历权限 -->
<key>NSCalendarsUsageDescription</key>
<string>我们需要访问你的日历以安排事件</string>
<!-- 跟踪权限 -->
<key>NSUserTrackingUsageDescription</key>
<string>我们需要访问你的跟踪数据以提供个性化广告</string>
<!-- 提醒事项权限 -->
<key>NSRemindersFullAccessUsageDescription</key>
<string>我们需要访问你的提醒事项以帮助你保持条理</string>
<!-- 蓝牙权限 -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>我们需要访问蓝牙以连接附近设备</string>
<!-- Apple Music 权限 -->
<key>NSAppleMusicUsageDescription</key>
<string>我们需要访问你的 Apple Music 音乐库</string>
<!-- Siri 权限 -->
<key>NSSiriUsageDescription</key>
<string>我们需要访问 Siri 以实现语音控制</string>
Siri 特殊配置
重要提示: 集成 Siri 除了在 Info.plist 配置外,还需在 Xcode 进行额外设置。
在 Xcode 中启用 Siri 功能
- 用 Xcode 打开你的项目(路径:ios/Runner.xcodeproj)
- 选中你的 App Target(一般为 Runner)
- 切换到 Signing & Capabilities 标签
- 点击 + Capability
- 添加 SiriKit 功能
这将自动创建必要的 entitlements 文件并配置 Siri 集成。
最低 iOS 版本要求
修改 Podfile
确保在 ios/Podfile 中设置平台版本为 iOS 15.0:
# 取消注释这一行以设置全局平台版本
platform :ios, '15.0'
修改 Xcode 工程设置
同样需要确保 ios/Runner.xcodeproj/project.pbxproj 中的部署目标至少为 iOS 15.0:
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
使用
基本使用
import 'package:flutter/material.dart';
import 'package:flutter_permission_kit/flutter_permission_kit.dart';
import 'package:flutter_permission_kit/core/flutter_permission_kit_config.dart';
import 'package:flutter_permission_kit/core/permission.dart';
import 'package:flutter_permission_kit/enums/display_type.dart';
import 'package:flutter_permission_kit/enums/permission_type.dart';
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (!mounted) return;
_initializePermissions();
});
}
Future<void> _initializePermissions() async {
final success = await FlutterPermissionKit.init(
config: FlutterPermissionKitConfig(
displayType: DisplayType.modal, // 也可以使用 DisplayType.alert
displayTitle: '应用权限请求',
displayHeaderDescription: '为了给你提供最佳体验,我们需要访问以下权限:',
displayBottomDescription: '你可以稍后在系统设置中更改这些权限。',
permissions: [
Permission(
name: '相机权限',
description: '用于拍摄照片和录制视频',
type: PermissionType.camera,
),
Permission(
name: '照片库',
description: '从相册中选择照片',
type: PermissionType.photos,
),
Permission(
name: '麦克风',
description: '录制语音信息',
type: PermissionType.microphone,
),
Permission(
name: '定位',
description: '显示附近的内容和地点',
type: PermissionType.location,
),
],
),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Permission Kit'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('iOS 权限管理'),
SizedBox(height: 20),
ElevatedButton(
onPressed: _initializePermissions,
child: Text('请求权限'),
),
],
),
),
),
);
}
}
配置示例
FlutterPermissionKitConfig(
displayType: DisplayType.modal,
displayTitle: '权限请求',
displayHeaderDescription: '我们需要你授予以下权限以继续使用:',
displayBottomDescription: '这些权限将帮助我们提供更好的功能体验。',
permissions: [
// 自定义你需要的权限列表
],
)
RoadMap
- 脱离 UI 的纯权限请求接口
- HealthPermissionKit
- 更加简洁的配置权限列表
结语
造轮子本就是一个学习的过程。从最初的思考设计,到逐步打磨功能,再到不断优化,每一步都充满了挑战与收获。