Created
September 2, 2020 07:05
-
-
Save alekseypotapov-dev/4d1237adcb97f9f14630e2973406bc46 to your computer and use it in GitHub Desktop.
Merging files using FileManager in swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let merger = FoldersMerger(actionType: .copy, conflictResolution: .keepSource) | |
merger.merge(atPath: sourceFolder, toPath: destinationFolder) | |
class FoldersMerger { | |
enum ActionType { case move, copy } | |
enum ConflictResolution { case keepSource, keepDestination } | |
private let fileManager = FileManager() | |
private var actionType: ActionType! | |
private var conflictResolution: ConflictResolution! | |
private var deleteEmptyFolders: Bool! | |
init(actionType: ActionType = .move, conflictResolution: ConflictResolution = .keepDestination, deleteEmptyFolders: Bool = false) { | |
self.actionType = actionType | |
self.conflictResolution = conflictResolution | |
self.deleteEmptyFolders = deleteEmptyFolders | |
} | |
func merge(atPath: String, toPath: String) { | |
let pathEnumerator = fileManager.enumerator(atPath: atPath) | |
var folders: [String] = [atPath] | |
while let relativePath = pathEnumerator?.nextObject() as? String { | |
let subItemAtPath = URL(fileURLWithPath: atPath).appendingPathComponent(relativePath).path | |
let subItemToPath = URL(fileURLWithPath: toPath).appendingPathComponent(relativePath).path | |
if isDir(atPath: subItemAtPath) { | |
if deleteEmptyFolders! { | |
folders.append(subItemAtPath) | |
} | |
if !isDir(atPath: subItemToPath) { | |
do { | |
try fileManager.createDirectory(atPath: subItemToPath, withIntermediateDirectories: true, attributes: nil) | |
NSLog("FoldersMerger: directory created: %@", subItemToPath) | |
} | |
catch let error { | |
NSLog("ERROR FoldersMerger: %@", error.localizedDescription) | |
} | |
} | |
else { | |
NSLog("FoldersMerger: directory %@ already exists", subItemToPath) | |
} | |
} | |
else { | |
if isFile(atPath:subItemToPath) && conflictResolution == .keepSource { | |
do { | |
try fileManager.removeItem(atPath: subItemToPath) | |
NSLog("FoldersMerger: file deleted: %@", subItemToPath) | |
} | |
catch let error { | |
NSLog("ERROR FoldersMerger: %@", error.localizedDescription) | |
} | |
} | |
do { | |
try fileManager.moveItem(atPath: subItemAtPath, toPath: subItemToPath) | |
NSLog("FoldersMerger: file moved from %@ to %@", subItemAtPath, subItemToPath) | |
} | |
catch let error { | |
NSLog("ERROR FoldersMerger: %@", error.localizedDescription) | |
} | |
} | |
} | |
if deleteEmptyFolders! { | |
folders.sort(by: { (path1, path2) -> Bool in | |
return path1.characters.split(separator: "/").count < path2.characters.split(separator: "/").count | |
}) | |
while let folderPath = folders.popLast() { | |
if isDirEmpty(atPath: folderPath) { | |
do { | |
try fileManager.removeItem(atPath: folderPath) | |
NSLog("FoldersMerger: empty dir deleted: %@", folderPath) | |
} | |
catch { | |
NSLog("ERROR FoldersMerger: %@", error.localizedDescription) | |
} | |
} | |
} | |
} | |
} | |
private func isDir(atPath: String) -> Bool { | |
var isDir: ObjCBool = false | |
let exist = fileManager.fileExists(atPath: atPath, isDirectory: &isDir) | |
return exist && isDir.boolValue | |
} | |
private func isFile(atPath: String) -> Bool { | |
var isDir: ObjCBool = false | |
let exist = fileManager.fileExists(atPath: atPath, isDirectory: &isDir) | |
return exist && !isDir.boolValue | |
} | |
private func isDirEmpty(atPath: String) -> Bool { | |
do { | |
return try fileManager.contentsOfDirectory(atPath: atPath).count == 0 | |
} | |
catch _ { | |
return false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It seems ActionType is not used