diff --git a/README.md b/README.md
index bfa66706..9cac3c6e 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,7 @@ _📌  Note that these commands must be re-executed each time you update this
"Camera",
"Contacts",
"FaceID",
+ "LocalNetworkPrivacy",
"LocationAccuracy",
"LocationAlways",
"LocationWhenInUse",
@@ -97,6 +98,8 @@ Then update your `Info.plist` with wanted permissions usage descriptions:
YOUR TEXT
NSFaceIDUsageDescription
YOUR TEXT
+ NSLocalNetworkUsageDescription
+ YOUR TEXT
NSLocationAlwaysAndWhenInUseUsageDescription
YOUR TEXT
NSLocationAlwaysUsageDescription
@@ -125,6 +128,13 @@ Then update your `Info.plist` with wanted permissions usage descriptions:
NSUserTrackingUsageDescription
YOUR TEXT
+
+
+ NSBonjourServices
+
+ _lnp._tcp.
+
+
@@ -488,6 +498,7 @@ PERMISSIONS.IOS.CALENDARS;
PERMISSIONS.IOS.CAMERA;
PERMISSIONS.IOS.CONTACTS;
PERMISSIONS.IOS.FACE_ID;
+PERMISSIONS.IOS.LOCAL_NETWORK_PRIVACY;
PERMISSIONS.IOS.LOCATION_ALWAYS;
PERMISSIONS.IOS.LOCATION_WHEN_IN_USE;
PERMISSIONS.IOS.MEDIA_LIBRARY;
diff --git a/example/ios/RNPermissionsExample/Info.plist b/example/ios/RNPermissionsExample/Info.plist
index ce57f966..bc76b70d 100644
--- a/example/ios/RNPermissionsExample/Info.plist
+++ b/example/ios/RNPermissionsExample/Info.plist
@@ -35,6 +35,10 @@
+ NSBonjourServices
+
+ _lnp._tcp.
+
NSAppleMusicUsageDescription
Let me use your media library
NSBluetoothAlwaysUsageDescription
@@ -49,6 +53,8 @@
Let me use your contacts
NSFaceIDUsageDescription
Let me use FaceID
+ NSLocalNetworkUsageDescription
+ Let me use your local network
NSLocationAlwaysAndWhenInUseUsageDescription
Let me use your location, even in background
NSLocationAlwaysUsageDescription
diff --git a/example/package.json b/example/package.json
index 45d05143..d3799d1f 100644
--- a/example/package.json
+++ b/example/package.json
@@ -17,6 +17,7 @@
"Camera",
"Contacts",
"FaceID",
+ "LocalNetworkPrivacy",
"LocationAccuracy",
"LocationAlways",
"LocationWhenInUse",
diff --git a/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.h b/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.h
new file mode 100644
index 00000000..3c0a8b24
--- /dev/null
+++ b/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.h
@@ -0,0 +1,5 @@
+@interface LocalNetworkPrivacy : NSObject
+
+- (void)checkAccessState:(void (^)(BOOL))completion;
+
+@end
diff --git a/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.m b/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.m
new file mode 100644
index 00000000..9ea9fa95
--- /dev/null
+++ b/ios/LocalNetworkPrivacy/LocalNetworkPrivacy.m
@@ -0,0 +1,47 @@
+#import
+#import "LocalNetworkPrivacy.h"
+
+@interface LocalNetworkPrivacy ()
+
+@property (nonatomic) NSNetService *service;
+@property (nonatomic) void (^completion)(BOOL);
+@property (nonatomic) NSTimer *timer;
+@property (nonatomic) BOOL publishing;
+
+@end
+
+@implementation LocalNetworkPrivacy
+
+- (instancetype)init {
+ if (self = [super init]) {
+ self.service = [[NSNetService alloc] initWithDomain:@"local." type:@"_lnp._tcp." name:@"LocalNetworkPrivacy" port:1100];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [self.service stop];
+}
+
+- (void)checkAccessState:(void (^)(BOOL))completion {
+ self.completion = completion;
+
+ self.publishing = YES;
+ self.service.delegate = self;
+ [self.service publish];
+
+ self.timer = [NSTimer scheduledTimerWithTimeInterval:2 repeats:NO block:^(NSTimer * _Nonnull timer) {
+ [self.timer invalidate];
+ self.completion(NO);
+ }];
+}
+
+
+#pragma mark - NSNetServiceDelegate
+
+- (void)netServiceDidPublish:(NSNetService *)sender {
+ [self.timer invalidate];
+ self.completion(YES);
+}
+
+@end
diff --git a/ios/LocalNetworkPrivacy/Permission-LocalNetworkPrivacy.podspec b/ios/LocalNetworkPrivacy/Permission-LocalNetworkPrivacy.podspec
new file mode 100644
index 00000000..52cefb09
--- /dev/null
+++ b/ios/LocalNetworkPrivacy/Permission-LocalNetworkPrivacy.podspec
@@ -0,0 +1,20 @@
+require 'json'
+package = JSON.parse(File.read('../../package.json'))
+
+Pod::Spec.new do |s|
+ s.name = "Permission-LocalNetworkPrivacy"
+ s.dependency "RNPermissions"
+
+ s.version = package["version"]
+ s.license = package["license"]
+ s.summary = package["description"]
+ s.authors = package["author"]
+ s.homepage = package["homepage"]
+
+ s.ios.deployment_target = "10.0"
+ s.tvos.deployment_target = "11.0"
+ s.requires_arc = true
+
+ s.source = { :git => package["repository"]["url"], :tag => s.version }
+ s.source_files = "*.{h,m}"
+end
diff --git a/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.h b/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.h
new file mode 100644
index 00000000..c25281db
--- /dev/null
+++ b/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.h
@@ -0,0 +1,5 @@
+#import "RNPermissions.h"
+
+@interface RNPermissionHandlerLocalNetworkPrivacy : NSObject
+
+@end
diff --git a/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.m b/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.m
new file mode 100644
index 00000000..0e69ab09
--- /dev/null
+++ b/ios/LocalNetworkPrivacy/RNPermissionHandlerLocalNetworkPrivacy.m
@@ -0,0 +1,33 @@
+#import "RNPermissionHandlerLocalNetworkPrivacy.h"
+#import "LocalNetworkPrivacy.h"
+
+@implementation RNPermissionHandlerLocalNetworkPrivacy
+
++ (NSArray * _Nonnull)usageDescriptionKeys {
+ return @[@"NSLocalNetworkUsageDescription"];
+}
+
++ (NSString * _Nonnull)handlerUniqueId {
+ return @"ios.permission.LOCAL_NETWORK_PRIVACY";
+}
+
+- (void)checkWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
+ rejecter:(void (__unused ^ _Nonnull)(NSError * _Nonnull))reject {
+ if (![RNPermissionsHelper isFlaggedAsRequested:[[self class] handlerUniqueId]]) {
+ return resolve(RNPermissionStatusNotDetermined);
+ }
+
+ [self requestWithResolver:resolve rejecter:reject];
+}
+
+- (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus))resolve
+ rejecter:(void (^ _Nonnull)(NSError * _Nonnull))reject {
+ [RNPermissionsHelper flagAsRequested:[[self class] handlerUniqueId]];
+
+ LocalNetworkPrivacy *local = [LocalNetworkPrivacy new];
+ [local checkAccessState:^(BOOL granted) {
+ resolve(granted ? RNPermissionStatusAuthorized : RNPermissionStatusDenied);
+ }];
+}
+
+@end
diff --git a/ios/RNPermissionsHelper.h b/ios/RNPermissionsHelper.h
index f45c3dcf..19340823 100644
--- a/ios/RNPermissionsHelper.h
+++ b/ios/RNPermissionsHelper.h
@@ -53,6 +53,9 @@ typedef NS_ENUM(NSInteger, RNPermission) {
#if __has_include("RNPermissionHandlerPhotoLibraryAddOnly.h")
RNPermissionPhotoLibraryAddOnly = 17,
#endif
+#if __has_include("RNPermissionHandlerLocalNetworkPrivacy.h")
+ RNPermissionLocalNetworkPrivacy = 18,
+#endif
};
typedef enum {
diff --git a/ios/RNPermissionsModule.mm b/ios/RNPermissionsModule.mm
index c5faea9b..53d75062 100644
--- a/ios/RNPermissionsModule.mm
+++ b/ios/RNPermissionsModule.mm
@@ -58,6 +58,9 @@
#if __has_include("RNPermissionHandlerLocationAccuracy.h")
#import "RNPermissionHandlerLocationAccuracy.h"
#endif
+#if __has_include("RNPermissionHandlerLocalNetworkPrivacy.h")
+#import "RNPermissionHandlerLocalNetworkPrivacy.h"
+#endif
@implementation RCTConvert(RNPermission)
@@ -113,6 +116,9 @@ @implementation RCTConvert(RNPermission)
#if __has_include("RNPermissionHandlerPhotoLibraryAddOnly.h")
[RNPermissionHandlerPhotoLibraryAddOnly handlerUniqueId]: @(RNPermissionPhotoLibraryAddOnly),
#endif
+#if __has_include("RNPermissionHandlerLocalNetworkPrivacy.h")
+ [RNPermissionHandlerLocalNetworkPrivacy handlerUniqueId]: @(RNPermissionLocalNetworkPrivacy),
+#endif
}), RNPermissionUnknown, integerValue);
@end
@@ -195,6 +201,9 @@ - (NSDictionary *)constantsToExport {
#if __has_include("RNPermissionHandlerLocationAccuracy.h")
[available addObject:[RNPermissionHandlerLocationAccuracy handlerUniqueId]];
#endif
+#if __has_include("RNPermissionHandlerLocalNetworkPrivacy.h")
+ [available addObject:[RNPermissionHandlerLocalNetworkPrivacy handlerUniqueId]];
+#endif
#if RCT_DEV
if ([available count] == 0) {
@@ -310,6 +319,11 @@ - (void)checkUsageDescriptionKeys:(NSArray * _Nonnull)keys {
case RNPermissionPhotoLibraryAddOnly:
handler = [RNPermissionHandlerPhotoLibraryAddOnly new];
break;
+#endif
+#if __has_include("RNPermissionHandlerLocalNetworkPrivacy.h")
+ case RNPermissionLocalNetworkPrivacy:
+ handler = [RNPermissionHandlerLocalNetworkPrivacy new];
+ break;
#endif
case RNPermissionUnknown:
break; // RCTConvert prevents this case
diff --git a/src/permissions.ios.ts b/src/permissions.ios.ts
index 87e6eb22..264bef72 100644
--- a/src/permissions.ios.ts
+++ b/src/permissions.ios.ts
@@ -8,6 +8,7 @@ const IOS = Object.freeze({
CAMERA: 'ios.permission.CAMERA',
CONTACTS: 'ios.permission.CONTACTS',
FACE_ID: 'ios.permission.FACE_ID',
+ LOCAL_NETWORK_PRIVACY: 'ios.permission.LOCAL_NETWORK_PRIVACY',
LOCATION_ALWAYS: 'ios.permission.LOCATION_ALWAYS',
LOCATION_WHEN_IN_USE: 'ios.permission.LOCATION_WHEN_IN_USE',
MEDIA_LIBRARY: 'ios.permission.MEDIA_LIBRARY',