final class PhotoData: Object {
@objc dynamic var id = "" // 기본키
@objc dynamic var date = ""
@objc dynamic var dateAdded = Date() // 새로 추가한 속성
@objc dynamic var image: Data? = nil
@objc dynamic var memo = ""
override static func primaryKey() -> String? {
return "id"
}
}
Primary Key
를 설정해주어야 한다.final class RealmManager {
// Realm 데이터베이스 객체를 생성한다.
let realm = try! Realm()
// 싱글턴 객체로, RealmManager 클래스의 인스턴스를 반환한다.
static let shared = RealmManager()
// PhotoData 객체의 배열
var photoList = [PhotoData]()
// MARK: - Create
func save(photoData: PhotoData, image: UIImage) {
// 저장할 데이터 객체 생성
let newData = PhotoData()
newData.id = UUID().uuidString
newData.date = photoData.date
newData.memo = photoData.memo
newData.image = image.jpegData(compressionQuality: 0.5)
// Realm 데이터베이스에 데이터 저장
try! realm.write {
realm.add(newData)
}
}
func getData(withId id: String) -> PhotoData? {
// 기존 데이터 가져오기
let existingData = realm.objects(PhotoData.self).filter { $0.id == id }.first
return existingData
}
// MARK: - Read
func fetchAll() -> Results<PhotoData> {
let results = realm.objects(PhotoData.self).sorted(byKeyPath: "dateAdded", ascending: false)
return results
}
func fetch(byDate date: String) -> PhotoData? {
let predicate = NSPredicate(format: "date == %@", date)
let results = realm.objects(PhotoData.self).filter(predicate)
return results.first
}
// MARK: - Update
func update(photoData: PhotoData, image: UIImage) {
// 기존 데이터 업데이트
guard let existingData = getData(withId: photoData.id) else {
return
}
do {
try realm.write {
existingData.date = photoData.date
existingData.memo = photoData.memo
existingData.image = image.jpegData(compressionQuality: 0.5)
}
} catch {
print("????")
}
}
// MARK: - Delete
func delete(photoData: PhotoData) {
do {
try realm.write {
realm.delete(photoData)
}
} catch {
print("Error deleting photoData: \(error)")
}
}
}
func save(photoData: PhotoData, image: UIImage)
func getData(withId id: String) -> PhotoData?
func fetchAll() -> Results<PhotoData>
func fetch(byDate date: String) -> PhotoData?
func update(photoData: PhotoData, image: UIImage)
func delete(photoData: PhotoData)
PhotoDetailViewController
@objc func saveButtonTapped() {
...
if diary != nil {
newData.id = diary!.id
let image = photoDetailView.photoImageView.image ?? UIImage()
**realmManager.update(photoData: newData, image: image)**
} else {
// 객체가 존재하지 않으면 새로운 객체로 저장
newData.id = UUID().uuidString
if let image = photoDetailView.photoImageView.image, image != UIImage(named: "addphoto") {
**realmManager.save(photoData: newData, image: image)**
...
photoDetailView.photoImageView.image
값이 nil이 아닌 경우, realmManager.update()
메소드를 사용하여 이미 존재하는 데이터를 업데이트한다.**realmManager.save()**
메소드를 사용하여 새 데이터를 저장한다.PhotoViewController
// numberOfItems() 메소드를 호출하여 데이터 소스의 총 아이템 수를 가져온다.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel.numberOfItems()
}
// PhotoColllecionViewCell과 같은 셀 클래스를 사용하여 셀 객체를 구성하고, 해당 셀에 대한 데이터를 ViewModel객체에서 가져온다.
// 그런 다음, 가져온 데이터를 사용하여 셀을 구성하고 반환한다.
// 셀 객체를 반환하기 전에 셀에 데이터를 할당해야 한다. ViewModel 객체에서 가져온 이미지 데이터를 사용하여 UIImageView의 이미지 속성을 업데이트한다.
// 셀이 컬렉션 뷰에 표시되기 전 해당 셀의 이미지가 설정되어있으므로, 데이터소스가 로드되는동안 셀이 비어있는 것을 방지할 수 있다.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotoCollectionViewCell.identifier, for: indexPath) as? PhotoCollectionViewCell,
let photoData = viewModel.photoData(at: indexPath),
let imageData = photoData.image else { return UICollectionViewCell() }
cell.imageView.image = UIImage(data: imageData)
return cell
}
final class PhotoViewModel {
static let realmManager = RealmManager.shared
// RealmManager 객체를 사용하여 저장된 모든 PhotoData를 가져오는 photos 프로퍼티
var photos: Results<PhotoData>?
// RelamManager 객체를 사용하여 photos 프로퍼티를 초기화
init() {
self.photos = PhotoViewModel.realmManager.fetchAll()
}
// phots의 총 수를 반환
func numberOfItems() -> Int {
return photos?.count ?? 0
}
// IndexPath를 통해 해당하는 PhotoData 객체를 반환
// UICollecionView의 cellForItemAt 메서드에서 사용
func photoData(at indexPath: IndexPath) -> PhotoData? {
return photos?[indexPath.row]
}
}