오랜만에 저녁 산책해보ㅆ습ㄴ ㅣㄷr... 🍺🍺🍺

 

 

안녕하세요!

 

오늘은 Realm에 대해서 알아보겠습니다.

(어떻게 읽어야 할까... 영어 울렁증이.. 😵‍💫😵‍💫)

 

 

iOS Database 종류는 다양하죠!

CoreData, Realm, SQLite..

제가 Realm을 선택한 이유가 뭘까요❓

 

👍 첫 번째로 인기가 많다는 점  

여러 가지 프로젝트에 투입되었을 때 인기가 많기 때문에 만날 확률이 높겠죠

 

✌️ 두 번째로 호환성입니다. 

CoreData가 iOS에서만 사용된다면

Realm은 안드로이드에서도 사용되기 때문이죠.

 

 

Realm Swift

Fast, Swifty data storage

realm.io

 

위의 Realm Swift의 설명과 같이 SQLite, Core Data의 대안으로 사용되기 쉽고,

Swift객체로 직접 작업하는 것처럼 간단하게 데이터 처리가 가능하다고 소개하고 있습니다.

 

여기서 TMI 🙋‍♂️🙋‍♂️🙋‍♂️

 

Realm은 MongoDB에 인수되었으며

MongoDB와 마찬가지로 NoSQL입니다.

NoSQL은 No SQL 관계형 DB를 사용하지 않는다 라는 뜻이 아닌

Not Only SQL의 약자라고 합니다.

데이터를 저장하는데 SQL 외에 여러 유형의 DB를 사용한다고 합니다.

 

 


📚 Realm 라이브러리 설치

 

Swift PackagManager 

 

https://github.com/realm/realm-swift.git

 


Cocoa Pods

 

platform :ios, '12.0'
target 'MyRealmProject' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  # Pods for MyRealmProject
  pod 'RealmSwift', '~>10'
end

 

 

[iOS/Swift] 외부 라이브러리 관리 - CocoaPods, Swift Package Manager(SPM)

오늘은 iOS 프로젝트 외부 라이브러리 관리 또는 프로젝트 종속성을 관리하기 위한 두 가지 도구를 소개하려고 합니다. 💁‍♂️💁‍♂️ CocoaPods(코코아팟) / Swift PackageManager(SPM) 두둥! 왜 하필

salmonpack.tistory.com

 

 


🛠️ Realm Studio

 

Realm Studio는 Realm 데이터를 한눈에 볼 수 있게 도와주고 

물론 수정 추가도 가능합니다.

 

Realm Studio - Realm Sync (LEGACY)

During development, you may want to export your schema for consistency and ease of use across definitions. For example, you may have already created your schema in an existing iOS application and now need to declare the same schema in your Android app. Cre

docs.realm.io

 


 

💻 시뮬레이터로 빌드하는 경우

 

print("realm 위치 \(Realm.Configuration.defaultConfiguration.fileURL!)")

 

 

위와 같이 Realm.Configuration.defaultConfiguration.fileURL을 통하여 

Realm 위치 정보를 찾아줍니다. 

 

 

 

 

 

 

 

 

realm 위치 file:///Users/chankyuhwang/Library/Developer/CoreSimulator/Devices/9D4CCDB5-F1E7-44C7-9199-BF5BAFFE869D/data/Containers/Data/Application/32312FF7-AF36-43EF-A216-8F3321463768/Documents/default.realm

 

Finder > 폴더로 이동... > file::/// ~ Documents까지의 위치로 이동하여 

.realm 파일을 찾아 열어줍니다.

 

.realm 파일 Open

 

해당 디렉터리로 이동하면 default.realm 파일을 볼 수 있는데요. 

해당 파일을 열어주시면 만든 프로젝트의 Realm 데이터를 한눈에 확인 가능 합니다.  👀

 

 

Realm 데이터를 한눈에 확인하는 것뿐 아니라

데이터 삭제/추가 기능도 가능합니다.

 

 


 

📱 아이폰으로 빌드하는 경우

 

Xcode에서 해당 프로젝트를 빌드합니다.

 

혹시 기기에서 빌드를 처음 하시거나, 오류가 발생 시 참고

 

[Xcode] 앱 빌드, 내 아이폰에서 실행

Xcode를 이용하여 나만의 앱을 만들었습니다. 그렇다면 내 아이폰에 직접 빌드하여 확인하고 싶죠!! 자 이제 손에 든 아이폰에 직접 빌드하러 가봅시다! 맥북과 아이폰을 연결시키고 연결된 아이

salmonpack.tistory.com

 

프로젝트 빌드 > Window > Device and Simulators 

해당 프로젝트 앱 선택 > Download Container... 

 

 

저장한 파일 경로로 이동 > 패키지 내용 보기

AppData > Documents > .realm 파일 Open

 

이렇게 default.realm 파일을 열게 된다면

위에서 보여드렸던 시뮬레이터의 경우와 동일하게 Realm 파일을 열 수 있습니다.

 

 


Realm의 데이터 모델 만들기 

 

아래 소스를 보시면 @Persisted를 발견하실 수 있습니다.

이전 버전에서는 @obcj dynamic var를 사용했다고 합니다.

 

하지만 최근 Realm 공식 문서에서는 @Persisted를 사용한다고 합니다.

또한 Realm 공식 Twitter에서도 언급이 있었네요!

👉  https://twitter.com/realm/status/1414633070683115527

 

import RealmSwift

class RealmWeatherData: Object {
	@Persisted(primaryKey: true) var date: String = ""
	@Persisted var sky: String = ""
	@Persisted var tem: String = ""
}

 

Persist란 집요하게 하다, 계속(지속)되다는 뜻이 있습니다. 

질척 질척

 

즉 앱의 상태와 상관없이 Realm 데이터는 

지속적이고 집요하게 계속되어야 한다는 뜻이지요. 

 

 

 


CRUD

 

Create

추가 작업은 realm.write { } 블록 안에서 진행해야 합니다.

 

final public class WeatherViewModel: ObservableObject {
    ...
   
    // Realm 가져오기 
    let realm = try! Realm()
     // Realm에 저장하기
     func saveRealmData(_ data: RealmWeatherData) {
        try! realm.write{
            realm.add(data)
        }
    }
    
    ...
}

 

어때요? 차암 쉽죠? 👨‍🎨🎨 

 


 

Read

이 단계에서 원하는 내용만 필터링하거나 정렬하는 등 원하는 형태로 변형할 수 있습니다.

.filter() 또는 .sorted()를 활용한다면요!

 

final public class WeatherViewModel: ObservableObject {
    ...
    
    // RealmWeatherData 객체 가져오기
    func getRealmData() {
        let getWeatherData = realm.objects(RealmWeatherData.self)
        print(getWeatherData)
    }
    // 필터링 데이터 
    func getFilterData() {
    	let filterData = realm.objects(RealmWeatherData.self)
                             .filter("date = '202030503'")
    }
    // sort (byKeyPath-정렬 기준 key, ascending-오름차순)
    func getSortData() {
    	let sortedData = realm.objects(realmWeatherData.self)
                            .sorted(byKeyPath: "date", ascending: true)
    }
    ...
}

 

 

struct ContentView: View {
    @ObservedObject var weatherViewModel: WeatherViewModel = WeatherViewModel()

var body: some View {
        TabView {
        	...
        }
        .onAppear {
            // 저장할 객체 만들기
            let testData = RealmWeatherData()
            testData.date = "20230503"
            testData.sky = "맑음"
            testData.tem = "24"
            
            let testData2 = RealmWeatherData()
            testData2.date = "20230502"
            testData2.sky = "흐림"
            testData2.tem = "23"
            
            let testData3 = RealmWeatherData()
            testData3.date = "20230501"
            testData3.sky = "비옴"
            testData3.tem = "17"
            
            self.weatherViewModel.saveRealmData(testData)
            self.weatherViewModel.saveRealmData(testData2)
            self.weatherViewModel.saveRealmData(testData3)
            self.weatherViewModel.getRealmData()
        }
    }
}

 

 

 

 

 


 

Update

동작은 Create와 같습니다.

또한 realm.write { } 블록 안에서 진행해야 하죠!

 

final public class WeatherViewModel: ObservableObject {

    ...
    
	// .add를 이용한 update
	func updateAddRealmData(_ data: RealmWeatherData) {
		try! realm.write {
			realm.add(data, update: .modified)
		}
	}
    
	// Realm 객체를 이용한 update
	func updateRealmData(_ data: RealmWeatherData) {
		let getWeatherData = realm.objects(RealmWeatherData.self)
		let selectWeatherData = getWeatherData.filter("date == '20230503").first

		try! realm.write{
			selectWeatherData?.sky = "Change SKY"
		}
	}
    
    ...
}

 

.add()를 이용하는 방법과

Realm객체를 변수로 받아 해당 속성값에 직접적으로 접근하여 Update 하는 방법

두 가지를 활용해 봤습니다.

 


 

Delete

Delete는 더 쉽습니다.

realm.delete(삭제할 Object) 끝!!!

 

final public class WeatherViewModel: ObservableObject {
    ...
	// Realm 삭제 
	func deleteRealmData(_ date: String) {
		guard let getWeatherData = realm.objects(RealmWeatherData.self).filter("date == '\(date)'").first else { return }
        
		try! realm.write {
			realm.delete(getWeatherData)
		}
	}
    ...
}

 

 


여기까지 저의 긴 글을 읽어주셔서 감사합니다.

제가 습관적으로 코딩을 하는 그날까지 습관적으로 코딩을 하기 위해 글 작성을 꾸준하게 해보겠습니다.

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기