Files
2026-06-02 10:42:33 +08:00

138 lines
4.2 KiB
Plaintext

// @ts-nocheck
import { ChooseFileOption, ChooseFile, ChooseFileSuccessCallbackResult } from '../interface'
import { UIDocumentPickerDelegate, UIDocumentPickerMode } from "UIKit"
import { URL, FileManager } from 'Foundation';
import { GeneralCallbackResultImpl } from '../unierror'
import { DispatchQueue } from 'Dispatch';
const documentTypes : Map<string, string[]> = new Map([
["all", ["public.item"]],
["file", [
"public.text",
"public.zip-archive",
"public.data",
"com.adobe.pdf",
"com.microsoft.word.doc",
"com.microsoft.word.docx",
"com.microsoft.excel.xls",
"com.microsoft.excel.xlsx"
]
],
["video", ["public.movie"]],
["image", ["public.image"]],
])
class ChooseFileImpl {
name : string = ''
path : string = ''
size : number = 0
time : number = 0
type : string = 'file'
constructor(uri : URL, options : ChooseFileOption) {
try {
const originalFileName = uri.lastPathComponent;
const attributes = UTSiOS.try(FileManager.default.attributesOfItem(atPath = uri.path))
const fileSize = attributes[FileAttributeKey.size] as number
const pathExtension = `${uri.pathExtension}`
const imageFormats = ['jpeg', 'jpg', 'png', 'gif', 'bmp', 'tiff', 'svg']
const videoFormats = ['mov', 'm4v', 'mp4', 'avi']
let fileName = originalFileName
if(options.filename != null) {
fileName = options.filename!
if(options.count != null && options.count! > 1) {
fileName = `${fileName}_${Date.now()}`;
}
fileName = `${fileName}.${pathExtension}`
}
// #ifdef UNI-APP-X
const dataPath = UTSiOS.getDataPath()
// #endif
// #ifndef UNI-APP-X
const dataPath = UTSiOS.getDataPath().replace(/data$/, "doc");
// #endif
const file = new URL(fileURLWithPath = dataPath).appendingPathComponent(fileName)//.absoluteString
const fileData = FileManager.default.contents(atPath = uri.path);
UTSiOS.try(fileData?.write(to = file))
if (imageFormats.includes(pathExtension)) {
this.type = 'image'
} else if (videoFormats.includes(pathExtension)) {
this.type = 'video'
} else {
this.type = 'file'
}
this.name = `${originalFileName}`
this.size = fileSize
this.path = `${file.absoluteString}`
} catch (e) {
}
}
}
class FilePickerManager implements UIDocumentPickerDelegate {
options : ChooseFileOption = {}
constructor() { }
chooseFile(options : ChooseFileOption) {
DispatchQueue.main.async(execute = () : void => {
this.options = options
const type = options.type ?? 'all'
const count = options.count ?? 1
const types = (documentTypes.get(type) ?? documentTypes.get('all')) as string[]
let documentPicker = UIDocumentPickerViewController(
documentTypes = types,
in = UIDocumentPickerMode.import
)
documentPicker.delegate = this
// 多选要大于 ios11
if (UTSiOS.available("iOS 11.0, *")) {
documentPicker.allowsMultipleSelection = count > 1
}
UTSiOS.getCurrentViewController().present(documentPicker, animated = true)
})
}
documentPicker(controller : UIDocumentPickerViewController, @argumentLabel("didPickDocumentsAt") urls : URL[]) {
DispatchQueue.main.async(execute = () : void => {
const tempFiles : ChooseFile[] = []
for (let i = 0; i < urls.length; i++) {
const url = urls[i]
const chooseFile = new ChooseFileImpl(url, this.options);
// IOS -> js 无法传class?
const file : ChooseFile = {
name: chooseFile.name,
path: chooseFile.path,
size: chooseFile.size,
time: chooseFile.time,
type: chooseFile.type,
}
if (chooseFile.path != '') {
tempFiles.push(file)
}
}
const count = this.options.count ?? Number.from(Double.greatestFiniteMagnitude) //Number.from(Double.MAX_VALUE)
if (tempFiles.length > 0 && count >= tempFiles.length) {
const res : ChooseFileSuccessCallbackResult = {
tempFiles,
errMsg: 'chooseFile:ok'
}
this.options.success?.(res)
} else {
const err = new GeneralCallbackResultImpl(9010002, `没有可用的文件或文件超过设置数量`)
this.options.fail?.(err)
this.options.complete?.(err)
}
})
}
}
const fileManager = new FilePickerManager()
export function chooseFile(options : ChooseFileOption) {
fileManager.chooseFile(options)
}