Skip to content

Commit 4ddab03

Browse files
authored
refactor(ios): simplify file moves (#845)
* refactor(ios): simplify file moves * Create tasty-plums-carry.md
1 parent f96f7bf commit 4ddab03

File tree

4 files changed

+52
-48
lines changed

4 files changed

+52
-48
lines changed

.changeset/tasty-plums-carry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-native-documents/picker": patch
3+
---
4+
5+
refactor(ios): simplify file moves

packages/document-picker/ios/swift/DocPicker.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import MobileCoreServices
2828
}
2929

3030
public func getMetadataFor(url: URL) throws -> DocumentMetadataBuilder {
31-
if (currentOptions?.isOpenMode() == true) {
32-
return try self.getOpenedDocumentInfo(url: url, requestLongTermAccess: currentOptions?.requestLongTermAccess ?? false)
31+
return if (currentOptions?.isOpenMode() == true) {
32+
try self.getOpenedDocumentInfo(url: url, requestLongTermAccess: currentOptions?.requestLongTermAccess ?? false)
3333
} else {
34-
return try self.getAnyModeMetadata(url: url)
34+
try self.getAnyModeMetadata(url: url)
3535
}
3636
}
3737

packages/document-picker/ios/swift/FileOperations.swift

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,68 @@ import Foundation
44

55
@objc public class FileOperations: NSObject {
66

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)
1010
resolve(results)
1111
}
1212
}
1313

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?]] {
1515
let destinationRootDir = getDirectoryForFileDestination(destinationPreset)
1616
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)
1918

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
3924
}
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)
4648
}
4749
}
4850

4951
static func moveToDestination(from: URL, usingFilename fileName: String, destinationDir: URL) throws -> URL {
5052
let destinationFile = destinationDir.appendingPathComponent(fileName).standardized
5153

5254
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+
)
5460
}
5561

56-
try FileManager.default.createDirectory(at: destinationDir, withIntermediateDirectories: true, attributes: nil)
5762
try FileManager.default.moveItem(at: from, to: destinationFile)
5863

5964
return destinationFile
6065
}
6166

6267
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!
6770
}
6871
}

packages/document-picker/ios/swift/IsKnownTypeImpl.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,10 @@ import UniformTypeIdentifiers
2828

2929
static func createUTType(kind: String, value: String) -> UTType? {
3030
switch kind {
31-
case "UTType":
32-
return UTType(value)
33-
case "mimeType":
34-
return UTType(mimeType: value)
35-
case "extension":
36-
return UTType(filenameExtension: value)
37-
default:
38-
return nil
31+
case "UTType": UTType(value)
32+
case "mimeType": UTType(mimeType: value)
33+
case "extension": UTType(filenameExtension: value)
34+
default: nil
3935
}
4036
}
4137
}

0 commit comments

Comments
 (0)