Leaned
Realm DB 백업
1) .realm 파일 자체를 백업
- 앱에서 사용하는 DB 파일의 스키마와 복구할 파일의 스키마가 동일할 때
단순히 파일을 교체하여 쉽게 백업 및 복구가 가능함. - 하지만 사용자의 앱 버전마다 스키마가 다를 경우 사용하는 DB의 구조가
각각 다르기 때문에 복구 시 충돌이 발생할 수 있음. - 또한 백업한 데이터를 Realm이 아닌 데이터베이스에서 사용하기 어렵다는 단점이 있음.
2) Json으로 변환하여 백업
- 마이그레이션, 스키마 업데이트 등 DB 구조 변화에 유연하게 대응할 수 있으며
Realm외에 다른 데이터베이스 또는 다른 플랫폼에서 비교적 사용하기 편리함. - 단, 개발 시간이 늘어날 수 있다는 단점이 있음.
파일 앱을 활용한 백업 및 복구
- Zip 라이브러리를 사용해서 백업할 파일 압축 및 파일 앱에 저장
func zipFiles(targetToZip paths: [DesignatedPath]) {
guard let documentURL = getDocumentDirectory() else { return }
let paths = paths.map{ documentURL.appendingPathComponet(pathComponent: $0) }.filter { FileManager.default.fileExists(atPath: $0.path) }
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let fileName = dateFormatter.string(from: Date())
let destinationPath = documentURL.appendingPathComponet(pathComponent: .zipFilePath(fileName: fileName))
do {
// 모달 dragToDown 제스처 막기
self.isModalInPresentation = true
try Zip.zipFiles(paths: paths, zipFilePath: destinationPath, password: nil) { progress in print(progress) }
// UIActivityViewController로 파일 앱에 저장하거나 이메일로 전송 등
let vc = UIActivityViewController(activityItems: [destinationPath], applicationActivities: nil)
self.present(vc,animated: true)
self.isModalInPresentation = false
} catch { self.isModalInPresentation = false }
}
- UIDocumentPickerViewController를 사용한 복구
// 파일 앱에서 zip파일만 보이게 설정
let vc = UIDocumentPickerViewController(forOpeningContentTypes: [.archive], asCopy: true)
vc.delegate = self
present(vc, animated: true)
// UIDocumentPickerDelegate 메서드
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// 파일 앱에서 선택한 파일의 URL
guard let src = urls.first else {
showAlert(title: "선택한 파일의 경로를 찾을 수 없습니다.")
return
}
// 저장할 디렉토리 경로
guard let documentURL = getDocumentDirectory() else {
showAlert(title: "저장할 디렉토리의 경로를 찾을 수 없습니다.")
return
}
// 저장할 파일 이름을 포함한 전체 URL
let dst = documentURL.appendingPathComponent(src.lastPathComponent)
if FileManager.default.fileExists(atPath: dst.path) {
showAlert(title: "같은 이름의 파일이 존재합니다.", message: "삭제 후 다시 시도해주세요")
return
} else {
do {
try FileManager.default.copyItem(at: src, to: dst)
showAlert(title: "파일 가져오기 성공", message: "백업 파일을 선택해주세요")
fetchFilesInDocument()
} catch {
showAlert(title: "파일 가져오기 실패")
}
}
}
- URL 객체로 파일 크기, 생성 날짜 얻기
// UITableViewCell Method
func configureCellWithURLResources(url: URL) {
var config = self.defaultContentConfiguration()
do {
let resource = try url.resourceValues(forKeys: [.creationDateKey, .fileSizeKey, .volumeAvailableCapacityForImportantUsageKey])
let sizeString = String(format: "%.2f", Double(resource.fileSize ?? 0) / pow(10, 6))
let date = resource.creationDate
let dateString = date?.formatted(date: .abbreviated, time: .shortened)
config.secondaryText = "\(sizeString)MB / \(dateString ?? "")"
} catch {
print(error)
}
config.text = url.lastPathComponent
config.image = .init(systemName: "folder.fill")
self.contentConfiguration = config
}
- 디렉토리 URL로 저장 가능한 공간 확인하기
guard let documentURL = getDocumentDirectory() else {
showAlert(title: "파일이 저장된 경로를 찾을 수 없습니다")
return
}
do {
let resource = try documentURL.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey])
print(resource.volumeAvailableCapacityForImportantUsage)
} catch {
print(error)
}
이상입니다.
참고 자료 : https://developer.apple.com/documentation/foundation/urlresourcekey/checking_volume_storage_capacity
'TIL' 카테고리의 다른 글
[Sesac IOS] 40일차 TIL (0) | 2022.08.31 |
---|---|
[Sesac IOS] 39일차 TIL (0) | 2022.08.29 |
[Sesac IOS] 37일차 TIL (0) | 2022.08.25 |
[Sesac IOS] 36일차 TIL (0) | 2022.08.24 |
[Sesac IOS] 34~35일차 TIL (0) | 2022.08.22 |