Add file provider for iOS
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import FileProvider
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
class FileProviderItem: NSObject, NSFileProviderItem {
|
||||
private let url: URL
|
||||
private let fileAttributes: [FileAttributeKey: Any]
|
||||
private let _identifier: NSFileProviderItemIdentifier
|
||||
private let _parentIdentifier: NSFileProviderItemIdentifier
|
||||
private let isRoot: Bool
|
||||
|
||||
init(rootAt url: URL) {
|
||||
self.url = url
|
||||
_identifier = .rootContainer
|
||||
_parentIdentifier = .rootContainer
|
||||
isRoot = true
|
||||
fileAttributes = (try? FileManager.default.attributesOfItem(atPath: url.path)) ?? [:]
|
||||
super.init()
|
||||
}
|
||||
|
||||
init(url: URL, identifier: NSFileProviderItemIdentifier, workingDirectory: URL) {
|
||||
self.url = url
|
||||
_identifier = identifier
|
||||
isRoot = false
|
||||
fileAttributes = (try? FileManager.default.attributesOfItem(atPath: url.path)) ?? [:]
|
||||
|
||||
let parentPath = url.deletingLastPathComponent().path
|
||||
if parentPath == workingDirectory.path {
|
||||
_parentIdentifier = .rootContainer
|
||||
} else {
|
||||
let relativePath = parentPath.replacingOccurrences(of: workingDirectory.path + "/", with: "")
|
||||
_parentIdentifier = NSFileProviderItemIdentifier(relativePath)
|
||||
}
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
var itemIdentifier: NSFileProviderItemIdentifier {
|
||||
_identifier
|
||||
}
|
||||
|
||||
var parentItemIdentifier: NSFileProviderItemIdentifier {
|
||||
_parentIdentifier
|
||||
}
|
||||
|
||||
var filename: String {
|
||||
if isRoot {
|
||||
return "sing-box"
|
||||
}
|
||||
return url.lastPathComponent
|
||||
}
|
||||
|
||||
var contentType: UTType {
|
||||
if isDirectory {
|
||||
return .folder
|
||||
}
|
||||
return UTType(filenameExtension: url.pathExtension) ?? .data
|
||||
}
|
||||
|
||||
var capabilities: NSFileProviderItemCapabilities {
|
||||
[
|
||||
.allowsReading,
|
||||
.allowsWriting,
|
||||
.allowsRenaming,
|
||||
.allowsReparenting,
|
||||
.allowsDeleting,
|
||||
.allowsAddingSubItems,
|
||||
.allowsContentEnumerating,
|
||||
]
|
||||
}
|
||||
|
||||
var itemVersion: NSFileProviderItemVersion {
|
||||
let modDate = fileAttributes[.modificationDate] as? Date ?? Date()
|
||||
let contentVersion = withUnsafeBytes(of: modDate.timeIntervalSince1970) { Data($0) }
|
||||
return NSFileProviderItemVersion(contentVersion: contentVersion, metadataVersion: contentVersion)
|
||||
}
|
||||
|
||||
var documentSize: NSNumber? {
|
||||
guard !isDirectory else { return nil }
|
||||
return fileAttributes[.size] as? NSNumber
|
||||
}
|
||||
|
||||
var creationDate: Date? {
|
||||
fileAttributes[.creationDate] as? Date
|
||||
}
|
||||
|
||||
var contentModificationDate: Date? {
|
||||
fileAttributes[.modificationDate] as? Date
|
||||
}
|
||||
|
||||
var childItemCount: NSNumber? {
|
||||
guard isDirectory else { return nil }
|
||||
let contents = try? FileManager.default.contentsOfDirectory(atPath: url.path)
|
||||
return NSNumber(value: contents?.count ?? 0)
|
||||
}
|
||||
|
||||
private var isDirectory: Bool {
|
||||
var isDir: ObjCBool = false
|
||||
FileManager.default.fileExists(atPath: url.path, isDirectory: &isDir)
|
||||
return isDir.boolValue
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user