diff --git a/Controller/SoundsViewModel.swift b/Controller/SoundsViewModel.swift index 45890ade..b2028055 100644 --- a/Controller/SoundsViewModel.swift +++ b/Controller/SoundsViewModel.swift @@ -22,26 +22,55 @@ class SoundsViewModel: ViewModel, ViewModelType { var copyNameAction: Driver var playAction: Driver } - - func transform(input: Input) -> Output { - let models = { () -> [AVURLAsset] in - var urls = Bundle.main.urls(forResourcesWithExtension: "caf", subdirectory: nil) ?? [] - urls.sort { u1, u2 -> Bool in - u1.lastPathComponent.localizedStandardCompare(u2.lastPathComponent) == ComparisonResult.orderedAscending + + func getSounds(urls: [URL]) -> [SoundCellViewModel] { + let urls = urls.sorted { u1, u2 -> Bool in + u1.lastPathComponent.localizedStandardCompare(u2.lastPathComponent) == ComparisonResult.orderedAscending + } + return urls + .map { AVURLAsset(url: $0) } + .map { SoundCellViewModel(model: $0) } + } + + /// 返回指定文件夹,指定后缀的文件列表数组 + func getFilesInDirectory(directory: String, suffix: String) -> [URL] { + let fileManager = FileManager.default + do { + let files = try fileManager.contentsOfDirectory(atPath: directory) + return files.compactMap { file -> URL? in + if file.hasSuffix(suffix) { + return URL(fileURLWithPath: directory).appendingPathComponent(file) + } + return nil } - let audios = urls.map { url -> AVURLAsset in - let asset = AVURLAsset(url: url) - return asset + } catch { + return [] + } + } + + func transform(input: Input) -> Output { + let defaultSounds = getSounds( + urls: Bundle.main.urls(forResourcesWithExtension: "caf", subdirectory: nil) ?? [] + ) + + let customSounds: [SoundCellViewModel] = { + guard let soundsDirectoryUrl = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first?.appending("/Sounds") else { + return [] } - return audios - }().map { SoundCellViewModel(model: $0) } - + return getSounds( + urls: getFilesInDirectory(directory: soundsDirectoryUrl, suffix: "caf") + ) + }() + let copyAction = Driver.merge( - models.map { $0.copyNameAction.asDriver(onErrorDriveWith: .empty()) } + (defaultSounds + customSounds).map { $0.copyNameAction.asDriver(onErrorDriveWith: .empty()) } ).asDriver() - + return Output( - audios: Observable.just([SectionModel(model: "model", items: models)]), + audios: Observable.just([ + SectionModel(model: "customSounds", items: customSounds), + SectionModel(model: "defaultSounds", items: defaultSounds) + ]), copyNameAction: copyAction, playAction: input.soundSelected.map { $0.model.url as CFURL } )