Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Permission handler #117

Merged
merged 15 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions docs/permission_handler.md
DmitrDomrachev marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@

# Permission Handler

The guide describes how to use work with permissions in Flutter.

# permission_handler

[**permission_handler**](https://pub.dev/packages/permission_handler) is a permissions plugin for
Flutter. This plugin provides a cross-platform (iOS, Android, Web, Windows) API to request and check
permissions.

## Setup
Add permission_handler to your pubspec.yaml file.

### Android:
In the AndroidManifest.xml file, add the permissions you need.
For example, to request the camera permission, add the following line:
```xml
<uses-permission android:name="android.permission.CAMERA"/>
```
[AndroidManifest example](https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/example/android/app/src/main/AndroidManifest.xml)

### IOS:
In the Info.plist file, add the permissions you need.
For example, to request the camera permission, add the following line:
```xml
<key>NSCameraUsageDescription</key>
<string>camera</string>
```
[Info.plist example](https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler/example/ios/Runner/Info.plist)
In the Podfile file, you must describe the permissions you need:
```ruby
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# YOUR CUSTOM TARGET CODE HERE.
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
]
end
end
end
```
## Usage
Create 'permissions' feature, using the masson.

In the 'permissions/domain/entities/failure' directory create the file 'permission_failure.dart':
```dart
/// Statuses of the user permission request error.
sealed class PermissionFailure extends Failure {
PermissionFailure({required super.original, required super.trace});}

/// Access denied.
final class PermissionDenied extends PermissionFailure {
/// Create an instance of [PermissionDenied].
PermissionDenied({required super.original, required super.trace});}

/// Access denied forever.
final class PermissionDeniedForever extends PermissionFailure {
/// Create an instance of [PermissionDeniedForever].
PermissionDeniedForever({required super.original, required super.trace});}

/// Service unavailable.
final class ServiceDisabled extends PermissionFailure {
/// Create an instance of [ServiceDisabled].
ServiceDisabled({required super.original, required super.trace});}

/// Other errors when requesting user permissions.
final class PermissionException extends PermissionFailure {
/// Create an instance of [PermissionException].
PermissionException({required super.original, required super.trace});}
```

In the `permissions/domain/repositories` directory create the file `i_permission_handler_repository.dart`:
```dart
/// Typedef for the result of a request for user permissions.
typedef PermissionResult = Result<void, PermissionFailure>;

/// Interface of the repository for obtaining permissions from the user.
abstract class IPermissionHandlerRepository {
/// Check the permission for the use of [permission].
Future<PermissionResult> checkPermission(Permission permission);
}
```

In the `permissions/data/repositories` directory create the file `permission_handler_repository.dart`:
```dart
/// Implementation of [PermissionHandlerRepository] for obtaining permissions from the user.
class PermissionHandlerRepository implements IPermissionHandlerRepository {
/// Create an instance of [PermissionHandlerRepository].
PermissionHandlerRepository();

@override Future<PermissionResult> checkPermission(Permission permission) async {
final status = await permission.status;
if (status.isGranted) {
return const Result.ok(null);
}
if (status.isDenied) {
final status = await permission.request();
if (status.isGranted) {
return const Result.ok(null);
} else {
return Result.failed(PermissionDenied(original: null, trace: null));
}
}
if (status.isPermanentlyDenied) {
return Result.failed(PermissionDeniedForever(original: null, trace: null));
}
return Result.failed(PermissionException(original: null, trace: null));
}
}
```

Open the 'lib/features/app/di/app_scope' file.
Add the getter 'PermissionHandlerRepository' to the 'IAppScope' class:
```dart
/// Permission handler repository.
IPermissionHandlerRepository get permissionHandlerRepository;
```

In the 'AppScope' class, add the 'PermissionHandlerRepository' variable:
```dart
...
@override
final IPermissionHandlerRepository permissionHandlerRepository;
...
AppScope({
...
required this.permissionHandlerRepository,
...
});
```

Open the 'lib/features/app/di/app_scope_register.dart' file.
In the 'AppScopeRegister' class, create the 'PermissionHandlerRepository' instance:
```dart
final permissionHandlerRepository = PermissionHandlerRepository();
```

and pass it to the 'AppScope' constructor:
```dart
return AppScope(
...
permissionHandlerRepository: permissionHandlerRepository,
...
);
```

Now you can get the permissions repository from the context.
```dart
final permissionRepo = context.read<IAppScope>().permissionHandlerRepository;
```
19 changes: 19 additions & 0 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
9C081569228C6AC20006FEB3 /* ShellScript */,
B66FF691DE180E7D19E1A137 /* [CP] Embed Pods Frameworks */,
8A5D96D62B94EB81002D56E0 /* [firebase_crashlytics] Crashlytics Upload Symbols */,
BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -401,6 +402,24 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
BF513D92CD81C03FF509F09E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down
Empty file.
Empty file.
Empty file removed lib/features/shared/di/.gitkeep
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@
"description": "Example of feature"
},
"featureExampleFailedLoadIpMessage": "Failed to load IP address"
}
}
4 changes: 2 additions & 2 deletions lib/l10n/app_localizations_ru.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions lib/l10n/app_ru.arb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
"inboxCount": "{count, plural, zero{У вас нет новых сообщений} one{У вас 1 новое ообщение} other{У вас {count} новых сообщений}}",
"@inboxCount": {
"description": "Количетво сообщений",
"description": "Количество сообщений",
"placeholders": {
"count": {}
}
Expand All @@ -64,7 +64,7 @@
"debugScreenServerConnectButton": "Переключить сервер",
"debugScreenProxySubtitle": "Прокси",
"debugScreenProxyInfo": "Активирует передачу через прокси сервер.",
"debugScreenProxyEditTextLabel": "Введите адресс прокси сервера",
"debugScreenProxyEditTextLabel": "Введите адрес прокси сервера",
"debugScreenProxyConnectButton": "Подключить",
"debugScreenThemeSubtitle": "Тема приложения",
"debugScreenThemeLight": "Светлая тема",
Expand Down Expand Up @@ -113,7 +113,7 @@
"uiKitScreenColorCardSkeletonTertiaryName": "Skeleton Tertiary",
"@segmentFeatureExample": {
"---------": "---------",
"description": "Пример фичи"
"description": "Feature example"
},
"featureExampleFailedLoadIpMessage": "Не удалось загрузить IP-адрес"
}
"featureExampleFailedLoadIpMessage": "Failed to load IP address"
}
48 changes: 48 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
url: "https://pub.dev"
source: hosted
version: "11.3.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474"
url: "https://pub.dev"
source: hosted
version: "12.0.5"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
url: "https://pub.dev"
source: hosted
version: "9.4.4"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
url: "https://pub.dev"
source: hosted
version: "4.2.1"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies:
nested: 1.0.0
path: 1.9.0
path_provider: 2.1.2
permission_handler: 11.3.1
DmitrDomrachev marked this conversation as resolved.
Show resolved Hide resolved
provider: 6.1.1
retrofit: 4.0.3
rxdart: 0.27.7
Expand Down
Loading