관리 메뉴

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

[iOS - swift] 9. SQLite DBMS를 iOS에서 사용방법 (템플릿 이용) 본문

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

[iOS - swift] 9. SQLite DBMS를 iOS에서 사용방법 (템플릿 이용)

jake-kim 2020. 5. 9. 22:05

SQLite Browser툴을 이용하여 필요한 테이블을 먼저 정의 한 후, 이 파일을 "앱 번들"에 저장, 이 템플릿을 "문서 디렉토리"에 저장

* "앱 번들"영역이 아닌, "문서 디렉토리"의 이점 : 앱 업데이트할 시 번들 영역은 데이터들이 덮어쓰이지만 문서 디렉토리는 안전하게 유지됨

 (앱 번들 영역은 .swift파일이 저장되어 있는 영역)

1. 템플릿 DB 생성

1) DB저장 (가급적이면 바탕화면에 저장)

2) 테이블 저장

* 테이블 구성 내용은 

www.ios-development.tistory.com/84 참고

 

2. xcode에서 만든 템플릿 사용

1) 만든 .sqlite파일을 xcode안 폴더에 드래그앤 드롭

- 단 Add to targets에 체크(앱 빌드 시 번들 패키지 과정에 추가시키기 위함)

2) 경로에 파일이 없다면 앱 번들에 만들어 둔 db.sqlite템플릿을 사용, 25~28번라인

 

*리펙토링 전체 코드

 - defer블록 사용 : 함수안에서 return을 만나기 전에 defer블록을 만나게 되면, return 종료 전에 defer블록을 역순(가장 최근에 만난 defer블록)부터 실행한 후 종료되는 것

//
//  ViewController.swift
//  SQLTest
//
//  Created by 김종권 on 2020/05/09.
//  Copyright © 2020 imustang. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
                
        let dbPath = self.getDBPath()
        dbExecute(dbPath: dbPath)
        print("dir = \n\(dbPath)")
    }
    
    /// 기존 DB가 없다면 템플릿의 주소 반환
    func getDBPath() -> String {
        /// 파일매니저객체 -> 앱 내의 디렉토리 탐색 -> "db.sqlite"파일의 디렉토리 획득
        let fileMgr = FileManager()
        let docPathURL = fileMgr.urls(for: .documentDirectory, in: .userDomainMask).first!
        let dbPath = docPathURL.appendingPathComponent("db.sqlite").path
        
        /// 파일이 없다면 앱 번들에 만들어 놓은 db.sqlite가져와서 사용
        if fileMgr.fileExists(atPath: dbPath) == false {
            let dbSource = Bundle.main.path(forResource: "db", ofType: "sqlite")
            try! fileMgr.copyItem(atPath: dbSource!, toPath: dbPath)
        }
        
        return dbPath
    }
        
    /// DB연결 ~ SQL실행 ~ DB연결종료
    func dbExecute(dbPath: String) {
        /// 필수로 필요한 객체 : 각각 DB와 연결할 객체와, 컴파일 된 SQL문을 담을 객체
        var db: OpaquePointer? = nil /// SQLite 연결 정보를 담을 객체
        guard sqlite3_open(dbPath, &db) == SQLITE_OK else {return}
        
        defer {
            print("Close DB Connection")
            sqlite3_close(db)
        }
        
        var stmt: OpaquePointer? = nil
        let sql = "CREATE TABLE IF NOT EXISTS sequence (num INTEGER)"
        guard sqlite3_prepare(db, sql, -1, &stmt, nil) == SQLITE_OK else {return}

        defer {
            print("Finalize Statement")
            sqlite3_finalize(stmt)
        }
        
        if sqlite3_step(stmt) == SQLITE_DONE {print("Success the Crete Table")}
    }
}

Comments