Skip to content

Instantly share code, notes, and snippets.

@ryotapoi
Created November 6, 2020 04:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryotapoi/2c869946eff9c962a4a088f5a7dc512c to your computer and use it in GitHub Desktop.
Save ryotapoi/2c869946eff9c962a4a088f5a7dc512c to your computer and use it in GitHub Desktop.
FileManagerによるファイル操作でCombineを使う。
import Foundation
import Combine
extension FileManager {
struct RemoveItemPublisher: Publisher {
typealias Output = Void
typealias Failure = Error
var url: URL
var fileManager: FileManager
init(at url: URL, fileManager: FileManager) {
self.url = url
self.fileManager = fileManager
}
func receive<S>(
subscriber: S
) where S : Subscriber, Failure == S.Failure, Output == S.Input {
Deferred {
Future { [self] promise in
do {
try fileManager.removeItem(at: url)
promise(.success(()))
} catch {
promise(.failure(error))
}
}
}
.receive(subscriber: subscriber)
}
func ignoreNoSuchFile() -> AnyPublisher<Void, Error> {
tryCatch { (error) -> AnyPublisher<Void, Error> in
let nserror = error as NSError
guard nserror.domain == NSCocoaErrorDomain,
CocoaError.Code(rawValue: nserror.code) == .fileNoSuchFile
else {
throw error
}
return Just(()).setFailureType(to: Error.self).eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
}
func removeItemPublisher(at url: URL) -> RemoveItemPublisher {
RemoveItemPublisher(at: url, fileManager: self)
}
func copyItemPublisher(at srcURL: URL, to dstURL: URL) -> AnyPublisher<Void, Error> {
Deferred {
Future { [self] promise in
do {
try copyItem(at: srcURL, to: dstURL)
promise(.success(()))
} catch {
promise(.failure(error))
}
}
}
.eraseToAnyPublisher()
}
func mergeItemsPublisher(at srcURLs: [URL], to dstURL: URL) -> AnyPublisher<Void, Error> {
Deferred {
Future { promise in
do {
try Data().write(to: dstURL)
let fileHandle = try FileHandle(forWritingTo: dstURL)
try srcURLs
.map { try Data(contentsOf: $0, options: .mappedIfSafe) }
.forEach { fileHandle.write($0) }
try fileHandle.close()
promise(.success(()))
} catch {
promise(.failure(error))
}
}
}
.eraseToAnyPublisher()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment