- Swift 5 기준
일반 메모나 할일 앱처럼 Device 내부에 이미지를 저장하고 불러와 사용할 때가 있죠. 싱글톤을 활용해 간편하게 사용할 수 있는 방법을 공유합니다.
Save Image
우선 ImageFileManager
라는 class 를 만들어서 싱글톤으로 활용해요. 그리고나서 Device Document에 이미지를 저장해볼게요.
class ImageFileManager {
static let shared: ImageFileManager = ImageFileManager()// Save Image
// name: ImageName
func saveImage(image: UIImage, name: String,
onSuccess: @escaping ((Bool) -> Void)) { guard let data: Data
= image.jpegData(compressionQuality: 1)
?? image.pngData() else { return } if let directory: NSURL =
try? FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false) as NSURL {
do {
try data.write(to: directory.appendingPathComponent(name)!)
onSuccess(true)
} catch let error as NSError {
print("Could not saveImage🥺: \(error), \(error.userInfo)")
onSuccess(false)
}
}
}
}
사용방법은 아래와 같아요. Image File Name 을 매번 지정해줄 수 없으니까 간편한 방법으로 unique name을 만들어 줄 수 있는 코드를 쓸거예요.
// UniqueName.jpeg
let uniqueFileName: String
= "(ProcessInfo.processInfo.globallyUniqueString).jpeg"ImageFileManager.shared
.saveImage(image: image,
name: uniqueFileName) { [weak self] onSuccess in
print("saveImage onSuccess: \(onSuccess)")
}
onSuccess 일 때 이후에 필요한 처리를 해주면 되겠죠? 이후에 저장된 이미지를 불러오려면 저장할 때 사용했던 uniqueFileName
를 알고 있어야해요.
Get Image
그럼 저장했던 image를 불러오는 코드를 알아볼게요. ImageFileManager
에 계속해서 아래 코드를 추가해요.
// named: 저장할 때 지정했던 uniqueFileName
func getSavedImage(named: String) -> UIImage? {
if let dir: URL
= try? FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false) { let path: String
= URL(fileURLWithPath: dir.absoluteString)
.appendingPathComponent(named).path let image: UIImage? = UIImage(contentsOfFile: path)
return image
} return nil
}
그럼 가져온 이미지를 보여줄 수 있는 샘플 코드를 볼게요.
if let image: UIImage
= ImageFileManager.shared.getSavedImage(named: "fileName") {
imageView.image = image
}
image를 저장하고, 가져오기까지 했으니 이제 삭제 해 볼까요?
Delete Image
Delete 도 마찬가지로 imageName을 알고 있어야해요. ImageFileManager
에 아래 코드를 추가할게요. document에서 해당 fileName이 있는지 확인하고, 있으면 삭제하는 로직이예요.
func deleteImage(named: String,
onSuccess: @escaping ((Bool) -> Void)) { guard let directory =
try? FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false) as NSURL
else { return } do {
if let docuPath = directory.path {
let fileNames = try
FileManager.default.contentsOfDirectory(atPath: docuPath)
for fileName in fileNames {
if fileName == named {
let filePathName = "\(docuPath)/\(fileName)"
try FileManager.default.removeItem(atPath: filePathName)
onSuccess(true)
return
}
}
}
} catch let error as NSError {
print("Could not deleteImage🥺: \(error), \(error.userInfo)")
onSuccess(false)
}
}
그럼 아래처럼 delete가 잘 되는지 테스트해볼게요.
ImageFileManager.shared.deleteImage(named: url) { onSuccess in
print("delete = \(onSuccess)")
}
참 쉽죠? 🙆♀️
Conclusion
이제껏 만들었던 앱은 항상 이미지를 서버에 보내고, 서버에서 url을 받아와 보여주는 형태였기 때문에 내부 document에 이미지를 저장하고, 불러오는걸 공부해봤어요.
유틸리티 앱에서는 이것보다 파일을 관리하는 더 좋은 방법이 있을 수 있을 것 같아서 개발하게되면 공부를 더 해보려고 합니다. 😃