관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 1. 데이터베이스 (Realm) 본문

iOS 실전 (swift)/데이터베이스

[iOS - swift] 1. 데이터베이스 (Realm)

jake-kim 2020. 4. 7. 20:02

1. Realm을 사용하는 이유

 - UserDefaults는 기본적인 데이터 형식(String, int)와 같은 것만 가능하고 느리지만 상대적으로 Realm은 빠르고 유연함

 

 

 

 

 * 그림 출처 :  realm.io 공식홈페이지

 


2. Realm 프레임워크 준비

 1) podfile에 프레임워크 추가 및 인스톨

1
2
pod 'RealmSwift''~> 3.17', :modular_headers => true
pod 'Realm''~> 3.17', :modular_headers => true
 

 

2) framework추가 (framework, Libraries, Embedded Content에 추가)

3) cmd + B : 빌드눌러서 업데이트


3. Realm사용 - CRUD

 - Realm의 데이터베이스 : 클래스 이름으로 만들어짐 (따로 DB를 생성하지 않고 클래스 이름으로 넣음)

 - Realm에 저장될 형식 (Value Object 클래스 정의)

 

실습에 사용될 화면(CRUD)

 

1) 데이터베이스에 저장할 Value Object클래스 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import RealmSwift
 
// Value Object
class Person: Object {
    @objc dynamic var name = " "
    @objc dynamic var age = 0
}
 
...
 
// ViewController 클래스 내
class ViewController: UIViewController {
    var realm: Realm!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        realm = try! Realm()
    }
}
 
 

* Object를 상속받음

* @objc dynamic : 이 키워드가 붙은 변수는 변수의 값이 바뀔 때 Realm에 알리고 DB에 알려주는 기능

* tip : Create, Read, Update, Delete에서 파일에 쓰는 작업은 realm의 권한으로 접근해야함 : realm.write{ "내용" }

 

2) Create

1
2
3
4
5
6
7
8
9
    @IBAction func createAction(_ sender: Any) {
        let person = Person()
        person.name = self.nameTF!.text!
        person.age = Int(self.ageTF!.text!)!
        
        try! realm.write {
            realm.add(person)
        }
    }
 
 

* Realm이 저장된 위치 : print(Realm.Configuration.defaultConfiguration.fileURL!)

 

3) Read

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    @IBAction func readAction(_ sender: Any) {
        
        let list = realm.objects(Person.self)
// print(list)할 시 저장된 정보 확인 가능
 
        if list.count == 0 {
            resultLabel?.text = ""
        }
        
        for item in list {
            resultLabel?.text! += ", name=\(item.name), age=\(item.age)"
        }
        
        // query
        let filterAge = 27
 
        let person = realm.objects(Person.self).filter("age > \(filterAge)")
        print(person.count)
        
    }
 
 

 

4) Update

1
2
3
4
5
6
7
8
9
10
11
12
@IBAction func updateAction(_ sender: Any) {
        
        DispatchQueue(label: "background").async {
            autoreleasepool{
                let realm = try! Realm()
                let person = realm.objects(Person.self).filter("age==27").first
                try! realm.write{
                    person!.age = 3
                }
            }
        }
    }
 
 

 

5) Delete

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    @IBAction func deteleAction(_ sender: Any) {
 
        try! realm.write {
            // 특정 객체 삭제
            realm.delete(realm.objects(Person.self))
 
            // 모든 것 삭제
            realm.deleteAll()
 
            // 쿼리를 통해 선택적 삭제
            let predicate = NSPredicate(format: "year = %d AND month = %d AND day = %d", year, month, day)
            realm.delete(realm.objects(DateRealm.self).filter(predicate))
        }
    }
 
 
 

 

결과) 


 

* 쿼리문 형식

1
2
3
4
let myFilter = NSPredicate(format: "title == %@", title) 
let myFilter2 = NSPredicate(format: "count == %d AND name BEGINSWITH %@""10""B")
let myFilter3 = NSPredicate(format: "count ==\(count)")
let person = realm.objects(Person.self).filter(myFilter)
 

※ 가급적 NSPredicate는 형식 지정자 보다는 '\()'이용하는 것이 안전


4. Realm에서 사진(UIImage형)저장 방법

 UIImage -> Data()

 Data() 형으로 넣을 것

1
2
3
4
5
// UIImage -> Data
let data: Data = image?.jpegData(compressionQuality: 0.9)
 
// Data -> UIImage
let uiImage: UIImage = UIImage(data: imageData)
 

 

5. 데이터 베이스 확인 

1) Realm Browser설치

2) 저장위치 파악 (Realm을 사용한 소스파일에 다음 코드 삽입)

 - 주소 복사

1
print("Realm저장위치=\n\(Realm.Configuration.defaultConfiguration.fileURL!)\n")
 

 

3) terminal 창 실행 후 입력 : open [복사한 주소]

1
open file:///Users/gimjong-gwon/Library/Developer/CoreSimulator/Devices/5A0438EA-9A06-4DC6-936C-A22A16127480/data/Containers/Data/Application/BB28ED06-B96F-4280-A2C7-2981041D1407/Documents/default.realm
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

결과

6. Realm객체를 다른 곳에서도 사용 할 수 있게끔 하는 프로그래밍

- static으로 선언

1
2
3
  // ViewController.swift
    static let shared = ViewController() // realm객체를 다른 곳에서도 접근 가능 : ViewController.shared.realm
    let realm = try! Realm()
 
 
 

 

 

Comments