Skip to content

Commit

Permalink
Support Calendar Access Levels (iOS17+) (#1151)
Browse files Browse the repository at this point in the history
* - 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 <[email protected]>

* - 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 <[email protected]>

* Update permission_handler/README.md

Co-authored-by: TimHoogstrate <[email protected]>

* 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 <[email protected]>
Co-authored-by: TimHoogstrate <[email protected]>
Co-authored-by: Jeroen Weener <[email protected]>
Co-authored-by: Maurits van Beusekom <[email protected]>
  • Loading branch information
5 people authored Nov 21, 2023
1 parent 5b4a5c4 commit e3c92e3
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 40 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/permission_handler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/permission_handler_apple.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
12 changes: 11 additions & 1 deletion permission_handler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 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.
Expand Down Expand Up @@ -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

Expand Down
37 changes: 19 additions & 18 deletions permission_handler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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',

Expand Down Expand Up @@ -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

Expand Down
5 changes: 4 additions & 1 deletion permission_handler/example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 2 additions & 0 deletions permission_handler/example/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
13 changes: 8 additions & 5 deletions permission_handler/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -15,17 +15,20 @@ flutter:
default_package: permission_handler_android
ios:
default_package: permission_handler_apple
web:
default_package: permission_handler_html
windows:
default_package: permission_handler_windows

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
Expand Down
22 changes: 11 additions & 11 deletions permission_handler/test/permission_handler_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand All @@ -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);
});

Expand Down

0 comments on commit e3c92e3

Please sign in to comment.