날씨, 사진과 함께 기록하는 일기장 어플을 개발하는 중,
Core Data에 이미지를 저장하는 방법이 필요해서 많은 자료를 찾아봤습니다.
영어로 된 자료는 꽤 찾을 수 있었지만, 한글로 정리된 내용은 없는 것 같아
저처럼 오랜 시간 동안 찾아 헤매지 마시고 금방 해결하실 수 있도록 정리해보려 합니다.
그대로 따라하시면 됩니다.
따라 하시다가 혹시나 안되실 분들을 위해 최하단에 프로젝트 파일도 올려놓도록 하겠습니다. 압축파일 받아서 실행하시면 됩니다.
1. 프로젝트 생성 시, Core Data 박스를 체크합니다.
제 프로젝트명은 CoreDataSaveImage2입니다. (1은 오류 나고 시행착오를 겪느라...)
만약 Core Data를 체크하지 않으시고 생성하셨다면, https://zeddios.tistory.com/987 글의 중하단 부분을 참고하셔서 추가해주시면 됩니다. (저도 엄청 많이 찾다가 해결법을 찾게 됐습니다.)
2. 하단 이미지처럼 컴포넌트들을 배치합니다.
Open Image버튼을 UIImageView와 겹치게 배치 후,
Control을 눌러 드래그 앤 뒤 Leading, Trailing, Top, Bottom을 클릭해주시면 됩니다.
Control 드래그앤 드랍한 뒤, 하단 이미지처럼 이름을 정해줍니다.
회색 박스 부분은 추후에 추가할 내용이기 때문에 아직 없는 게 당연합니다.
Open Image 버튼 - @IBAction pickImageButtonPressed
Save Image 버튼 - @IBAction saveImageButtonPressed
Retrieve Image from Core Data 버튼 - @IBAction retrieveButtonPressed
3. "프로젝트명.xcdatamodeld" 파일에 들어간 뒤, 하단 이미지의 순서를 그대로 따라 하면 됩니다.
이미지를 Core Data에 저장하려면 다양한 타입 중, Binary Data 타입으로 해야 한다고 합니다. (stack overflow에 이와 관련해서 글이 있으니 참고하시기 바랍니다.)
4. Editor - Create NSMangaedObject Subclass를 클릭합니다.
5. ViewController.swift 파일로 돌아갑니다.
네모 박스 된 부분을 추가합니다. import CoreData를 빠트리면 안 됩니다!
(UINavigationControllerDelegate 추가 부분은 6번 작업을 진행하면서 에러 해결 버튼을 누르면 해결됩니다.)
6. ViewController.swift 파일의 최하단에 extension코드를 추가합니다.
에러를 해결하라고 뜨고, 에러 해결 버튼을 누르면 5번의 UINavigationControllerDelegate가 추가됩니다.
extension ViewController: UIImagePickerControllerDelegate {
func openImagePicker() {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
dismiss(animated: true, completion: nil)
if let img = info[.originalImage] as? UIImage {
self.imageView.image = img
}
}
}
pickImageButtonPressed에 self.openImagePicker() 메서드를 호출합니다.
여기까지 진행 후 실행하면, 아래 이미지처럼 갤러리 사진을 잘 보여줍니다.
그럼 이제 저장버튼을 하러 갑시다!
7. Save Image 버튼 - @IBAction saveImageButtonPressed부분을
하단 코드처럼 추가합니다.
이 코드를 통해, 이미지 attribute를 이용해 사진 개체의 instance를 만들고 Core Data에 저장할 수 있게 해 줍니다.
@IBAction func saveImageButtonPressed(_ sender: UIButton) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let photo = NSEntityDescription.insertNewObject(forEntityName: "Photo", into: context) as! Photo
let png = self.imageView.image?.pngData()
photo.image = png
do {
try context.save()
} catch let error {
print(error.localizedDescription)
}
}
하단 글을 참고하셔서, 본 글의 7번 코드를 수정하시길 매우 권장합니다!
만약 수정하지 않으신다면 CoreData 이미지 뒤집힘 문제를 겪으시게 됩니다.
https://developer-p.tistory.com/149
8. Retrieve Image from Core Data 버튼 - @IBAction retrieveButtonPressed부분을
하단 코드처럼 추가합니다.
@IBAction func retrieveButtonPressed(_ sender: UIButton) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Photo")
do {
arrPhotos = try context.fetch(fetchRequest) as? [Photo]
if let photo = arrPhotos?.last {
imageView.image = UIImage(data: photo.image!)
}
} catch let error {
print(error.localizedDescription)
}
}
이미지를 선택하고 Save Image버튼을 눌러 저장한 뒤,
앱을 다시 실행하고 Retrieve Image from Core Data버튼을 눌러보면 하단 이미지처럼 잘 실행되는 걸 확인할 수 있습니다.
https://developer-p.tistory.com/149
Core Data에 이미지를 저장하는 방법을 지금까지 알아봤습니다.
되게 많은 자료를 찾아보고, 영상을 보고 따라도 해봤는데 잘 작동하지 않아서 꽤 애를 먹었던 내용입니다.
아래는 제가 참고한 자료들 중 일부입니다.
유튜브 파일은 제가 잘못 따라 했는지 에러가 나면서 실행되지 않았고,
https://www.youtube.com/watch?v=fQp17kDeRTU
제 글뿐만 아니라, medium 글을 참고하셔도 좋을 것 같습니다.
https://cb510.medium.com/saving-images-to-core-data-in-ios-473b92d5fd4f
제 글을 잘 따라 하셨다면 문제없이 작동할 겁니다.
혹시나 안되실 분들을 위해 프로젝트 파일을 올려놓도록 하겠습니다.
제 글을 보고 도움이 되셨으면 좋겠습니다.
최근댓글