阅读视图

发现新文章,点击刷新页面。

Flutter造轮子系列:flutter_permission_kit

仓库:github.com/maojiu-bb/f…

插件:pub.dev/packages/fl…

前言

在之前的博客中,我介绍过一个名为 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 功能

  1. 用 Xcode 打开你的项目(路径:ios/Runner.xcodeproj)
  2. 选中你的 App Target(一般为 Runner)
  3. 切换到 Signing & Capabilities 标签
  4. 点击 + Capability
  5. 添加 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
  • 更加简洁的配置权限列表

结语

造轮子本就是一个学习的过程。从最初的思考设计,到逐步打磨功能,再到不断优化,每一步都充满了挑战与收获。

❌