Piotr Witkoś
Piotr Witkoś

Reputation: 394

Objective-C NSFileManager works fine on simulator but Operation not permitted error Domain=NSCocoaErrorDomain Code=257 on device when check file size

I need to check size with Objective-C of external file which is shared to my react native app.

I got url which works fine without getting file attributes:

file:///private/var/mobile/Containers/Shared/AppGroup/61894F8B-0001-40C2-856E-F30D4663F7A7/File%20Provider%20Storage/Instrukcja_Welcome_to.pdf

and

NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:url.relativePath error:&error];
NSNumber *fileSize = fileAttributes[NSFileSize];

works perfectly on simulator but when I use physical device I got error:

Error Domain=NSCocoaErrorDomain Code=257 "The file “Instrukcja_Welcome_to.pdf” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/61894F8B-0001-40C2-856E-F30D4663F7A7/File Provider Storage/Instrukcja_Welcome_to.pdf, NSUnderlyingError=0x280eeb240 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

I tried:

  NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
  [fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:&error byAccessor:^(NSURL *newURL) {
      fileAccessGranted = YES;
  }];

and added

<key>NSFileUsageDescription</key>
<string>This app requires access to files.</string>

to info.plist

Upvotes: 0

Views: 153

Answers (1)

Piotr Witkoś
Piotr Witkoś

Reputation: 394

The solution turned out to be quite simple:

NSURL *url = = [NSURL fileURLWithPath:@"/private/var/mobile/Containers/Shared/AppGroup/61894F8B-0001-40C2-856E-F30D4663F7A7/File Provider Storage/Downloads/Instrukcja_Welcome_to.pdf"];
BOOL isAccessGranted = [url startAccessingSecurityScopedResource]; 
if (isAccessGranted) {
    NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:url.relativePath error:&error];
    NSNumber *fileSize = fileAttributes[NSFileSize];
}
[url stopAccessingSecurityScopedResource];

The key thing is to use startAccessingSecurityScopedResource method on NSURL *url before using file and after finishing to use stopAccessingSecurityScopedResource

Upvotes: 1

Related Questions