diff --git a/.eslintignore b/.eslintignore index 279106d4..6e1343ef 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,3 +4,4 @@ example/ fetchWindowsCapabilites.js mock.js node_modules +react-native.config.js diff --git a/MIGRATION.md b/MIGRATION.md deleted file mode 100644 index 536cc0b4..00000000 --- a/MIGRATION.md +++ /dev/null @@ -1,39 +0,0 @@ -# Migration from v2 - -## What's new - -- Windows support ([#530](https://github.com/zoontek/react-native-permissions/pull/530) by @bzoz) -- Android 11 support -- iOS 14 support added, iOS 9 support dropped -- Updated example app -- New iOS 14+ permission handler: `Permission-PhotoLibraryAddOnly`. It exposes a new method: `openLimitedPhotoLibraryPicker` ([#510](https://github.com/zoontek/react-native-permissions/pull/510) by @jochem725) -- New iOS 14+ permission handler: `Permission-LocationAccuracy`. It exposes two new methods: `checkLocationAccuracy` & `requestLocationAccuracy` ([#503](https://github.com/zoontek/react-native-permissions/pull/503) by @adapptor-kurt) -- Support of the new `Limited` status for `PhotoLibrary` permission ([#510](https://github.com/zoontek/react-native-permissions/pull/510) by @jochem725) -- Support of the new `Limited` status for `Notifications` permission (=`Ephemeral`, (see [Apple doc](https://developer.apple.com/documentation/usernotifications/unauthorizationstatus/unauthorizationstatusephemeral?language=objc)) - -## Breaking changes - -1. `.podspec` extension is no longer required in your `Podfile`: - -```diff -target 'YourAwesomeProject' do - - # … - - permissions_path = '../node_modules/react-native-permissions/ios' - -- pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars.podspec" -+ pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars" -- pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec" -+ pod 'Permission-Camera', :path => "#{permissions_path}/Camera" - - # … - -end -``` - -2. `request(PERMISSIONS.IOS.PHOTO_LIBRARY)` and `requestNotifications` could now resolve with a `RESULTS.LIMITED` permission status. - -## Known issue - -Updating the permission status to `Ask me next time` in your app settings will not update the permission status on Android 11 for now. diff --git a/README.md b/README.md index ee0408c7..b87533db 100644 --- a/README.md +++ b/README.md @@ -37,40 +37,42 @@ $ yarn add react-native-permissions ### iOS -By default no permission handler is installed. Update your `Podfile` by choosing the ones you want to check or request, then run `pod install`. - -```ruby -target 'YourAwesomeProject' do - - # … - - permissions_path = '../node_modules/react-native-permissions/ios' - - pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency" - pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral" - pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars" - pod 'Permission-Camera', :path => "#{permissions_path}/Camera" - pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts" - pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID" - pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy" - pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways" - pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse" - pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary" - pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone" - pod 'Permission-Motion', :path => "#{permissions_path}/Motion" - pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications" - pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary" - pod 'Permission-PhotoLibraryAddOnly', :path => "#{permissions_path}/PhotoLibraryAddOnly" - pod 'Permission-Reminders', :path => "#{permissions_path}/Reminders" - pod 'Permission-Siri', :path => "#{permissions_path}/Siri" - pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition" - pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit" - -end +By default no permission handler is installed. To add one, update your `package.json` by adding the permissions used in your app, then run `npx react-native setup-ios-permissions` followed by `pod install`. + +_📌  Note that these commands must be re-executed each time you update this config, delete the `node_modules` directory or update this library. An useful trick to cover a lot of these cases is running them on `postinstall` and just run `yarn` or `npm install` manually when needed._ + +```json +{ + "reactNativePermissionsIOS": [ + "AppTrackingTransparency", + "BluetoothPeripheral", + "Calendars", + "Camera", + "Contacts", + "FaceID", + "LocationAccuracy", + "LocationAlways", + "LocationWhenInUse", + "MediaLibrary", + "Microphone", + "Motion", + "Notifications", + "PhotoLibrary", + "PhotoLibraryAddOnly", + "Reminders", + "Siri", + "SpeechRecognition", + "StoreKit" + ], + "devDependencies": { + "pod-install": "0.1.38" + }, + "scripts": { + "postinstall": "react-native setup-ios-permissions && pod-install" + } +} ``` -> :warning: If you see a **No permission handler detected** error: Make sure that you have at least one permission handler set up. In some cases the Xcode cache needs to be cleared (`Xcode -> Product -> Clean Build Folder`) - Then update your `Info.plist` with wanted permissions usage descriptions: ```xml @@ -129,29 +131,6 @@ Then update your `Info.plist` with wanted permissions usage descriptions: ``` -#### Workaround for `use_frameworks!` issues - -If you use `use_frameworks!`, add this at the top of your `Podfile`, and uncomment the line corresponding to your CocoaPods version: - -```ruby -use_frameworks! - -# Convert all permission pods into static libraries -pre_install do |installer| - Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} - - installer.pod_targets.each do |pod| - if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-') - def pod.build_type; - # Uncomment the line corresponding to your CocoaPods version - # Pod::BuildType.static_library # >= 1.9 - # Pod::Target::BuildType.static_library # < 1.9 - end - end - end -end -``` - ### Android Add all wanted permissions to your app `android/app/src/main/AndroidManifest.xml` file: diff --git a/RNPermissions.podspec b/RNPermissions.podspec index 9583a512..9a464651 100644 --- a/RNPermissions.podspec +++ b/RNPermissions.podspec @@ -16,5 +16,5 @@ Pod::Spec.new do |s| s.requires_arc = true s.source = { :git => package["repository"]["url"], :tag => s.version } - s.source_files = "ios/*.{h,m}" + s.source_files = "ios/*.{h,m,mm}" end diff --git a/example/ios/Podfile b/example/ios/Podfile index 3e56b5e4..8560996c 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -21,23 +21,6 @@ if linkage != nil use_frameworks! :linkage => linkage.to_sym end -# use_frameworks! - -# # Convert all permission pods into static libraries -# pre_install do |installer| -# Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} - -# installer.pod_targets.each do |pod| -# if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-') -# def pod.build_type; -# # Uncomment one line depending on your CocoaPods version -# # Pod::BuildType.static_library # >= 1.9 -# # Pod::Target::BuildType.static_library # < 1.9 -# end -# end -# end -# end - target 'RNPermissionsExample' do config = use_native_modules! @@ -60,28 +43,6 @@ target 'RNPermissionsExample' do :app_path => "#{Pod::Config.instance.installation_root}/.." ) - permissions_path = '../node_modules/react-native-permissions/ios' - - pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency" - pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral" - pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars" - pod 'Permission-Camera', :path => "#{permissions_path}/Camera" - pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts" - pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID" - pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy" - pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways" - pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse" - pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary" - pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone" - pod 'Permission-Motion', :path => "#{permissions_path}/Motion" - pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications" - pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary" - pod 'Permission-PhotoLibraryAddOnly', :path => "#{permissions_path}/PhotoLibraryAddOnly" - pod 'Permission-Reminders', :path => "#{permissions_path}/Reminders" - # pod 'Permission-Siri', :path => "#{permissions_path}/Siri" - pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition" - pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit" - post_install do |installer| react_native_post_install( installer, diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index d527b3be..dd9eaf34 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -78,42 +78,6 @@ PODS: - hermes-engine/Pre-built (0.71.3) - libevent (2.1.12) - OpenSSL-Universal (1.1.1100) - - Permission-AppTrackingTransparency (3.6.1): - - RNPermissions - - Permission-BluetoothPeripheral (3.6.1): - - RNPermissions - - Permission-Calendars (3.6.1): - - RNPermissions - - Permission-Camera (3.6.1): - - RNPermissions - - Permission-Contacts (3.6.1): - - RNPermissions - - Permission-FaceID (3.6.1): - - RNPermissions - - Permission-LocationAccuracy (3.6.1): - - RNPermissions - - Permission-LocationAlways (3.6.1): - - RNPermissions - - Permission-LocationWhenInUse (3.6.1): - - RNPermissions - - Permission-MediaLibrary (3.6.1): - - RNPermissions - - Permission-Microphone (3.6.1): - - RNPermissions - - Permission-Motion (3.6.1): - - RNPermissions - - Permission-Notifications (3.6.1): - - RNPermissions - - Permission-PhotoLibrary (3.6.1): - - RNPermissions - - Permission-PhotoLibraryAddOnly (3.6.1): - - RNPermissions - - Permission-Reminders (3.6.1): - - RNPermissions - - Permission-SpeechRecognition (3.6.1): - - RNPermissions - - Permission-StoreKit (3.6.1): - - RNPermissions - RCT-Folly (2021.07.22.00): - boost - DoubleConversion @@ -455,7 +419,7 @@ PODS: - React-jsi (= 0.71.3) - React-logger (= 0.71.3) - React-perflogger (= 0.71.3) - - RNPermissions (3.6.1): + - RNPermissions (3.7.0): - React-Core - RNVectorIcons (9.2.0): - React-Core @@ -494,24 +458,6 @@ DEPENDENCIES: - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - libevent (~> 2.1.12) - OpenSSL-Universal (= 1.1.1100) - - Permission-AppTrackingTransparency (from `../node_modules/react-native-permissions/ios/AppTrackingTransparency`) - - Permission-BluetoothPeripheral (from `../node_modules/react-native-permissions/ios/BluetoothPeripheral`) - - Permission-Calendars (from `../node_modules/react-native-permissions/ios/Calendars`) - - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`) - - Permission-Contacts (from `../node_modules/react-native-permissions/ios/Contacts`) - - Permission-FaceID (from `../node_modules/react-native-permissions/ios/FaceID`) - - Permission-LocationAccuracy (from `../node_modules/react-native-permissions/ios/LocationAccuracy`) - - Permission-LocationAlways (from `../node_modules/react-native-permissions/ios/LocationAlways`) - - Permission-LocationWhenInUse (from `../node_modules/react-native-permissions/ios/LocationWhenInUse`) - - Permission-MediaLibrary (from `../node_modules/react-native-permissions/ios/MediaLibrary`) - - Permission-Microphone (from `../node_modules/react-native-permissions/ios/Microphone`) - - Permission-Motion (from `../node_modules/react-native-permissions/ios/Motion`) - - Permission-Notifications (from `../node_modules/react-native-permissions/ios/Notifications`) - - Permission-PhotoLibrary (from `../node_modules/react-native-permissions/ios/PhotoLibrary`) - - Permission-PhotoLibraryAddOnly (from `../node_modules/react-native-permissions/ios/PhotoLibraryAddOnly`) - - Permission-Reminders (from `../node_modules/react-native-permissions/ios/Reminders`) - - Permission-SpeechRecognition (from `../node_modules/react-native-permissions/ios/SpeechRecognition`) - - Permission-StoreKit (from `../node_modules/react-native-permissions/ios/StoreKit`) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) @@ -577,42 +523,6 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" - Permission-AppTrackingTransparency: - :path: "../node_modules/react-native-permissions/ios/AppTrackingTransparency" - Permission-BluetoothPeripheral: - :path: "../node_modules/react-native-permissions/ios/BluetoothPeripheral" - Permission-Calendars: - :path: "../node_modules/react-native-permissions/ios/Calendars" - Permission-Camera: - :path: "../node_modules/react-native-permissions/ios/Camera" - Permission-Contacts: - :path: "../node_modules/react-native-permissions/ios/Contacts" - Permission-FaceID: - :path: "../node_modules/react-native-permissions/ios/FaceID" - Permission-LocationAccuracy: - :path: "../node_modules/react-native-permissions/ios/LocationAccuracy" - Permission-LocationAlways: - :path: "../node_modules/react-native-permissions/ios/LocationAlways" - Permission-LocationWhenInUse: - :path: "../node_modules/react-native-permissions/ios/LocationWhenInUse" - Permission-MediaLibrary: - :path: "../node_modules/react-native-permissions/ios/MediaLibrary" - Permission-Microphone: - :path: "../node_modules/react-native-permissions/ios/Microphone" - Permission-Motion: - :path: "../node_modules/react-native-permissions/ios/Motion" - Permission-Notifications: - :path: "../node_modules/react-native-permissions/ios/Notifications" - Permission-PhotoLibrary: - :path: "../node_modules/react-native-permissions/ios/PhotoLibrary" - Permission-PhotoLibraryAddOnly: - :path: "../node_modules/react-native-permissions/ios/PhotoLibraryAddOnly" - Permission-Reminders: - :path: "../node_modules/react-native-permissions/ios/Reminders" - Permission-SpeechRecognition: - :path: "../node_modules/react-native-permissions/ios/SpeechRecognition" - Permission-StoreKit: - :path: "../node_modules/react-native-permissions/ios/StoreKit" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -696,24 +606,6 @@ SPEC CHECKSUMS: hermes-engine: 38bfe887e456b33b697187570a08de33969f5db7 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c - Permission-AppTrackingTransparency: 9eedbc3b5a2907b8cb2c971461754616eac1661d - Permission-BluetoothPeripheral: 67708853584bb9208c76d36d0e0ea4eafb97ea5b - Permission-Calendars: dd55f36958c398a487f141d4c89119907e34dca8 - Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6 - Permission-Contacts: 2484d274171688b1ca80978b949ac771259b51f0 - Permission-FaceID: e70223280292a1a5e4b8ad943b70cd9229a7d2c3 - Permission-LocationAccuracy: 76df17de5c6b8bc2eee34e61ee92cdd7a864c73d - Permission-LocationAlways: 8d99b025c9f73c696e0cdb367e42525f2e9a26f2 - Permission-LocationWhenInUse: 3ba99e45c852763f730eabecec2870c2382b7bd4 - Permission-MediaLibrary: a994236bae41b3597a376ff08298fb1c6d84729b - Permission-Microphone: 48212dd4d28025d9930d583e3c7a56da7268665c - Permission-Motion: d3e5ac6c989b2594a3c5c5ab19ffe9453fa3eb5c - Permission-Notifications: 150484ae586eb9be4e32217582a78350a9bb31c3 - Permission-PhotoLibrary: 5b34ca67279f7201ae109cef36f9806a6596002d - Permission-PhotoLibraryAddOnly: 6dba8924024e239af2e282daa8a88967679b4983 - Permission-Reminders: dd6692dab69ae8a4e2473860e25b6304f9bcd326 - Permission-SpeechRecognition: 7bda51c7a3b68f259a98436ed431afdf84a19ecf - Permission-StoreKit: 7dcf43ad1b8cdc7ae21e547d49df9ac9b6ea7270 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 RCTRequired: bec48f07daf7bcdc2655a0cde84e07d24d2a9e2a RCTTypeSafety: 171394eebacf71e1cfad79dbfae7ee8fc16ca80a @@ -742,12 +634,12 @@ SPEC CHECKSUMS: React-RCTVibration: 5199a180d04873366a83855de55ac33ce60fe4d5 React-runtimeexecutor: 7bf0dafc7b727d93c8cb94eb00a9d3753c446c3e ReactCommon: 6f65ea5b7d84deb9e386f670dd11ce499ded7b40 - RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c + RNPermissions: 2874f8dbcfb95a6079a98e19dcc5767e086bc77d RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: 5ed1699acbba8863755998a4245daa200ff3817b YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 31bbb3fdb2c3b3bc787b7409362c73d1b56d9e38 +PODFILE CHECKSUM: 2de9221df73fac717714236687b9875bb50f8f18 COCOAPODS: 1.11.3 diff --git a/example/package.json b/example/package.json index e5ae4346..1f243149 100644 --- a/example/package.json +++ b/example/package.json @@ -7,10 +7,30 @@ "clean-modules": "rm -rf ./node_modules/react-native-permissions/{example,node_modules}", "clean": "rm -rf ./node_modules ./ios/Pods", "preinstall": "cd .. && yarn prepack && cd example", - "postinstall": "yarn clean-modules && pod-install", + "postinstall": "yarn clean-modules && react-native setup-ios-permissions && pod-install", "start": "react-native start", "reinstall": "yarn clean && yarn install" }, + "reactNativePermissionsIOS": [ + "AppTrackingTransparency", + "BluetoothPeripheral", + "Calendars", + "Camera", + "Contacts", + "FaceID", + "LocationAccuracy", + "LocationAlways", + "LocationWhenInUse", + "MediaLibrary", + "Microphone", + "Motion", + "Notifications", + "PhotoLibrary", + "PhotoLibraryAddOnly", + "Reminders", + "SpeechRecognition", + "StoreKit" + ], "dependencies": { "react": "18.2.0", "react-native": "0.71.3", diff --git a/example/yarn.lock b/example/yarn.lock index 9aad68c0..420c301d 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -1954,6 +1954,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2247,6 +2252,11 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ== +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -2533,6 +2543,16 @@ cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmiconfig@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" + integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -3273,6 +3293,14 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -3614,6 +3642,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsc-android@^250230.2.1: version "250230.2.1" resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250230.2.1.tgz#3790313a970586a03ab0ad47defbc84df54f1b83" @@ -3664,6 +3699,11 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json5@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -3717,6 +3757,11 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -4742,6 +4787,13 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -4750,6 +4802,16 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -4959,6 +5021,9 @@ react-native-paper@^5.2.0: react-native-permissions@../: version "3.6.1" + dependencies: + cosmiconfig "^8.0.0" + picocolors "^1.0.0" react-native-safe-area-context@^4.5.0: version "4.5.0" @@ -5201,6 +5266,11 @@ resolve-from@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" diff --git a/ios/RNPermissions.m b/ios/RNPermissions.m index ff7f80e8..4e5bf483 100644 --- a/ios/RNPermissions.m +++ b/ios/RNPermissions.m @@ -203,9 +203,8 @@ - (NSDictionary *)constantsToExport { NSMutableString *message = [NSMutableString new]; [message appendString:@"⚠ No permission handler detected.\n\n"]; - [message appendString:@"• Check that you link at least one permission handler in your Podfile.\n"]; - [message appendString:@"• Uninstall this app, delete your Xcode DerivedData folder and rebuild it.\n"]; - [message appendString:@"• If you use `use_frameworks!`, follow the workaround guide in the project README."]; + [message appendString:@"• Check that you added at least one permission handler in your package.json reactNativePermissionsIOS config.\n"]; + [message appendString:@"• Uninstall this app, reinstall your Pods, delete your Xcode DerivedData folder and rebuild it.\n"]; RCTLogError(@"%@", message); } diff --git a/package.json b/package.json index 3c24e2a4..619ee818 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-permissions", - "version": "3.6.1", + "version": "3.7.0", "license": "MIT", "description": "An unified permissions API for React Native on iOS, Android and Windows", "author": "Mathieu Acthernoene ", @@ -59,6 +59,10 @@ "optional": true } }, + "dependencies": { + "cosmiconfig": "^8.0.0", + "picocolors": "^1.0.0" + }, "devDependencies": { "@types/react-native": "^0.71.3", "@typescript-eslint/eslint-plugin": "^5.53.0", diff --git a/react-native.config.js b/react-native.config.js new file mode 100644 index 00000000..0f9f4cc7 --- /dev/null +++ b/react-native.config.js @@ -0,0 +1,66 @@ +const cosmiconfig = require('cosmiconfig'); +const fs = require('fs/promises'); +const path = require('path'); +const pc = require('picocolors'); + +const CONFIG_KEY = 'reactNativePermissionsIOS'; + +const log = { + error: (text) => console.log(pc.red(text)), + warning: (text) => console.log(pc.yellow(text)), +}; + +module.exports = { + commands: [ + { + name: 'setup-ios-permissions', + description: + 'Update react-native-permissions podspec to link additional permission handlers.', + func: async () => { + const explorer = await cosmiconfig(CONFIG_KEY); + const result = await explorer.search(); + + if (!result) { + log.error( + `No config detected. In order to setup iOS permissions, you first need to add an "${CONFIG_KEY}" array in your package.json.`, + ); + + process.exit(1); + } + + const {config} = result; + + if (!Array.isArray(config) || config.length === 0) { + log.error(`Invalid "${CONFIG_KEY}" config detected. It must be a non-empty array.`); + process.exit(1); + } + + const iosDirPath = path.join(__dirname, 'ios'); + const podspecPath = path.join(__dirname, 'RNPermissions.podspec'); + const iosDir = await fs.readdir(iosDirPath, {withFileTypes: true}); + const podspec = await fs.readFile(podspecPath, 'utf-8'); + + const directories = iosDir + .filter((dirent) => dirent.isDirectory() || dirent.name.endsWith('.xcodeproj')) + .map((dirent) => dirent.name) + .filter((name) => config.includes(name)); + + const unknownPermissions = config + .filter((name) => !directories.includes(name)) + .map((name) => `"${name}"`); + + if (unknownPermissions.length > 0) { + log.warning(`Unknown iOS permissions: ${unknownPermissions.join(', ')}`); + } + + const sourceFiles = [ + '"ios/*.{h,m,mm}"', + ...directories.map((name) => `"ios/${name}/*.{h,m,mm}"`), + ]; + + const podspecContent = podspec.replace(/"ios\/\*\.{h,m,mm}".*/, sourceFiles.join(', ')); + return fs.writeFile(podspecPath, podspecContent, 'utf-8'); + }, + }, + ], +}; diff --git a/yarn.lock b/yarn.lock index 001a3664..829c4c24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2391,6 +2391,16 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" + integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"