Skip to content

Commit d7d0100

Browse files
fix: Fixed location permission handling on iOS
chore: Bumped version to 1.1.0
1 parent b9d03f1 commit d7d0100

File tree

7 files changed

+243
-33
lines changed

7 files changed

+243
-33
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// NPLocationManagerListener.h
3+
// Permissions Kit
4+
//
5+
// Created by Ayyappa on 03/04/25.
6+
// Copyright (c) 2025 Voxel Busters Interactive LLP. All rights reserved.
7+
8+
#import "NPConfig.h"
9+
10+
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
11+
#import <CoreLocation/CoreLocation.h>
12+
typedef void (^LocationAuthorizationStatusCallback) (CLAuthorizationStatus authStatus);
13+
14+
@interface NPLocationManagerListener : NSObject<CLLocationManagerDelegate>
15+
16+
-(NPLocationManagerListener*) init:(LocationAuthorizationStatusCallback) completion withInitialStatus:(CLAuthorizationStatus) initialStatus;
17+
18+
@end
19+
#endif

Assets/Plugins/VoxelBusters/PermissionsKit/Plugins/iOS/PermissionsKit/NPLocationManagerListener.h.meta

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// NPLocationManagerListener.mm
3+
// Permissions Kit
4+
//
5+
// Created by Ayyappa on 03/04/25.
6+
// Copyright (c) 2025 Voxel Busters Interactive LLP. All rights reserved.
7+
8+
#import "NPLocationManagerListener.h"
9+
10+
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
11+
#import <CoreLocation/CoreLocation.h>
12+
13+
@interface NPLocationManagerListener ()
14+
15+
@property (nonatomic, copy) LocationAuthorizationStatusCallback callback;
16+
@property (nonatomic) CLAuthorizationStatus initialStatus;
17+
18+
@end
19+
20+
@implementation NPLocationManagerListener
21+
22+
@synthesize callback;
23+
@synthesize initialStatus;
24+
25+
-(NPLocationManagerListener*) init:(LocationAuthorizationStatusCallback) callback withInitialStatus:(CLAuthorizationStatus) initialStatus
26+
{
27+
self.callback = callback;
28+
self.initialStatus = initialStatus;
29+
return self;
30+
}
31+
32+
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager
33+
{
34+
35+
CLAuthorizationStatus authStatus = [CLLocationManager authorizationStatus];
36+
37+
if(initialStatus != authStatus) {
38+
self.callback(authStatus);
39+
}
40+
}
41+
42+
@end
43+
#endif

Assets/Plugins/VoxelBusters/PermissionsKit/Plugins/iOS/PermissionsKit/NPLocationManagerListener.mm.meta

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Plugins/VoxelBusters/PermissionsKit/Plugins/iOS/PermissionsKit/NPPermissionsKit.mm

100755100644
Lines changed: 90 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#endif
1818
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
1919
#import <CoreLocation/CoreLocation.h>
20+
#import "NPLocationManagerListener.h"
2021
#endif
2122
#if PERMISSIONS_KIT_USES_NOTIFICATIONS_FRAMEWORK
2223
#import <UserNotifications/UserNotifications.h>
@@ -32,10 +33,20 @@
3233

3334
@interface NPPermissionsKit ()
3435

36+
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
37+
@property (nonatomic, strong) CLLocationManager *locationManager;
38+
@property (nonatomic, strong) NPLocationManagerListener *locationStatusListener;
39+
#endif
40+
3541
@end
3642

3743
@implementation NPPermissionsKit
3844

45+
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
46+
@synthesize locationManager;
47+
@synthesize locationStatusListener;
48+
#endif
49+
3950
-(NPPermissionsKit*) init
4051
{
4152

@@ -150,9 +161,24 @@ -(void) request:(NSArray<NPPermission*>*) permissions withPurposeDescription:(NS
150161

151162
} else
152163
#endif
153-
{
154-
completionHandler(permission, PermissionsKitStatusAuthorized, nil);
155-
}
164+
if ([permission equals:[NPPermission ACCESS_INTERNET]] ||
165+
[permission equals:[NPPermission ACCESS_WIFI_STATE]] ||
166+
[permission equals:[NPPermission VIBRATE]] ||
167+
[permission equals:[NPPermission IN_APP_PURCHASES]])
168+
{
169+
NSLog(@"No need of any request for this permission(%@)", permission);
170+
completionHandler(permission, PermissionsKitStatusAuthorized, nil);
171+
}
172+
else if ([permission equals:[NPPermission ACCESS_NETWORK_STATE]])
173+
{
174+
NSLog(@"TODO: Currently passing unknown for permission(%@)", permission);
175+
completionHandler(permission, PermissionsKitStatusUnknown, nil);
176+
}
177+
else
178+
{
179+
NSLog(@"Permission(%@) is not handled. This can be due to not enabling the permission in settings or report to this plugin developer with the permission name.", permission);
180+
completionHandler(permission, PermissionsKitStatusUnknown, nil);
181+
}
156182
}
157183
}
158184

@@ -161,36 +187,54 @@ -(void) request:(NSArray<NPPermission*>*) permissions withPurposeDescription:(NS
161187
- (void)requestLocationPermission:(BOOL)requestAlways
162188
completion:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
163189

164-
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
190+
self.locationManager = [[CLLocationManager alloc] init];
165191
CLAuthorizationStatus authStatus = [CLLocationManager authorizationStatus];
166192
PermissionsKitStatus status = PermissionsKitStatusUnknown;
167-
168-
if (authStatus == kCLAuthorizationStatusNotDetermined) {
169-
// First-time request
193+
194+
self.locationStatusListener = [[NPLocationManagerListener alloc] init:^(CLAuthorizationStatus authStatus) {
195+
PermissionsKitStatus newStatus = [self convertStatus:authStatus withRequestAlways:requestAlways];
196+
completion(newStatus, nil);
197+
self.locationManager = nil;
198+
self.locationStatusListener = nil;
199+
} withInitialStatus:authStatus];
200+
201+
status = [self convertStatus:authStatus withRequestAlways:requestAlways];
202+
203+
if(status == PermissionsKitStatusUnknown || (status == PermissionsKitStatusLimited && requestAlways)) {
204+
locationManager.delegate = self.locationStatusListener;
170205
if (requestAlways) {
171206
[locationManager requestAlwaysAuthorization];
172207
} else {
173208
[locationManager requestWhenInUseAuthorization];
174209
}
210+
} else {
211+
self.locationManager = nil;
212+
completion(status, nil);
213+
}
214+
}
215+
216+
-(PermissionsKitStatus) convertStatus:(CLAuthorizationStatus) authStatus withRequestAlways:(BOOL) requestAlways
217+
{
218+
PermissionsKitStatus status;
219+
if (authStatus == kCLAuthorizationStatusNotDetermined) {
175220
status = PermissionsKitStatusUnknown;
176221
} else if (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {
177222
status = requestAlways ? PermissionsKitStatusLimited : PermissionsKitStatusAuthorized;
178-
if (requestAlways) {
179-
[locationManager requestAlwaysAuthorization];
180-
}
181223
} else if (authStatus == kCLAuthorizationStatusAuthorizedAlways) {
182224
status = PermissionsKitStatusAuthorized;
183225
} else if (authStatus == kCLAuthorizationStatusDenied) {
184226
status = PermissionsKitStatusDenied;
185227
} else {
186228
status = PermissionsKitStatusRestricted;
187229
}
188-
189-
completion(status, nil);
230+
231+
return status;
190232
}
233+
234+
191235
#endif
192236

193-
#if PERMISSIONS_KIT_USES_LOCATION_FRAMEWORK
237+
#if PERMISSIONS_KIT_USES_NOTIFICATIONS_FRAMEWORK
194238
- (void)requestPushNotificationPermission:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
195239
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
196240
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
@@ -201,19 +245,24 @@ - (void)requestPushNotificationPermission:(void (^)(PermissionsKitStatus status,
201245
#endif
202246

203247
#if PERMISSIONS_KIT_USES_AVFOUNDATION_FRAMEWORK
204-
- (void)requestCameraPermission:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
205-
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
206-
207-
PermissionsKitStatus status = PermissionsKitStatusUnknown;
208-
if (authStatus == AVAuthorizationStatusAuthorized) {
209-
status = PermissionsKitStatusAuthorized;
210-
} else if (authStatus == AVAuthorizationStatusDenied) {
211-
status = PermissionsKitStatusDenied;
212-
} else if (authStatus == AVAuthorizationStatusRestricted) {
213-
status = PermissionsKitStatusRestricted;
214-
}
215-
216-
completion(status, nil);
248+
- (void)requestCameraPermission:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
249+
250+
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
251+
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
252+
253+
PermissionsKitStatus status = PermissionsKitStatusUnknown;
254+
if (authStatus == AVAuthorizationStatusAuthorized) {
255+
status = PermissionsKitStatusAuthorized;
256+
} else if (authStatus == AVAuthorizationStatusDenied) {
257+
status = PermissionsKitStatusDenied;
258+
} else if (authStatus == AVAuthorizationStatusRestricted) {
259+
status = PermissionsKitStatusRestricted;
260+
}
261+
262+
// send callback
263+
completion(status, nil);
264+
}];
265+
217266
}
218267

219268
- (void)requestMicrophonePermission:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
@@ -224,23 +273,32 @@ - (void)requestMicrophonePermission:(void (^)(PermissionsKitStatus status, NSErr
224273
#endif
225274

226275
#if PERMISSIONS_KIT_USES_PHOTOS_FRAMEWORK
227-
- (void) requestPhotoLibraryPermission:(PHAccessLevel) accessLevel withCallback:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {
228-
[PHPhotoLibrary requestAuthorizationForAccessLevel:accessLevel handler:^(PHAuthorizationStatus authStatus) {
276+
- (void) requestPhotoLibraryPermission:(PHAccessLevel) accessLevel withCallback:(void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion API_AVAILABLE(ios(14)){
277+
278+
void (^handler)(PHAuthorizationStatus status) = ^(PHAuthorizationStatus authStatus) {
229279
PermissionsKitStatus status = PermissionsKitStatusUnknown;
230280
if (authStatus == PHAuthorizationStatusAuthorized) {
231281
status = PermissionsKitStatusAuthorized;
232282
} else if (authStatus == PHAuthorizationStatusDenied) {
233283
status = PermissionsKitStatusDenied;
234284
} else if (authStatus == PHAuthorizationStatusRestricted) {
235285
status = PermissionsKitStatusRestricted;
236-
} else if (@available(iOS 14, *)) {
237-
if (authStatus == PHAuthorizationStatusLimited) {
286+
} else if (authStatus == PHAuthorizationStatusLimited) {
238287
status = PermissionsKitStatusLimited;
239-
}
288+
} else {
289+
NSLog(@"PHAuthorizationStatus not handled %ld", authStatus);
240290
}
241291

242292
completion(status, nil);
243-
}];
293+
};
294+
295+
296+
if (@available(iOS 14, *)) {
297+
[PHPhotoLibrary requestAuthorizationForAccessLevel:accessLevel handler:handler];
298+
} else {
299+
// Fallback on earlier versions
300+
[PHPhotoLibrary requestAuthorization:handler];
301+
}
244302
}
245303

246304
- (void) requestWriteToPhotoLibraryPermission: (void (^)(PermissionsKitStatus status, NSError * _Nullable error))completion {

Assets/Plugins/VoxelBusters/PermissionsKit/Runtime/Core/Setup/PermissionsKitSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class PermissionsKitSettings : SettingsObject
4747
{
4848
return new UnityPackageDefinition(name: "com.voxelbusters.permissionskit",
4949
displayName: "Permissions Kit",
50-
version: "1.0.2",
50+
version: "1.1.0",
5151
defaultInstallPath: $"Assets/Plugins/VoxelBusters/PermissionsKit",
5252
dependencies: CoreLibrarySettings.Package);
5353
});
1.07 MB
Binary file not shown.

0 commit comments

Comments
 (0)