|
6 | 6 | //
|
7 | 7 |
|
8 | 8 | import Foundation
|
| 9 | +import NitroModules |
| 10 | +import FastIOPrivate |
9 | 11 |
|
10 |
| -class HybridFileSystem : HybridFileSystemSpec { |
| 12 | +class HybridFileSystem : NSObject, UIDocumentPickerDelegate, HybridFileSystemSpec { |
11 | 13 | func createInputStream(path: String) -> any HybridInputStreamSpec {
|
12 |
| - let fakePath = Bundle.main.url(forResource: "img", withExtension: "jpg")!.path |
13 |
| - guard let stream = InputStream(fileAtPath: fakePath) else { |
| 14 | + guard let stream = InputStream(fileAtPath: path) else { |
14 | 15 | fatalError("Failed to create stream from \(path)")
|
15 | 16 | }
|
16 | 17 | return HybridInputStream(stream: stream)
|
17 | 18 | }
|
18 | 19 |
|
19 | 20 | func getFileMetadata(path: String) throws -> Metadata {
|
20 |
| - let fileURL = Bundle.main.url(forResource: "img", withExtension: "jpg")! |
21 |
| - let attributes = try FileManager.default.attributesOfItem(atPath: fileURL.path) |
22 |
| - |
| 21 | + let attributes = try FileManager.default.attributesOfItem(atPath: path) |
| 22 | + let fileURL = URL(fileURLWithPath: path) |
| 23 | + |
23 | 24 | return Metadata.init(
|
24 | 25 | name: fileURL.lastPathComponent,
|
| 26 | + path: path, |
| 27 | + root: "/", |
25 | 28 | size: attributes[.size] as? Double ?? 0,
|
26 |
| - lastModified: 0 |
| 29 | + lastModified: (attributes[.modificationDate] as? Date)?.timeIntervalSince1970 ?? 0 * 1000 |
27 | 30 | )
|
28 | 31 | }
|
29 | 32 |
|
| 33 | + private var filePicker: (promise: Promise<[String]>, vc: UIDocumentPickerViewController)? |
| 34 | + func showOpenFilePicker() throws -> Promise<[String]> { |
| 35 | + if filePicker != nil { |
| 36 | + return Promise.rejected(withError: RuntimeError.error(withMessage: "File picker already open")) |
| 37 | + } |
| 38 | + |
| 39 | + let promise = Promise<[String]>() |
| 40 | + |
| 41 | + DispatchQueue.main.async { |
| 42 | + let documentPicker = UIDocumentPickerViewController( |
| 43 | + forOpeningContentTypes: [.item], |
| 44 | + asCopy: true |
| 45 | + ) |
| 46 | + documentPicker.delegate = self |
| 47 | + |
| 48 | + guard let vc = RCTUtilsWrapper.getPresentedViewController() else { |
| 49 | + promise.reject(withError: RuntimeError.error(withMessage: "Cannot present file picker")) |
| 50 | + return |
| 51 | + } |
| 52 | + |
| 53 | + vc.present(documentPicker, animated: true) |
| 54 | + |
| 55 | + self.filePicker = (promise, documentPicker) |
| 56 | + } |
| 57 | + |
| 58 | + return promise |
| 59 | + } |
| 60 | + |
| 61 | + func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { |
| 62 | + controller.dismiss(animated: true, completion: nil) |
| 63 | + |
| 64 | + filePicker?.promise.resolve(withResult: urls.map { $0.path }) |
| 65 | + filePicker = nil |
| 66 | + } |
| 67 | + |
| 68 | + func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { |
| 69 | + controller.dismiss(animated: true, completion: nil) |
| 70 | + |
| 71 | + filePicker?.promise.resolve(withResult: []) |
| 72 | + filePicker = nil |
| 73 | + } |
| 74 | + |
30 | 75 | var hybridContext = margelo.nitro.HybridContext()
|
31 | 76 |
|
32 | 77 | // Return size of the instance to inform JS GC about memory pressure
|
33 | 78 | var memorySize: Int {
|
34 | 79 | return getSizeOf(self)
|
35 | 80 | }
|
| 81 | + |
| 82 | + deinit { |
| 83 | + if let (promise, picker) = filePicker { |
| 84 | + promise.resolve(withResult: []) |
| 85 | + DispatchQueue.main.async { |
| 86 | + picker.dismiss(animated: false) |
| 87 | + } |
| 88 | + } |
| 89 | + } |
36 | 90 | }
|
0 commit comments