728x90
반응형
안녕하세요 🙇🏻♂️
저번 포스팅 Core Data에 이어서 이번 포스팅에서는 Realm에 대해 다뤄보겠읍니다!
포스팅은 편의상 편의 말투로 진행함다 😎
Realm이란?
Realm은 모바일과 웹 애플리케이션을 위한 경량의 NoSQL 데이터베이스입니다. 주요 특징은 다음과 같습니다:
- 편리한 데이터 모델링: Realm은 객체 지향적 데이터 모델을 사용합니다. 이를 통해 복잡한 데이터 구조를 간단히 정의하고 조작할 수 있습니다.
- 빠른 성능: Realm은 빠른 데이터베이스 연산을 지원하며, 메모리 내에서 작업을 처리하여 높은 성능을 제공합니다.
- 간편한 사용: Realm은 간단한 API와 자동화된 데이터 동기화 기능을 제공하여 개발자가 복잡한 데이터베이스 관리를 쉽게 할 수 있게 돕습니다.
- 자동 동기화: Realm Cloud를 사용하면 데이터가 자동으로 동기화되며, 이를 통해 여러 디바이스 간의 데이터 일관성을 유지할 수 있습니다.
- 다양한 플랫폼 지원: Realm은 iOS, Android, JavaScript, .NET 등 다양한 플랫폼에서 사용할 수 있습니다.
- 간편한 쿼리: Realm은 강력한 쿼리 기능을 제공하여 데이터 검색과 필터링을 쉽게 할 수 있습니다.
이러한 특성 덕분에 Realm은 특히 모바일 앱 개발자들 사이에서 인기가 많습니다.
제일 중요한 점은 저번 포스팅과 마찬가지로 Local DB라는 점임
Realm의 특징과 사용 방법
- Realm은 모바일 데이터베이스로, 빠르고 사용하기 쉬운 API를 제공합니다. 왜냐하면 Realm은 성능이 뛰어나고, 간단한 설정으로 사용할 수 있기 때문입니다.
- Realm은 객체 지향적인 접근 방식을 사용하여 데이터를 관리합니다. 데이터 모델을 정의하고, 이를 기반으로 객체를 생성하고 관리할 수 있습니다.
- Realm은 데이터의 변경 사항을 자동으로 추적하고, 이를 기반으로 UI를 업데이트할 수 있습니다. 이를 통해 데이터와 UI 간의 동기화를 쉽게 관리할 수 있습니다.
- Realm은 데이터의 영구 저장을 위해 자체적인 저장소를 사용합니다. SQLite와 달리, Realm은 자체적인 저장소 포맷을 사용하여 성능을 최적화합니다.
- Realm의 단점은 Core Data에 비해 기능이 제한적일 수 있다는 점입니다. 하지만 간단한 설정과 빠른 성능을 제공하기 때문에 소규모 프로젝트에 적합합니다.
import RealmSwift
class Dog: Object {
@objc dynamic var name = ""
@objc dynamic var age = 0
}
class RealmManager {
static let shared = RealmManager()
var realm: Realm {
return try! Realm()
}
func addDog(name: String, age: Int) {
let dog = Dog()
dog.name = name
dog.age = age
try! realm.write {
realm.add(dog)
}
}
func getDogs() -> Results {
return realm.objects(Dog.self)
}
}
Realm과 Core Data의 차이점?
Core Data는 Apple의 지원과 통합성을 강조하며 복잡한 데이터 모델을 다루기에 적합합니다. 반면, Realm은 빠른 성능과 간단한 API로 대량의 데이터 처리에 적합하며 다중 플랫폼 호환성을 제공합니다.
요새 기업들은 Realm을 많이 사용하는 추세인듯 보임
Realm 예제
SwiftUI로 예제 구현했고 Realm의 CRUD UIKit이나 SwiftUI나 동일 구현이니 참고 바람!
데이터의 모델
//
// MemoData.swift
// Realm-Example
//
// Created by ukseung.dev on 9/5/24.
//
import Foundation
import RealmSwift
final class MemoData: Object {
@objc dynamic var id = "" // 기본키
@objc dynamic var date = Date()
@objc dynamic var image: Data? = nil
@objc dynamic var memo = ""
override static func primaryKey() -> String? {
return "id"
}
}
View(UI)
//
// ContentView.swift
// Realm-Example
//
// Created by ukseung.dev on 9/5/24.
//
import SwiftUI
import RealmSwift
struct ContentView: View {
@StateObject private var viewModel = MemoViewModel()
@State private var memoText: String = ""
@State private var image: UIImage? = nil
@State private var showingCustomAlert = false
@State private var selectedMemo: MemoData?
@State private var editedMemoText: String = ""
var body: some View {
VStack {
TextField("메모를 입력하세요", text: $memoText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Button("메모 저장") {
let imageData = image?.jpegData(compressionQuality: 0.8)
viewModel.saveMemo(memoText: memoText, imageData: imageData)
}
.padding()
List {
ForEach(viewModel.memos, id: \.id) { memo in
VStack(alignment: .leading) {
Text(memo.memo)
if let imageData = memo.image, let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
.frame(height: 100)
}
Text("\(memo.date)")
.font(.caption)
.foregroundColor(.gray)
}
.onTapGesture {
selectedMemo = memo
editedMemoText = memo.memo
showingCustomAlert = true
}
}
.onDelete(perform: viewModel.deleteMemo)
}
}
.sheet(isPresented: $showingCustomAlert) {
CustomAlertView(
memoText: $editedMemoText,
onSave: {
if let selectedMemo = selectedMemo {
viewModel.updateMemo(memo: selectedMemo, newMemoText: editedMemoText)
}
showingCustomAlert = false
}
)
}
}
}
struct CustomAlertView: View {
@Binding var memoText: String
var onSave: () -> Void
var body: some View {
VStack(spacing: 20) {
Text("Edit Memo")
.font(.headline)
TextField("메모를 입력하세요", text: $memoText)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
HStack {
Button("Cancel") {
// Dismiss the alert
onSave()
}
.padding()
Button("Save") {
// Save the updated memo text
onSave()
}
.padding()
}
}
.padding()
.background(Color.white)
.cornerRadius(20)
.shadow(radius: 10)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black.opacity(0.4).edgesIgnoringSafeArea(.all))
}
}
#Preview {
ContentView()
}
ViewModel
//
// ContentViewModel.swift
// Realm-Example
//
// Created by ukseung.dev on 9/5/24.
//
import Foundation
import RealmSwift
class MemoViewModel: ObservableObject {
private var realm: Realm?
@Published var memos: [MemoData] = []
init() {
// Realm 인스턴스 생성
do {
realm = try Realm()
fetchMemos()
} catch {
print("Error initializing Realm: \(error)")
}
}
// 메모 저장
func saveMemo(memoText: String, imageData: Data?) {
guard let realm = realm else { return } // realm이 nil인지 확인
let memo = MemoData()
memo.id = memoText
memo.memo = memoText
memo.image = imageData
memo.date = Date()
do {
try realm.write {
realm.add(memo)
fetchMemos() // 저장 후 데이터 업데이트
}
} catch {
print("Error saving memo: \(error)")
}
}
// 메모 삭제
func deleteMemo(at offsets: IndexSet) {
guard let realm = realm else { return }
do {
try realm.write {
let objectsToDelete = offsets.map { memos[$0] }
realm.delete(objectsToDelete)
fetchMemos() // 삭제 후 데이터 업데이트
}
} catch {
print("Error deleting memo: \(error)")
}
}
// 메모 수정
func updateMemo(memo: MemoData, newMemoText: String) {
guard let realm = realm else { return }
try! realm.write {
memo.memo = newMemoText
memo.date = Date() // Update the date to the current time when modified
}
fetchMemos() // Refresh the list of memos
}
// 저장된 메모 불러오기
func fetchMemos() {
guard let realm = realm else { return } // realm이 nil인지 확인
let results = realm.objects(MemoData.self)
memos = Array(results)
}
}
결과
CRUD를 예제로 구현 해보았음
Realm을 통해 적재된 데이터들은 시각화하여 볼수도 있음.
ref.
결론
Core Data와 비슷한 Realm을 예제를 통해 확인 해보았고 프로젝트의 상황에 맞게 채택하여 구현하면 될 듯 하다.
소스코드
728x90
반응형
'iOS > Swift' 카테고리의 다른 글
[iOS] Core Data 기본 개념 및 간단 예제 (2) | 2024.08.20 |
---|---|
[Swift] Tuist CLI, 나도 한번 써보자 (0) | 2024.08.13 |
[Swift] Framework,SDK 생성 및 import 하는 방법 (1) | 2024.08.06 |
[Swift] Storyboard없이 CodeBaseUI 코드 구현 (0) | 2024.05.31 |
[Swift] 앱 빌드 오류, failed: Operation not permitted (1) (2) | 2023.11.29 |