Commit e3c92e38 by Miloš Karakaš Committed by GitHub

Support Calendar Access Levels (iOS17+) (#1151)

* - Split iOS calendar permission into write only and full access

* - Fixes + adjust readme and bump versions

* - Adjust Changelog.md

* - Support iOS 17+ calendar permissions

* - Update README.md to reflect iOS 17+ calendar permissions

* - Fix PermissionManager.m issue

* - Fix dependencies

* #1108 Adjusted for calendarReadOnly and calendarFullAccess

* #1108 Remove breaking change annotation from changelog

* Switch calendarReadOnly to calendarWriteOnly

* Update permission_handler/CHANGELOG.md

Co-authored-by: TimHoogstrate <tim566@hotmail.com>

* - Adjusted iOS EventPermissionStrategy.m after review

* Added NSCalendarsFullAccessUsageDescription to apple example .plist and podfile

* Fix deprecated calendar permission logic

* Update EventPermissionStrategy.m

* Make small adjustments

* Make small touch-ups

* Updates `Runner.xcodeproj` files

* Update permission_handler/README.md

Co-authored-by: TimHoogstrate <tim566@hotmail.com>

* Update permission_handler/README.md

Co-authored-by: TimHoogstrate <tim566@hotmail.com>

* Replace `calendar` with `contacts` in tests

* Update permission_handler_apple.yaml

* Update permission_handler.yaml

* Update permission_handler.yaml

* Update permission_handler_apple.yaml

---------

Co-authored-by: milosKarakas <milos.karakas@codebluestudio.com>
Co-authored-by: TimHoogstrate <tim566@hotmail.com>
Co-authored-by: Jeroen Weener <JeroenWeener@users.noreply.github.com>
Co-authored-by: Maurits van Beusekom <maurits@baseflow.com>
parent 5b4a5c42
......@@ -22,7 +22,11 @@ jobs:
name: App facing package
# The type of runner that the job will run on
runs-on: macos-latest
#
# TODO(mvanbeusekom): Manually set to macOS 13 to support Xcode 15 and iOS 17 SDKs.
# Currently `macos-latest` is based on macOS 12 and doesn't support iOS 17 SDK. This
# should be moved back to `macos-latest` when GitHub Actions images are updated.
runs-on: macos-13
env:
source-directory: ./permission_handler
......@@ -33,6 +37,13 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
# Override current Xcode version with version 15.0.1.
#
# TODO(mvanbeusekom): Remove when the macos-latest image supports version 15.0.1
# out of the box (see https://github.com/actions/runner-images/blob/main/README.md).
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_15.0.1.app/Contents/Developer'
# Make sure JAVA version 17 is installed on build agent.
- uses: actions/setup-java@v3
with:
......
......@@ -22,7 +22,11 @@ jobs:
name: Apple platform package
# The type of runner that the job will run on
runs-on: macos-latest
#
# TODO(mvanbeusekom): Manually set to macOS 13 to support Xcode 15 and iOS 17 SDKs.
# Currently `macos-latest` is based on macOS 12 and doesn't support iOS 17 SDK. This
# should be moved back to `macos-latest` when GitHub Actions images are updated.
runs-on: macos-13
env:
source-directory: ./permission_handler_apple
......@@ -32,6 +36,13 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
# Override current Xcode version with version 15.0.1.
#
# TODO(mvanbeusekom): Remove when the macos-latest image supports version 15.0.1
# out of the box (see https://github.com/actions/runner-images/blob/main/README.md).
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_15.0.1.app/Contents/Developer'
# Make sure the stable version of Flutter is available
- uses: subosito/flutter-action@v2
......
## 11.1.0
* Adds support for iOS 17+ [Calendar access levels](https://developer.apple.com/documentation/technotes/tn3152-migrating-to-the-latest-calendar-access-levels).
* Deprecates `Permission.calendar`. Use `Permission.calendarWriteOnly` to request a write-only access to the calendar. For full access to calendar use `Permission.calendarFullAccess`.
* For `Permission.calendarFullAccess` on iOS 17+ use `PERMISSION_EVENTS_FULL_ACCESS` in Podfile instead of `PERMISSION_EVENTS`.
* Adds web support by endorsing `permission_handler_html` as the web implementation of the permission handler. Only some permissions are supported at this time.
* Updates `permission_handler_android` dependency to version 12.0.1.
* Updates `permission_handler_apple` dependency to version 9.2.0.
* Updates `permission_handler_windows` dependency to version 0.2.0.
* Updates `permission_handler_platform_interface` dependency to version 4.0.2.
## 11.0.1
* Adds extension methods to the `PermissionStatus` enum allowing developers to register callback methods, which will improve code readability.
......@@ -74,7 +84,7 @@
## 9.0.2
* Fixes regression when requesting 'locationAlways' permission on Andriod 9 (Pie) and earlier.
* Fixes regression when requesting 'locationAlways' permission on Android 9 (Pie) and earlier.
## 9.0.1
......
......@@ -83,9 +83,12 @@ You must list the permission you want to use in your application:
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
## dart: [PermissionGroup.calendarWriteOnly, PermissionGroup.calendar (iOS 16 and below)]
# 'PERMISSION_EVENTS=1',
## dart: [PermissionGroup.calendarFullAccess, PermissionGroup.calendar (iOS 17 and above)]
# 'PERMISSION_EVENTS_FULL_ACCESS=1',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=1',
......@@ -143,22 +146,20 @@ You must list the permission you want to use in your application:
e.g. when you don't need camera permission, just delete 'NSCameraUsageDescription'
The following lists the relationship between `Permission` and `The key of Info.plist`:
| Permission | Info.plist | Macro |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| PermissionGroup.calendar | NSCalendarsUsageDescription | PERMISSION_EVENTS |
| PermissionGroup.reminders | NSRemindersUsageDescription | PERMISSION_REMINDERS |
| PermissionGroup.contacts | NSContactsUsageDescription | PERMISSION_CONTACTS |
| PermissionGroup.camera | NSCameraUsageDescription | PERMISSION_CAMERA |
| PermissionGroup.microphone | NSMicrophoneUsageDescription | PERMISSION_MICROPHONE |
| PermissionGroup.speech | NSSpeechRecognitionUsageDescription | PERMISSION_SPEECH_RECOGNIZER |
| PermissionGroup.photos | NSPhotoLibraryUsageDescription | PERMISSION_PHOTOS |
| PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse | NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription | PERMISSION_LOCATION |
| PermissionGroup.notification | PermissionGroupNotification | PERMISSION_NOTIFICATIONS |
| PermissionGroup.mediaLibrary | NSAppleMusicUsageDescription, kTCCServiceMediaLibrary | PERMISSION_MEDIA_LIBRARY |
| PermissionGroup.sensors | NSMotionUsageDescription | PERMISSION_SENSORS |
| PermissionGroup.bluetooth | NSBluetoothAlwaysUsageDescription, NSBluetoothPeripheralUsageDescription | PERMISSION_BLUETOOTH |
| PermissionGroup.appTrackingTransparency | NSUserTrackingUsageDescription | PERMISSION_APP_TRACKING_TRANSPARENCY |
| PermissionGroup.criticalAlerts | PermissionGroupCriticalAlerts | PERMISSION_CRITICAL_ALERTS |
| Permission | Info.plist | Macro |
|-------------------------------------------------------------------------------------------| ------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| PermissionGroup.calendar (< iOS 17) | NSCalendarsUsageDescription | PERMISSION_EVENTS |
| PermissionGroup.calendarWriteOnly (iOS 17+) | NSCalendarsWriteOnlyAccessUsageDescription | PERMISSION_EVENTS |
| PermissionGroup.calendarFullAccess (iOS 17+) | NSCalendarsFullAccessUsageDescription | PERMISSION_EVENTS_FULL_ACCESS |
| PermissionGroup.reminders | NSRemindersUsageDescription | PERMISSION_REMINDERS |
| PermissionGroup.contacts | NSContactsUsageDescription | PERMISSION_CONTACTS |
| PermissionGroup.camera | NSCameraUsageDescription | PERMISSION_CAMERA |
| PermissionGroup.microphone | NSMicrophoneUsageDescription | PERMISSION_MICROPHONE |
| PermissionGroup.speech | NSSpeechRecognitionUsageDescription | PERMISSION_SPEECH_RECOGNIZER |
| PermissionGroup.photos | NSPhotoLibraryUsageDescription | PERMISSION_PHOTOS |
| PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse | NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription | PERMISSION_LOCATION |
| PermissionGroup.notification | PermissionGroupNotification | PERMISSION_NOTIFICATIONS |
| PermissionGroup.mediaLibrary | NSAppleMusicUsageDescription, kTCCServiceMedia
4. Clean & Rebuild
......
......@@ -45,8 +45,11 @@ post_install do |installer|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
## dart: [PermissionGroup.calendarWriteOnly, PermissionGroup.calendar (until iOS 16)]
'PERMISSION_EVENTS=1',
## dart: [PermissionGroup.calendarFullAccess, PermissionGroup.calendar (from iOS 17)]
'PERMISSION_EVENTS_FULL_ACCESS=1',
## dart: PermissionGroup.reminders
'PERMISSION_REMINDERS=1',
......
......@@ -155,7 +155,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......
......@@ -61,6 +61,8 @@
<!-- Permission options for the `calendar` group -->
<key>NSCalendarsUsageDescription</key>
<string>Calendars</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>Calendar full access</string>
<!-- Permission options for the `camera` group -->
<key>NSCameraUsageDescription</key>
......
......@@ -2,7 +2,7 @@ name: permission_handler
description: Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
repository: https://github.com/baseflow/flutter-permission-handler
issue_tracker: https://github.com/Baseflow/flutter-permission-handler/issues
version: 11.0.1
version: 11.1.0
environment:
sdk: ">=2.15.0 <4.0.0"
......@@ -15,6 +15,8 @@ flutter:
default_package: permission_handler_android
ios:
default_package: permission_handler_apple
web:
default_package: permission_handler_html
windows:
default_package: permission_handler_windows
......@@ -22,10 +24,11 @@ dependencies:
flutter:
sdk: flutter
meta: ^1.7.0
permission_handler_android: ^11.0.0
permission_handler_apple: ^9.1.4
permission_handler_windows: ^0.1.3
permission_handler_platform_interface: ^3.11.5
permission_handler_android: ^12.0.1
permission_handler_apple: ^9.2.0
permission_handler_html: ^0.1.0+1
permission_handler_windows: ^0.2.0
permission_handler_platform_interface: ^4.0.2
dev_dependencies:
flutter_lints: ^1.0.4
......
......@@ -17,7 +17,7 @@ void main() {
});
test('PermissionActions on Permission: get status', () async {
final permissionStatus = await Permission.calendar.status;
final permissionStatus = await Permission.contacts.status;
expect(permissionStatus, PermissionStatus.granted);
});
......@@ -29,50 +29,50 @@ void main() {
final mockPermissionHandlerPlatform = PermissionHandlerPlatform.instance;
when(mockPermissionHandlerPlatform
.shouldShowRequestPermissionRationale(Permission.calendar))
.shouldShowRequestPermissionRationale(Permission.contacts))
.thenAnswer((_) => Future.value(true));
await Permission.calendar.shouldShowRequestRationale;
await Permission.contacts.shouldShowRequestRationale;
verify(mockPermissionHandlerPlatform
.shouldShowRequestPermissionRationale(Permission.calendar))
.shouldShowRequestPermissionRationale(Permission.contacts))
.called(1);
});
test('PermissionActions on Permission: request()', () async {
final permissionRequest = Permission.calendar.request();
final permissionRequest = Permission.contacts.request();
expect(permissionRequest, isA<Future<PermissionStatus>>());
});
test('PermissionCheckShortcuts on Permission: get isGranted', () async {
final isGranted = await Permission.calendar.isGranted;
final isGranted = await Permission.contacts.isGranted;
expect(isGranted, true);
});
test('PermissionCheckShortcuts on Permission: get isDenied', () async {
final isDenied = await Permission.calendar.isDenied;
final isDenied = await Permission.contacts.isDenied;
expect(isDenied, false);
});
test('PermissionCheckShortcuts on Permission: get isRestricted', () async {
final isRestricted = await Permission.calendar.isRestricted;
final isRestricted = await Permission.contacts.isRestricted;
expect(isRestricted, false);
});
test('PermissionCheckShortcuts on Permission: get isLimited', () async {
final isLimited = await Permission.calendar.isLimited;
final isLimited = await Permission.contacts.isLimited;
expect(isLimited, false);
});
test('PermissionCheckShortcuts on Permission: get isPermanentlyDenied',
() async {
final isPermanentlyDenied = await Permission.calendar.isPermanentlyDenied;
final isPermanentlyDenied = await Permission.contacts.isPermanentlyDenied;
expect(isPermanentlyDenied, false);
});
test('PermissionCheckShortcuts on Permission: get isProvisional', () async {
final isProvisional = await Permission.calendar.isProvisional;
final isProvisional = await Permission.contacts.isProvisional;
expect(isProvisional, false);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment