@onekeyfe/react-native-cloud-fs 2.6.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CloudFs.podspec +19 -0
- package/android/build.gradle +64 -42
- package/android/src/main/java/com/rncloudfs/RNCloudFsModule.kt +50 -0
- package/android/src/main/java/com/rncloudfs/RNCloudFsPackage.kt +33 -0
- package/ios/CloudFs.h +7 -0
- package/ios/{RNCloudFs.m → CloudFs.mm} +174 -225
- package/lib/module/NativeCloudFs.js +5 -0
- package/lib/module/NativeCloudFs.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeCloudFs.d.ts +14 -0
- package/lib/typescript/src/NativeCloudFs.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +80 -7
- package/src/NativeCloudFs.ts +15 -0
- package/src/index.tsx +4 -0
- package/.github/workflows/package-publish.yml +0 -19
- package/README.md +0 -146
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
- package/android/gradle.properties +0 -16
- package/android/gradlew +0 -160
- package/android/gradlew.bat +0 -90
- package/android/src/main/AndroidManifest.xml +0 -6
- package/android/src/main/java/org/rncloudfs/DriveServiceHelper.java +0 -214
- package/android/src/main/java/org/rncloudfs/RNCloudFsModule.java +0 -511
- package/android/src/main/java/org/rncloudfs/RNCloudFsPackage.java +0 -28
- package/docs/getting-started.md +0 -61
- package/docs/todo.md +0 -34
- package/docs/xcode.png +0 -0
- package/index.js +0 -7
- package/ios/RNCloudFs.h +0 -10
- package/ios/RNCloudFs.xcodeproj/project.pbxproj +0 -252
- package/ios/RNCloudFs.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/licesnse.txt +0 -21
- package/react-native-cloud-fs.podspec +0 -17
|
@@ -1,43 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
#import "RNCloudFs.h"
|
|
1
|
+
#import "CloudFs.h"
|
|
3
2
|
#import <UIKit/UIKit.h>
|
|
4
|
-
#if __has_include(<React/RCTBridgeModule.h>)
|
|
5
|
-
#import <React/RCTBridgeModule.h>
|
|
6
|
-
#else
|
|
7
|
-
#import "RCTBridgeModule.h"
|
|
8
|
-
#endif
|
|
9
|
-
#import "RCTEventDispatcher.h"
|
|
10
|
-
#import "RCTUtils.h"
|
|
11
3
|
#import <AssetsLibrary/AssetsLibrary.h>
|
|
12
|
-
#import "RCTLog.h"
|
|
13
4
|
|
|
14
|
-
@implementation
|
|
5
|
+
@implementation CloudFs
|
|
15
6
|
|
|
7
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
8
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
9
|
+
{
|
|
10
|
+
return std::make_shared<facebook::react::NativeRNCloudFsSpecJSI>(params);
|
|
11
|
+
}
|
|
16
12
|
|
|
13
|
+
+ (NSString *)moduleName
|
|
14
|
+
{
|
|
15
|
+
return @"RNCloudFs";
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
+ (BOOL)requiresMainQueueSetup
|
|
19
19
|
{
|
|
20
|
-
return
|
|
20
|
+
return NO;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- (dispatch_queue_t)methodQueue
|
|
24
|
+
{
|
|
25
|
+
return dispatch_queue_create("com.onekey.CloudFs.queue", DISPATCH_QUEUE_SERIAL);
|
|
26
|
+
}
|
|
24
27
|
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
RCT_EXPORT_METHOD(isAvailable:(RCTPromiseResolveBlock)resolve
|
|
28
|
-
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
28
|
+
// MARK: - isAvailable
|
|
29
29
|
|
|
30
|
+
- (void)isAvailable:(RCTPromiseResolveBlock)resolve
|
|
31
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
32
|
+
{
|
|
30
33
|
NSURL *ubiquityURL = [self icloudDirectory];
|
|
31
|
-
if(ubiquityURL != nil){
|
|
34
|
+
if (ubiquityURL != nil) {
|
|
32
35
|
return resolve(@YES);
|
|
33
36
|
}
|
|
34
37
|
return resolve(@NO);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
39
|
-
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
40
|
+
// MARK: - createFile
|
|
40
41
|
|
|
42
|
+
- (void)createFile:(NSDictionary *)options
|
|
43
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
44
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
45
|
+
{
|
|
41
46
|
NSString *destinationPath = [options objectForKey:@"targetPath"];
|
|
42
47
|
NSString *content = [options objectForKey:@"content"];
|
|
43
48
|
NSString *scope = [options objectForKey:@"scope"];
|
|
@@ -47,58 +52,55 @@ RCT_EXPORT_METHOD(createFile:(NSDictionary *) options
|
|
|
47
52
|
|
|
48
53
|
NSError *error;
|
|
49
54
|
[content writeToFile:tempFile atomically:YES encoding:NSUTF8StringEncoding error:&error];
|
|
50
|
-
if(error) {
|
|
55
|
+
if (error) {
|
|
51
56
|
return reject(@"error", error.description, nil);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
[self moveToICloudDirectory:documentsFolder :tempFile :destinationPath :resolve :reject];
|
|
59
|
+
[self moveToICloudDirectory:documentsFolder tempFile:tempFile destinationPath:destinationPath resolve:resolve reject:reject];
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
59
|
-
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
62
|
+
// MARK: - fileExists
|
|
60
63
|
|
|
64
|
+
- (void)fileExists:(NSDictionary *)options
|
|
65
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
66
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
67
|
+
{
|
|
61
68
|
NSString *destinationPath = [options objectForKey:@"targetPath"];
|
|
62
69
|
NSString *scope = [options objectForKey:@"scope"];
|
|
63
70
|
bool documentsFolder = !scope || [scope caseInsensitiveCompare:@"visible"] == NSOrderedSame;
|
|
64
71
|
|
|
65
|
-
NSFileManager*
|
|
66
|
-
|
|
72
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
67
73
|
NSURL *ubiquityURL = documentsFolder ? [self icloudDocumentsDirectory] : [self icloudDirectory];
|
|
68
74
|
|
|
69
75
|
if (ubiquityURL) {
|
|
70
|
-
NSURL*
|
|
71
|
-
NSString*
|
|
72
|
-
|
|
76
|
+
NSURL *dir = [ubiquityURL URLByAppendingPathComponent:destinationPath];
|
|
77
|
+
NSString *dirPath = [dir.path stringByStandardizingPath];
|
|
73
78
|
bool exists = [fileManager fileExistsAtPath:dirPath];
|
|
74
|
-
|
|
75
79
|
return resolve(@(exists));
|
|
76
80
|
} else {
|
|
77
|
-
|
|
78
|
-
return reject(@"error", [NSString stringWithFormat:@"could access iCloud drive '%@'", destinationPath], nil);
|
|
81
|
+
return reject(@"error", [NSString stringWithFormat:@"could not access iCloud drive '%@'", destinationPath], nil);
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
84
|
-
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
85
|
+
// MARK: - listFiles
|
|
85
86
|
|
|
87
|
+
- (void)listFiles:(NSDictionary *)options
|
|
88
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
89
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
90
|
+
{
|
|
86
91
|
NSString *destinationPath = [options objectForKey:@"targetPath"];
|
|
87
92
|
NSString *scope = [options objectForKey:@"scope"];
|
|
88
93
|
bool documentsFolder = !scope || [scope caseInsensitiveCompare:@"visible"] == NSOrderedSame;
|
|
89
94
|
|
|
90
|
-
NSFileManager*
|
|
91
|
-
|
|
95
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
92
96
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
|
93
97
|
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
|
|
94
98
|
|
|
95
99
|
NSURL *ubiquityURL = documentsFolder ? [self icloudDocumentsDirectory] : [self icloudDirectory];
|
|
96
100
|
|
|
97
101
|
if (ubiquityURL) {
|
|
98
|
-
NSURL*
|
|
99
|
-
|
|
102
|
+
NSURL *target = [ubiquityURL URLByAppendingPathComponent:destinationPath];
|
|
100
103
|
NSMutableArray<NSDictionary *> *fileData = [NSMutableArray new];
|
|
101
|
-
|
|
102
104
|
NSError *error = nil;
|
|
103
105
|
|
|
104
106
|
BOOL isDirectory;
|
|
@@ -106,7 +108,7 @@ RCT_EXPORT_METHOD(listFiles:(NSDictionary *)options
|
|
|
106
108
|
|
|
107
109
|
NSURL *dirPath;
|
|
108
110
|
NSArray *contents;
|
|
109
|
-
if(isDirectory) {
|
|
111
|
+
if (isDirectory) {
|
|
110
112
|
contents = [fileManager contentsOfDirectoryAtPath:[target path] error:&error];
|
|
111
113
|
dirPath = target;
|
|
112
114
|
} else {
|
|
@@ -114,163 +116,143 @@ RCT_EXPORT_METHOD(listFiles:(NSDictionary *)options
|
|
|
114
116
|
dirPath = [target URLByDeletingLastPathComponent];
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
if(error) {
|
|
119
|
+
if (error) {
|
|
118
120
|
return reject(@"error", error.description, nil);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
[contents enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
|
|
122
124
|
NSURL *fileUrl = [dirPath URLByAppendingPathComponent:object];
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if(error) {
|
|
127
|
-
RCTLogTrace(@"problem getting attributes for %@", [fileUrl path]);
|
|
128
|
-
//skip this one
|
|
125
|
+
NSError *attrError;
|
|
126
|
+
NSDictionary *attributes = [fileManager attributesOfItemAtPath:[fileUrl path] error:&attrError];
|
|
127
|
+
if (attrError) {
|
|
129
128
|
return;
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
NSFileAttributeType type = [attributes objectForKey:NSFileType];
|
|
133
|
-
|
|
134
132
|
bool isDir = type == NSFileTypeDirectory;
|
|
135
133
|
bool isFile = type == NSFileTypeRegular;
|
|
136
134
|
|
|
137
|
-
if(!isDir && !isFile)
|
|
138
|
-
return;
|
|
139
|
-
|
|
140
|
-
NSDate* modDate = [attributes objectForKey:NSFileModificationDate];
|
|
135
|
+
if (!isDir && !isFile) return;
|
|
141
136
|
|
|
142
|
-
|
|
137
|
+
NSDate *modDate = [attributes objectForKey:NSFileModificationDate];
|
|
138
|
+
NSError *shareError;
|
|
139
|
+
NSURL *shareUrl = [fileManager URLForPublishingUbiquitousItemAtURL:fileUrl expirationDate:nil error:&shareError];
|
|
143
140
|
|
|
144
141
|
[fileData addObject:@{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
142
|
+
@"name": object,
|
|
143
|
+
@"path": [fileUrl path],
|
|
144
|
+
@"uri": shareUrl ? [shareUrl absoluteString] : [NSNull null],
|
|
145
|
+
@"size": [attributes objectForKey:NSFileSize],
|
|
146
|
+
@"lastModified": [dateFormatter stringFromDate:modDate],
|
|
147
|
+
@"isDirectory": @(isDir),
|
|
148
|
+
@"isFile": @(isFile)
|
|
149
|
+
}];
|
|
153
150
|
}];
|
|
154
151
|
|
|
155
|
-
if (error) {
|
|
156
|
-
return reject(@"error", [NSString stringWithFormat:@"could not copy to iCloud drive '%@'", destinationPath], error);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
152
|
NSString *relativePath = [[dirPath path] stringByReplacingOccurrencesOfString:[ubiquityURL path] withString:@"."];
|
|
160
153
|
|
|
161
154
|
return resolve(@{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
155
|
+
@"files": fileData,
|
|
156
|
+
@"path": relativePath
|
|
157
|
+
});
|
|
166
158
|
} else {
|
|
167
|
-
|
|
168
|
-
return reject(@"error", [NSString stringWithFormat:@"could not copy to iCloud drive '%@'", destinationPath], nil);
|
|
159
|
+
return reject(@"error", [NSString stringWithFormat:@"could not list iCloud drive '%@'", destinationPath], nil);
|
|
169
160
|
}
|
|
170
161
|
}
|
|
171
162
|
|
|
163
|
+
// MARK: - getIcloudDocument
|
|
172
164
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
165
|
+
- (void)getIcloudDocument:(NSString *)filename
|
|
166
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
167
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
168
|
+
{
|
|
176
169
|
__block bool resolved = NO;
|
|
177
170
|
_query = [[NSMetadataQuery alloc] init];
|
|
178
|
-
|
|
179
171
|
[_query setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope]];
|
|
180
172
|
|
|
181
|
-
NSPredicate *pred = [NSPredicate predicateWithFormat
|
|
173
|
+
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@", NSMetadataItemFSNameKey, filename];
|
|
182
174
|
[_query setPredicate:pred];
|
|
183
|
-
|
|
184
175
|
|
|
185
|
-
[[NSNotificationCenter defaultCenter] addObserverForName:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
{
|
|
176
|
+
[[NSNotificationCenter defaultCenter] addObserverForName:NSMetadataQueryDidFinishGatheringNotification
|
|
177
|
+
object:_query
|
|
178
|
+
queue:[NSOperationQueue currentQueue]
|
|
179
|
+
usingBlock:^(NSNotification __strong *notification) {
|
|
190
180
|
NSMetadataQuery *query = [notification object];
|
|
191
181
|
[query disableUpdates];
|
|
192
182
|
[query stopQuery];
|
|
193
183
|
for (NSMetadataItem *item in query.results) {
|
|
194
|
-
if([[item valueForAttribute:NSMetadataItemFSNameKey] isEqualToString:filename]){
|
|
184
|
+
if ([[item valueForAttribute:NSMetadataItemFSNameKey] isEqualToString:filename]) {
|
|
195
185
|
resolved = YES;
|
|
196
186
|
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
|
|
197
|
-
bool fileIsReady = [self downloadFileIfNotAvailable:
|
|
198
|
-
if(fileIsReady){
|
|
199
|
-
NSData *data = [NSData dataWithContentsOfURL:
|
|
187
|
+
bool fileIsReady = [self downloadFileIfNotAvailable:item];
|
|
188
|
+
if (fileIsReady) {
|
|
189
|
+
NSData *data = [NSData dataWithContentsOfURL:url];
|
|
200
190
|
NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
201
|
-
return
|
|
191
|
+
return resolve(content);
|
|
202
192
|
} else {
|
|
203
|
-
|
|
204
|
-
[self getIcloudDocument:filename resolver:resolver rejecter:rejecter];
|
|
193
|
+
[self getIcloudDocument:filename resolve:resolve reject:reject];
|
|
205
194
|
}
|
|
206
195
|
}
|
|
207
196
|
}
|
|
208
|
-
if(!resolved){
|
|
209
|
-
return
|
|
197
|
+
if (!resolved) {
|
|
198
|
+
return reject(@"error", [NSString stringWithFormat:@"item not found '%@'", filename], nil);
|
|
210
199
|
}
|
|
211
200
|
}];
|
|
212
201
|
|
|
213
202
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
214
203
|
[self->_query startQuery];
|
|
215
204
|
});
|
|
216
|
-
|
|
217
205
|
}
|
|
218
206
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
207
|
+
// MARK: - deleteFromCloud
|
|
208
|
+
|
|
209
|
+
- (void)deleteFromCloud:(NSDictionary *)item
|
|
210
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
211
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
212
|
+
{
|
|
213
|
+
NSError *error;
|
|
214
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
225
215
|
[fileManager removeItemAtPath:item[@"path"] error:&error];
|
|
226
|
-
if(error) {
|
|
227
|
-
return
|
|
216
|
+
if (error) {
|
|
217
|
+
return reject(@"error", error.description, nil);
|
|
228
218
|
}
|
|
229
|
-
|
|
230
|
-
return resolver(@(result));
|
|
231
|
-
|
|
219
|
+
return resolve(@YES);
|
|
232
220
|
}
|
|
233
221
|
|
|
222
|
+
// MARK: - copyToCloud
|
|
234
223
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// mimeType is ignored for iOS
|
|
224
|
+
- (void)copyToCloud:(NSDictionary *)options
|
|
225
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
226
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
227
|
+
{
|
|
240
228
|
NSDictionary *source = [options objectForKey:@"sourcePath"];
|
|
241
229
|
NSString *destinationPath = [options objectForKey:@"targetPath"];
|
|
242
230
|
NSString *scope = [options objectForKey:@"scope"];
|
|
243
231
|
bool documentsFolder = !scope || [scope caseInsensitiveCompare:@"visible"] == NSOrderedSame;
|
|
244
232
|
|
|
245
|
-
NSFileManager*
|
|
233
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
246
234
|
|
|
247
235
|
NSString *sourceUri = [source objectForKey:@"uri"];
|
|
248
|
-
if(!sourceUri) {
|
|
236
|
+
if (!sourceUri) {
|
|
249
237
|
sourceUri = [source objectForKey:@"path"];
|
|
250
238
|
}
|
|
251
239
|
|
|
252
|
-
if([sourceUri hasPrefix:@"assets-library"]){
|
|
240
|
+
if ([sourceUri hasPrefix:@"assets-library"]) {
|
|
253
241
|
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
|
|
254
|
-
|
|
255
242
|
[library assetForURL:[NSURL URLWithString:sourceUri] resultBlock:^(ALAsset *asset) {
|
|
256
|
-
|
|
257
243
|
ALAssetRepresentation *rep = [asset defaultRepresentation];
|
|
258
|
-
|
|
259
|
-
Byte *buffer = (Byte*)malloc(rep.size);
|
|
244
|
+
Byte *buffer = (Byte *)malloc(rep.size);
|
|
260
245
|
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
|
|
261
246
|
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
|
|
262
|
-
|
|
263
247
|
if (data) {
|
|
264
248
|
NSString *filename = [sourceUri lastPathComponent];
|
|
265
249
|
NSString *tempFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
|
|
266
250
|
[data writeToFile:tempFile atomically:YES];
|
|
267
|
-
[self moveToICloudDirectory:documentsFolder :tempFile :destinationPath :resolve :reject];
|
|
251
|
+
[self moveToICloudDirectory:documentsFolder tempFile:tempFile destinationPath:destinationPath resolve:resolve reject:reject];
|
|
268
252
|
} else {
|
|
269
|
-
RCTLogTrace(@"source file does not exist %@", sourceUri);
|
|
270
253
|
return reject(@"error", [NSString stringWithFormat:@"failed to copy asset '%@'", sourceUri], nil);
|
|
271
254
|
}
|
|
272
255
|
} failureBlock:^(NSError *error) {
|
|
273
|
-
RCTLogTrace(@"source file does not exist %@", sourceUri);
|
|
274
256
|
return reject(@"error", error.description, nil);
|
|
275
257
|
}];
|
|
276
258
|
} else if ([sourceUri hasPrefix:@"file:/"] || [sourceUri hasPrefix:@"/"]) {
|
|
@@ -279,189 +261,156 @@ RCT_EXPORT_METHOD(copyToCloud:(NSDictionary *)options
|
|
|
279
261
|
|
|
280
262
|
if ([fileManager fileExistsAtPath:modifiedSourceUri isDirectory:nil]) {
|
|
281
263
|
NSURL *sourceURL = [NSURL fileURLWithPath:modifiedSourceUri];
|
|
282
|
-
|
|
283
|
-
// todo: figure out how to *copy* to icloud drive
|
|
284
|
-
// ...setUbiquitous will move the file instead of copying it, so as a work around lets copy it to a tmp file first
|
|
285
264
|
NSString *filename = [sourceUri lastPathComponent];
|
|
286
265
|
NSString *tempFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
|
|
287
266
|
|
|
288
267
|
NSError *error;
|
|
289
|
-
if([fileManager fileExistsAtPath:tempFile]){
|
|
268
|
+
if ([fileManager fileExistsAtPath:tempFile]) {
|
|
290
269
|
[fileManager removeItemAtPath:tempFile error:&error];
|
|
291
|
-
if(error) {
|
|
270
|
+
if (error) {
|
|
292
271
|
return reject(@"error", error.description, nil);
|
|
293
272
|
}
|
|
294
273
|
}
|
|
295
274
|
|
|
296
275
|
[fileManager copyItemAtPath:[sourceURL path] toPath:tempFile error:&error];
|
|
297
|
-
if(error) {
|
|
276
|
+
if (error) {
|
|
298
277
|
return reject(@"error", error.description, nil);
|
|
299
278
|
}
|
|
300
279
|
|
|
301
|
-
[self moveToICloudDirectory:documentsFolder :tempFile :destinationPath :resolve :reject];
|
|
280
|
+
[self moveToICloudDirectory:documentsFolder tempFile:tempFile destinationPath:destinationPath resolve:resolve reject:reject];
|
|
302
281
|
} else {
|
|
303
|
-
NSLog(@"source file does not exist %@", sourceUri);
|
|
304
282
|
return reject(@"error", [NSString stringWithFormat:@"no such file or directory, open '%@'", sourceUri], nil);
|
|
305
283
|
}
|
|
306
284
|
} else {
|
|
307
285
|
NSURL *url = [NSURL URLWithString:sourceUri];
|
|
308
286
|
NSData *urlData = [NSData dataWithContentsOfURL:url];
|
|
309
|
-
|
|
310
287
|
if (urlData) {
|
|
311
288
|
NSString *filename = [sourceUri lastPathComponent];
|
|
312
289
|
NSString *tempFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
|
|
313
290
|
[urlData writeToFile:tempFile atomically:YES];
|
|
314
|
-
[self moveToICloudDirectory:documentsFolder :tempFile :destinationPath :resolve :reject];
|
|
291
|
+
[self moveToICloudDirectory:documentsFolder tempFile:tempFile destinationPath:destinationPath resolve:resolve reject:reject];
|
|
315
292
|
} else {
|
|
316
|
-
RCTLogTrace(@"source file does not exist %@", sourceUri);
|
|
317
293
|
return reject(@"error", [NSString stringWithFormat:@"cannot download '%@'", sourceUri], nil);
|
|
318
294
|
}
|
|
319
295
|
}
|
|
320
296
|
}
|
|
321
297
|
|
|
322
|
-
|
|
323
|
-
:(RCTPromiseResolveBlock)resolver
|
|
324
|
-
:(RCTPromiseRejectBlock)rejecter {
|
|
298
|
+
// MARK: - syncCloud
|
|
325
299
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
300
|
+
- (void)syncCloud:(RCTPromiseResolveBlock)resolve
|
|
301
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
302
|
+
{
|
|
303
|
+
_query = [[NSMetadataQuery alloc] init];
|
|
304
|
+
[_query setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope]];
|
|
305
|
+
[_query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE '*'", NSMetadataItemFSNameKey]];
|
|
306
|
+
|
|
307
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
308
|
+
BOOL startedQuery = [self->_query startQuery];
|
|
309
|
+
if (!startedQuery) {
|
|
310
|
+
reject(@"error", @"Failed to start query.\n", nil);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
[[NSNotificationCenter defaultCenter] addObserverForName:NSMetadataQueryDidFinishGatheringNotification
|
|
315
|
+
object:_query
|
|
316
|
+
queue:[NSOperationQueue currentQueue]
|
|
317
|
+
usingBlock:^(NSNotification __strong *notification) {
|
|
318
|
+
NSMetadataQuery *query = [notification object];
|
|
319
|
+
[query disableUpdates];
|
|
320
|
+
[query stopQuery];
|
|
321
|
+
for (NSMetadataItem *item in query.results) {
|
|
322
|
+
[self downloadFileIfNotAvailable:item];
|
|
323
|
+
}
|
|
324
|
+
return resolve(nil);
|
|
325
|
+
}];
|
|
333
326
|
}
|
|
334
327
|
|
|
335
|
-
|
|
336
|
-
:(RCTPromiseResolveBlock)resolver
|
|
337
|
-
:(RCTPromiseRejectBlock)rejecter {
|
|
328
|
+
// MARK: - Private helpers
|
|
338
329
|
|
|
330
|
+
- (void)moveToICloudDirectory:(bool)documentsFolder
|
|
331
|
+
tempFile:(NSString *)tempFile
|
|
332
|
+
destinationPath:(NSString *)destinationPath
|
|
333
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
334
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
335
|
+
{
|
|
336
|
+
NSURL *ubiquityURL = documentsFolder ? [self icloudDocumentsDirectory] : [self icloudDirectory];
|
|
337
|
+
[self moveToICloud:ubiquityURL tempFile:tempFile destinationPath:destinationPath resolve:resolve reject:reject];
|
|
338
|
+
}
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
- (void)moveToICloud:(NSURL *)ubiquityURL
|
|
341
|
+
tempFile:(NSString *)tempFile
|
|
342
|
+
destinationPath:(NSString *)destinationPath
|
|
343
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
344
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
345
|
+
{
|
|
346
|
+
NSString *destPath = destinationPath;
|
|
341
347
|
while ([destPath hasPrefix:@"/"]) {
|
|
342
348
|
destPath = [destPath substringFromIndex:1];
|
|
343
349
|
}
|
|
344
350
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
351
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
348
352
|
|
|
349
353
|
if (ubiquityURL) {
|
|
350
|
-
|
|
351
|
-
NSURL* targetFile = [ubiquityURL URLByAppendingPathComponent:destPath];
|
|
354
|
+
NSURL *targetFile = [ubiquityURL URLByAppendingPathComponent:destPath];
|
|
352
355
|
NSURL *dir = [targetFile URLByDeletingLastPathComponent];
|
|
356
|
+
NSURL *uniqueFile = targetFile;
|
|
353
357
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if([fileManager fileExistsAtPath:uniqueFile.path]){
|
|
358
|
+
if ([fileManager fileExistsAtPath:uniqueFile.path]) {
|
|
357
359
|
NSError *error;
|
|
358
360
|
[fileManager removeItemAtPath:uniqueFile.path error:&error];
|
|
359
|
-
if(error) {
|
|
360
|
-
return
|
|
361
|
+
if (error) {
|
|
362
|
+
return reject(@"error", error.description, nil);
|
|
361
363
|
}
|
|
362
364
|
}
|
|
363
365
|
|
|
364
|
-
RCTLogTrace(@"Target file: %@", uniqueFile.path);
|
|
365
|
-
|
|
366
366
|
if (![fileManager fileExistsAtPath:dir.path]) {
|
|
367
367
|
[fileManager createDirectoryAtURL:dir withIntermediateDirectories:YES attributes:nil error:nil];
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
NSError *error;
|
|
371
371
|
[fileManager setUbiquitous:YES itemAtURL:[NSURL fileURLWithPath:tempFile] destinationURL:uniqueFile error:&error];
|
|
372
|
-
if(error) {
|
|
373
|
-
return
|
|
372
|
+
if (error) {
|
|
373
|
+
return reject(@"error", error.description, nil);
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
[fileManager removeItemAtPath:tempFile error:&error];
|
|
377
|
-
|
|
378
|
-
return resolver(uniqueFile.path);
|
|
377
|
+
return resolve(uniqueFile.path);
|
|
379
378
|
} else {
|
|
380
379
|
NSError *error;
|
|
381
380
|
[fileManager removeItemAtPath:tempFile error:&error];
|
|
382
|
-
|
|
383
|
-
return rejecter(@"error", [NSString stringWithFormat:@"could not copy '%@' to iCloud drive", tempFile], nil);
|
|
381
|
+
return reject(@"error", [NSString stringWithFormat:@"could not copy '%@' to iCloud drive", tempFile], nil);
|
|
384
382
|
}
|
|
385
383
|
}
|
|
386
384
|
|
|
387
|
-
- (NSURL *)icloudDocumentsDirectory
|
|
388
|
-
|
|
385
|
+
- (NSURL *)icloudDocumentsDirectory
|
|
386
|
+
{
|
|
387
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
389
388
|
NSURL *rootDirectory = [[self icloudDirectory] URLByAppendingPathComponent:@"Documents"];
|
|
390
|
-
|
|
391
389
|
if (rootDirectory) {
|
|
392
390
|
if (![fileManager fileExistsAtPath:rootDirectory.path isDirectory:nil]) {
|
|
393
|
-
RCTLogTrace(@"Creating documents directory: %@", rootDirectory.path);
|
|
394
391
|
[fileManager createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil];
|
|
395
392
|
}
|
|
396
393
|
}
|
|
397
|
-
|
|
398
394
|
return rootDirectory;
|
|
399
395
|
}
|
|
400
396
|
|
|
401
|
-
- (NSURL *)icloudDirectory
|
|
402
|
-
|
|
397
|
+
- (NSURL *)icloudDirectory
|
|
398
|
+
{
|
|
399
|
+
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
403
400
|
NSURL *rootDirectory = [fileManager URLForUbiquityContainerIdentifier:nil];
|
|
404
401
|
return rootDirectory;
|
|
405
402
|
}
|
|
406
403
|
|
|
407
|
-
- (
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return [NSURL fileURLWithPath:resourcePath];
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
- (BOOL)downloadFileIfNotAvailable:(NSMetadataItem*)item {
|
|
416
|
-
if ([[item valueForAttribute:NSMetadataUbiquitousItemDownloadingStatusKey] isEqualToString:NSMetadataUbiquitousItemDownloadingStatusCurrent]){
|
|
417
|
-
NSLog(@"File is ready!");
|
|
404
|
+
- (BOOL)downloadFileIfNotAvailable:(NSMetadataItem *)item
|
|
405
|
+
{
|
|
406
|
+
if ([[item valueForAttribute:NSMetadataUbiquitousItemDownloadingStatusKey] isEqualToString:NSMetadataUbiquitousItemDownloadingStatusCurrent]) {
|
|
418
407
|
return YES;
|
|
419
408
|
}
|
|
420
|
-
|
|
421
|
-
NSFileManager* fm = [NSFileManager defaultManager];
|
|
409
|
+
NSFileManager *fm = [NSFileManager defaultManager];
|
|
422
410
|
NSError *downloadError = nil;
|
|
423
411
|
[fm startDownloadingUbiquitousItemAtURL:[item valueForAttribute:NSMetadataItemURLKey] error:&downloadError];
|
|
424
|
-
if (downloadError) {
|
|
425
|
-
NSLog(@"Error occurred starting download: %@", downloadError);
|
|
426
|
-
}
|
|
427
|
-
NSLog(@"Waiting before retrying...");
|
|
428
412
|
[NSThread sleepForTimeInterval:0.3];
|
|
429
413
|
return NO;
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
RCT_EXPORT_METHOD(syncCloud:(RCTPromiseResolveBlock)resolve
|
|
435
|
-
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
436
|
-
|
|
437
|
-
_query = [[NSMetadataQuery alloc] init];
|
|
438
|
-
[_query setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope]];
|
|
439
|
-
[_query setPredicate:[NSPredicate predicateWithFormat: @"%K LIKE '*'", NSMetadataItemFSNameKey]];
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
443
|
-
|
|
444
|
-
BOOL startedQuery = [self->_query startQuery];
|
|
445
|
-
if (!startedQuery)
|
|
446
|
-
{
|
|
447
|
-
reject(@"error", @"Failed to start query.\n", nil);
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
[[NSNotificationCenter defaultCenter] addObserverForName:
|
|
452
|
-
NSMetadataQueryDidFinishGatheringNotification
|
|
453
|
-
object:_query queue:[NSOperationQueue currentQueue]
|
|
454
|
-
usingBlock:^(NSNotification __strong *notification)
|
|
455
|
-
{
|
|
456
|
-
NSMetadataQuery *query = [notification object];
|
|
457
|
-
[query disableUpdates];
|
|
458
|
-
[query stopQuery];
|
|
459
|
-
for (NSMetadataItem *item in query.results) {
|
|
460
|
-
[self downloadFileIfNotAvailable: item];
|
|
461
|
-
}
|
|
462
|
-
return resolve(@YES);
|
|
463
|
-
}];
|
|
464
|
-
|
|
465
414
|
}
|
|
466
415
|
|
|
467
416
|
@end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeCloudFs.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;AAclD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,WAAW,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeCloudFs","CloudFs"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,aAAa,MAAM,oBAAiB;AAE3C,OAAO,MAAMC,OAAO,GAAGD,aAAa","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|