Skip to content

Commit

Permalink
[#75] iOS/macOS: Support bookmark:// schema in stat() and hash() func…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
Sergey Pogodin authored and Sergey Pogodin committed Oct 27, 2024
1 parent 5a0f285 commit bf8c977
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1493,8 +1493,14 @@ The type of result resolved by [stat()].
is a folder; _false_ otherwise.
- `isFile` — **() => boolean** — Evaluates _true_ if the item is
a file; _false_ otherwise.
- `mode` — **number** | **undefined** — UNIX file mode; _undefined_
on platforms that currnetly do not support it (Android).

- ~~`mode` — **number** | **undefined** — UNIX file mode;
_undefined_ on platforms that currnetly do not support it.~~

**NOTE**: In the library v2.29.0 the support of this field for iOS / macOS
(the only platforms that provided it before) was dropped; thus it is now
_undefined_ on all platforms.

- `mtime` — [Date] — Item's last modification date.
- `originalFilepath` — **string** — (Android-only) In case
of content uri this is the pointed file path, otherwise is the same as `path`.
Expand Down
6 changes: 4 additions & 2 deletions example/src/TestBaseMethods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,9 @@ const tests: { [name: string]: StatusOrEvaluator } = {
Platform.select({
android: undefined,
windows: undefined,
default: 493,

// TODO: At least temporary not supported on iOS/macOS
default: undefined, // 493,
}) ||
res.mtime.valueOf() < now - 1000 ||
res.mtime.valueOf() > now + 1000 ||
Expand Down Expand Up @@ -974,7 +976,7 @@ const tests: { [name: string]: StatusOrEvaluator } = {
res.mode !==
Platform.select({
android: undefined,
default: 420,
default: undefined, // 420,
windows: undefined,
}) ||
res.mtime.valueOf() < now - 1000 ||
Expand Down
39 changes: 25 additions & 14 deletions ios/ReactNativeFs.mm
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,27 @@ - (instancetype) init

@try {
NSError *error = nil;
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error];
NSDictionary *attributes = [url resourceValuesForKeys:@[
NSURLContentModificationDateKey,
NSURLCreationDateKey,
NSURLFileResourceTypeKey,
NSURLFileSizeKey,
] error:&error];

if (error) return [[RNFSException fromError:error] reject:reject];

NSValue *size = attributes[NSURLFileSizeKey];
if (size == nil) size = @64;

attributes = @{
@"ctime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileCreationDate]],
@"mtime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileModificationDate]],
@"size": [attributes objectForKey:NSFileSize],
@"type": [attributes objectForKey:NSFileType],
@"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue]),
@"ctime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSURLCreationDateKey]],
@"mtime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSURLContentModificationDateKey]],
@"size": size,
@"type": [attributes objectForKey:NSURLFileResourceTypeKey],

// TODO: So far I haven't found how to get POSIX permissions of a resource from NSURL object.
// @"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue]),

@"originalFilepath": @"NOT_SUPPORTED_ON_IOS"
};

Expand Down Expand Up @@ -430,23 +441,23 @@ - (instancetype) init
BOOL allowed = [url startAccessingSecurityScopedResource];

@try {
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filepath];
BOOL fileExists = [url checkResourceIsReachableAndReturnError:&error];

if (!fileExists) {
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: no such file or directory, open '%@'", filepath], nil);
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: no such file or directory, open '%@'", url.absoluteURL], nil);
}

NSError *error = nil;

NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error];

NSNumber *isDirectory;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error];
if (error) return [[RNFSException fromError:error] reject:reject];

if ([attributes objectForKey:NSFileType] == NSFileTypeDirectory) {
if (isDirectory.boolValue) {
return reject(@"EISDIR", @"EISDIR: illegal operation on a directory, read", nil);
}

NSData *content = [[NSFileManager defaultManager] contentsAtPath:filepath];
NSData *content = [NSData dataWithContentsOfURL:url];

NSArray *keys = [NSArray arrayWithObjects:@"md5", @"sha1", @"sha224", @"sha256", @"sha384", @"sha512", nil];

Expand Down Expand Up @@ -1067,8 +1078,8 @@ - (NSDictionary *)constantsToExport
@"ExternalStorageDirectoryPath": [NSNull null],
@"TemporaryDirectoryPath": NSTemporaryDirectory(),
@"LibraryDirectoryPath": [self getPathForDirectory:NSLibraryDirectory],
@"FileTypeRegular": NSFileTypeRegular,
@"FileTypeDirectory": NSFileTypeDirectory,
@"FileTypeRegular": NSURLFileResourceTypeRegular,
@"FileTypeDirectory": NSURLFileResourceTypeDirectory,
@"FileProtectionComplete": NSFileProtectionComplete,
@"FileProtectionCompleteUnlessOpen": NSFileProtectionCompleteUnlessOpen,
@"FileProtectionCompleteUntilFirstUserAuthentication": NSFileProtectionCompleteUntilFirstUserAuthentication,
Expand Down

0 comments on commit bf8c977

Please sign in to comment.