@@ -4,65 +4,68 @@ import Foundation
4
4
5
5
@objc public class FileOperations : NSObject {
6
6
7
- @objc public static func keepLocalCopyAtUniqueDestination( from: Array < Dictionary < String , String > > , destinationPreset: String , resolve: @escaping RNDPPromiseResolveBlock ) {
8
- Task {
9
- let results = await moveFiles ( from: from, destinationPreset: destinationPreset)
7
+ @objc public static func keepLocalCopyAtUniqueDestination( from: [ [ String : String ] ] , destinationPreset: String , resolve: @escaping RNDPPromiseResolveBlock ) {
8
+ DispatchQueue . global ( qos : . utility ) . async {
9
+ let results = moveFiles ( from: from, destinationPreset: destinationPreset)
10
10
resolve ( results)
11
11
}
12
12
}
13
13
14
- static func moveFiles( from: Array < Dictionary < String , String > > , destinationPreset: String ) async -> [ [ String : String ? ] ] {
14
+ static func moveFiles( from: [ [ String : String ] ] , destinationPreset: String ) -> [ [ String : String ? ] ] {
15
15
let destinationRootDir = getDirectoryForFileDestination ( destinationPreset)
16
16
let uniqueSubDirName = UUID ( ) . uuidString
17
- let destinationDir : URL = destinationRootDir. appendingPathComponent ( " \( uniqueSubDirName) / " , isDirectory: true )
18
- // TODO do we need all of this Task dance?
17
+ let destinationDir = destinationRootDir. appendingPathComponent ( uniqueSubDirName, isDirectory: true )
19
18
20
- return await withTaskGroup ( of: LocalCopyResponse . self) { group in
21
- var results : Array < Dictionary < String , String ? > > = [ [ String: String? ] ] ( )
22
-
23
- for dictionary in from {
24
- group. addTask {
25
- do {
26
- guard let uriString = dictionary [ " uri " ] , let uri = URL ( string: uriString) else {
27
- return LocalCopyResponse . error ( sourceUri: dictionary [ " uri " ] , copyError: " Invalid URI " )
28
- }
29
- guard let fileName = dictionary [ " fileName " ] else {
30
- return LocalCopyResponse . error ( sourceUri: uri. absoluteString, copyError: " Invalid fileName " )
31
- }
32
-
33
- let destinationUrl = try moveToDestination ( from: uri, usingFilename: fileName, destinationDir: destinationDir)
34
- return LocalCopyResponse . success ( sourceUri: uri. absoluteString, localUri: destinationUrl. absoluteString)
35
- } catch {
36
- return LocalCopyResponse . error ( sourceUri: dictionary [ " uri " ] !, copyError: error. localizedDescription)
37
- }
38
- }
19
+ do {
20
+ try FileManager . default. createDirectory ( at: destinationDir, withIntermediateDirectories: true , attributes: nil )
21
+ } catch {
22
+ return from. map { dictionary in
23
+ LocalCopyResponse . error ( sourceUri: dictionary [ " uri " ] , copyError: " Failed to create destination directory: \( error. localizedDescription) " ) . dictionaryRepresentation
39
24
}
40
-
41
- for await result in group {
42
- results. append ( result. dictionaryRepresentation)
43
- }
44
-
45
- return results
25
+ }
26
+
27
+ // move files
28
+ return from. map { dictionary in
29
+ moveSingleFile ( dictionary: dictionary, destinationDir: destinationDir) . dictionaryRepresentation
30
+ }
31
+ }
32
+
33
+ private static func moveSingleFile( dictionary: [ String : String ] , destinationDir: URL ) -> LocalCopyResponse {
34
+ guard let uriString = dictionary [ " uri " ] ,
35
+ let uri = URL ( string: uriString) ,
36
+ let fileName = dictionary [ " fileName " ] else {
37
+ return LocalCopyResponse . error (
38
+ sourceUri: dictionary [ " uri " ] ,
39
+ copyError: " Invalid URI or fileName "
40
+ )
41
+ }
42
+
43
+ do {
44
+ let destinationUrl = try moveToDestination ( from: uri, usingFilename: fileName, destinationDir: destinationDir)
45
+ return LocalCopyResponse . success ( sourceUri: uri. absoluteString, localUri: destinationUrl. absoluteString)
46
+ } catch {
47
+ return LocalCopyResponse . error ( sourceUri: uriString, copyError: error. localizedDescription)
46
48
}
47
49
}
48
50
49
51
static func moveToDestination( from: URL , usingFilename fileName: String , destinationDir: URL ) throws -> URL {
50
52
let destinationFile = destinationDir. appendingPathComponent ( fileName) . standardized
51
53
52
54
guard destinationFile. path. hasPrefix ( destinationDir. standardized. path) else {
53
- throw NSError ( domain: " PathTraversalPrevention " , code: 400 , userInfo: [ NSLocalizedDescriptionKey: " The copied file is attempting to write outside of the target directory. " ] )
55
+ throw NSError (
56
+ domain: " PathTraversalPrevention " ,
57
+ code: 400 ,
58
+ userInfo: [ NSLocalizedDescriptionKey: " The copied file is attempting to write outside of the target directory. " ]
59
+ )
54
60
}
55
61
56
- try FileManager . default. createDirectory ( at: destinationDir, withIntermediateDirectories: true , attributes: nil )
57
62
try FileManager . default. moveItem ( at: from, to: destinationFile)
58
63
59
64
return destinationFile
60
65
}
61
66
62
67
static func getDirectoryForFileDestination( _ copyToDirectory: String ) -> URL {
63
- if copyToDirectory == " documentDirectory " {
64
- return FileManager . default. urls ( for: . documentDirectory, in: . userDomainMask) . first!
65
- }
66
- return FileManager . default. urls ( for: . cachesDirectory, in: . userDomainMask) . first!
68
+ let searchPath : FileManager . SearchPathDirectory = copyToDirectory == " documentDirectory " ? . documentDirectory : . cachesDirectory
69
+ return FileManager . default. urls ( for: searchPath, in: . userDomainMask) . first!
67
70
}
68
71
}
0 commit comments