본문 바로가기

ios

Use Realm in Swift

아이폰 내부에서 자료를 저장해야 될 필요가 생겼습니다.
CoreData는 사용할 생각도 안했고, UserDefaults, SQLite 직접 사용등을 고민하다 Realm이란 오픈소스 데이터베이스를 발견하여 사용해보기로 하고 샘플 코드를 작성해 보았습니다. 다음 링크를 가보면 알 수 있지만 Java, Kotlin, Swift, Objective-C, JavaScript에서 사용이 가능할 정도로 많은 플랫폼을 지원해주고 있으며, ORM형태로 코드를 작성하여 데이터를 관리합니다. 여러 글들을 읽어보면 속도가 아주 빠르다고 합니다. 그래서 사용해보자고 결심했습니다. ㅎㅎ

https://realm.io/kr/products/realm-database/ 

 

Realm Database

Loved by developers and more than two billion users, Realm Database is fast, easy to use, open source, and totally free.

realm.io

일단 사용하기 위해서는 다음과 같이 설치를 진행해야 합니다. 저는 CocoaPods를 통해 설치하였습니다.
Podfile에 다음과 같이 작성하고

# Realm is a modern data framework & database for iOS, macOS, tvOS & watchOS.
pod 'RealmSwift'

pod instal 명령을 실행하여 설치를 진행합니다.

다음과 같이 Data Model을 작성해줍니다.

//
//  LocationInfo.swift
//  Sample
//
//  Created by francis on 2020/04/10.
//  Copyright © 2020 Aircook. All rights reserved.
//

import RealmSwift

@objcMembers class LocationInfo: Object, NSCopying {
    
    dynamic var id: Int = 0
    dynamic var latitude: String = "0.0000000"
    dynamic var longitude: String = "0.0000000"
    
    func copy(with zone: NSZone? = nil) -> Any {
        let copy = LocationInfo()
        copy.latitude = self.latitude
        copy.longitude = self.longitude
        
        return copy
    }
    
    override static func primaryKey() -> String? {
        return "id"
    }
    
    func autoIncrementKey() -> Int {
           let realm = try! Realm()
           return (realm.objects(LocationInfo.self).max(ofProperty: "id") as Int? ?? 0) + 1
       }
}

그리고 다음과 같이 작성한 Model을 이용하여 다음 코드로 테스트를 진행하였습니다.

//
//  AppDelegate.swift
//  Sample
//
//  Created by francis on 2020/04/08.
//  Copyright © 2020 Aircook. All rights reserved.
//

import UIKit
import Device
import RealmSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // Override point for customization after application launch.
        
        Logger.debug("application start..")
        
        Logger.debug("device is simulator \(Device.isSimulator())")

        Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 1)
        
        Logger.debug("realm file url is \(Realm.Configuration.defaultConfiguration.fileURL!)")
        Logger.debug("realm schema version is \(Realm.Configuration.defaultConfiguration.schemaVersion)")
        Logger.debug("realm configuration is \(Realm.Configuration.defaultConfiguration)")

        let realm = try! Realm()
        
        //Delete All
        try! realm.write {
            realm.deleteAll()
        }
                
        // Create
        try! realm.write {
            for _ in 1 ... 10 {
                //새로운 객체를 만들고, 자동증가값 PK를 셋팅한다.
                let newLocationInfo: LocationInfo = LocationInfo()
                newLocationInfo.id = newLocationInfo.autoIncrementKey()
                newLocationInfo.latitude = String(format: "%.7f",  Double.random(in: 37.5100000 ..< 37.5199999))
                newLocationInfo.longitude = String(format: "%.7f",  Double.random(in: 126.9800000 ..< 126.9899999))
                //Adds an unmanaged object to this Realm.
                realm.add(newLocationInfo, update: .all)
            }
        }
        
        // Read All
        let locationInfos = realm.objects(LocationInfo.self)
        for locationInfo in locationInfos {
            Logger.debug("locationInfo id is \(locationInfo.id)")
            Logger.debug("locationInfo latitude is \(locationInfo.latitude)")
            Logger.debug("locationInfo longitude is \(locationInfo.longitude)")
        }
        
        // Read 10th Info, Read by Predicate
        if let tenthLocationInfo = realm.objects(LocationInfo.self).filter("id=10").first {
            Logger.debug("locationInfo id is \(tenthLocationInfo.id)")
            Logger.debug("locationInfo latitude is \(tenthLocationInfo.latitude)")
            Logger.debug("locationInfo longitude is \(tenthLocationInfo.longitude)")
        }
        
        // Update, Read by Index
        let tenthLocationInfo = realm.objects(LocationInfo.self)[9]
        try! realm.write {
            tenthLocationInfo.longitude = "126.0000000"
        }
        Logger.debug("locationInfo id is \(tenthLocationInfo.id)")
        Logger.debug("locationInfo latitude is \(tenthLocationInfo.latitude)")
        Logger.debug("locationInfo longitude is \(tenthLocationInfo.longitude)")

        // Delete
        if let firstLocationInfo = realm.objects(LocationInfo.self).first {
            try! realm.write {
                realm.delete(firstLocationInfo)
            }
        }
        
        return true
    }

}

App Store에서 Realm Browser를 이용하여 다음과 같이 결과를 확인 할 수 있습니다.

'ios' 카테고리의 다른 글

Location updates in Background Modes  (0) 2020.04.19
Migration in Realm  (0) 2020.04.18
Tab Bar 사라지게 하는 방법  (0) 2020.04.03
WKWebView  (5) 2018.02.14
Objective-C 메모리 관리  (1) 2011.06.13