-
[iOS] FMDB 사용하기iOS/EARLY BUDDY | iOS 2020. 8. 14. 15:58
안녕하세요 :)
오늘은 얼리버디 어플에 최근에 검색한 주소 저장 부분을 FMDB를 사용해서 구현해보려고 합니다.
FMDB란?
FMDB는 SQLite를 Object-C로 감싼 것입니다.
즉, XCode에서 코드로 SQLite를 사용할 수 있게 해주는 것입니다.
FMDB 사용 설정
우선, FMDB Github에 들어가면 Cocoapod으로도 설정을 할 수 있다고 합니다.
저는 클론 받은 후에 fmdb 폴더를 직접 옮긴 방법을 사용했습니다.
첫 번째로 프로젝트에 프레임워크를 추가해줍니다.
프로젝트의 Build Phases -> Link Binary With Libraries에 + 버튼을 누르고
sql을 검색하면 sqlite가 두 개가 검색됩니다.
둘 중 아무거나 Add 해주시면 sqlite 프레임워크가 추가됩니다.
그 후 Source Control -> Clone.. 을 클릭해준 후 https://github.com/ccgus/fmdb를 입력해서 fmdb를 클론 받습니다.
클론을 받아서 fmdb 프로젝트를 열어보면 src 폴더 안에 fmdb라는 폴더가 있을 텐데 fmdb 폴더만 FMDB를 적용할 프로젝트에 끌어옵니다.
그 후에 프로젝트 내에서 fmdb 폴더 안의 info.list 파일을 삭제해주고, 헤더 파일을 하나 생성해줍니다.
저는 bridging-header.h라는 파일을 생성해줬습니다.
#ifndef bridging_Header_h #define bridging_Header_h #endif /* bridging_Header_h */ #import "FMDB.h"
그리고 해당 헤더 파일 제일 하단에 #import "FMDB.h"라는 문구를 추가해줍니다.
그 후에 프로젝트 설정을 들어가 줍니다.
Build Settings에서 Swift Compiler - General에서 Object-C Bridging Header에 방금 만든 헤더 파일 경로를 추가해줍니다.
여기까지 해주면 환경 설정은 완료했습니다!
FMDB 사용하기
데이터베이스 생성하기
var databasePath = String()
우선 데이터베이스 경로를 저장할 변수를 선언해줍니다.
let fileManager = FileManager.default let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let docsDir = dirPath[0]
그 후에 파일 매니저를. default로 설정합니다.
FileManager는 파일 시스템의 내용을 검사하거나 변화시킬 때 사용합니다.
저는 iOS 내장 파일을 사용할 것이기 때문에 FileManager를 선언해줍니다.
그 후에 디렉터리 경로를 저장할 상수와, 문서 경로를 저장할 상수를 선언해줍니다.
databasePath = docsDir.appending("/RecentSearch.db")
다음에 저는 데이터베이스 이름을 최근 검색을 의미하는 RecentSearch로 만들었습니다.
처음에 선언했던 데이터베이스 경로에 문서 경로 + /RecentSearch.db를 더하여 넣어줍니다.
if !fileManager.fileExists(atPath: databasePath) { let recentLocationDB = FMDatabase(path: databasePath) if recentLocationDB.open() { let createSql = "CREATE TABLE IF NOT EXISTS RecentLocation (ID INTEGER PRIMARY KEY AUTOINCREMENT, LOCATION TEXT)" if !recentLocationDB.executeStatements(createSql) { print("Error: recentLocationDB execute Fail, \(recentLocationDB.lastError())") } recentLocationDB.close() } else { print("Error: recentLocationDB open Fail, \(recentLocationDB.lastError())") } } else { print("recentLocationDB is exist") }
그리고 데이터베이스 중복 생성을 방지하기 위해서 해당 데이터베이스 경로에 파일이 존재할 경우에 FMDatabase를 만들어주고, 테이블 생성 sql문을 executeStatements에 넣어줍니다.
최근 검색 주소 개수 조회하기
저는 테이블 뷰의 셀 개수를 최근 검색 개수로 받아와야 하기 때문에 개수를 조회해야 했습니다.
(셀은 최대 20개까지 보입니다.)우선 UITableViewDataSource에 있는 함수 중에 numberOfRowsInSection 함수 부분에 데이터베이스 조회 기능을 추가해주었습니다.
if recentLocationDB.open() { let selectSql = "SELECT COUNT(*) FROM RecentLocation" do { let result = try recentLocationDB.executeQuery(selectSql, values: []) if result.next() { countRow = Int(result.int(forColumn: "COUNT(*)")) print("result = \(countRow)") } } catch { print("Error") } } else { print("Error: recentLocationDB open Fail, \(recentLocationDB.lastError())") }
아까 만들었던 데이터베이스를 오픈하고, 만약 오픈되지 않았다면 에러 메시지를 출력합니다.
오픈한 후에 SELECT COUNT 구문인 sql문을 executeQuery 부분에 넣어주고 values는 넣어주지 않습니다.
values는 sql문에 따로 삽입할 값들이 있을 때 사용합니다. 저는 COUNT 문으로 RecentLocation 테이블의 모든 칼럼 개수를 세서 반환할 것이기 때문에 values는 사용하지 않았습니다.
최근 검색 주소 검색
셀 개수를 반환해주었다면 데이터를 넣어줘야 할 것입니다.
위의 개수 조회와 쿼리문만 다르고 다른 것은 동일합니다.
if recentLocationDB.open() { let selectSql = "SELECT Location FROM RecentLocation WHERE rowId = \(indexPath.row + 1)" do { let result = try recentLocationDB.executeQuery(selectSql, values: []) if result.next() { recentLocationCell.recentSearchLocation.text = result.string(forColumn: "Location") print("result = \(result.string(forColumn: "Location"))") } } catch { print("Error") } } else { print("Error: recentLocationDB open Fail, \(recentLocationDB.lastError())") }
이렇게 rowId를 사용해서 데이터를 조회해줍니다.
주의할 점은 rowId가 1부터 시작이기 때문에 indexPath.row에 1을 더해줘야 한다는 것입니다.
최근 검색 주소 저장
그리고 검색 창에서 주소를 검색하면 검색한 스트링이 테이블에 ID 값과 같이 저장시키려고 합니다.
if recentLocationDB.open() { let insertSql = "INSERT INTO RecentLocation (Location) values ('\(searchText)')" let result = recentLocationDB.executeUpdate(insertSql, withArgumentsIn: []) if !result { print("Error: recentLocationDB add Fail, \(recentLocationDB.lastError())") } } else { print("Error: recentLocationDB open Fail, \(recentLocationDB.lastError())") }
위와 같이 insert 쿼리문을 저장하는 상수를 선언하고, 이번에는 executeUpdate를 통해 값을 테이블에 넣어줍니다.
마무리하기
아직 쿼리문을 더 수정해야 완벽하게 최근 검색한 주소 20개만 가져오는 기능을 완성하게 되지만, 우선 제가 사용했던 FMDB 사용법에 대해 알아봤습니다!
감사합니다 :)
'iOS > EARLY BUDDY | iOS' 카테고리의 다른 글
[iOS] 테이블 뷰 셀 안에 컬렉션 뷰 넣기 (0) 2020.08.28 [iOS] FMDB를 사용한 최근 장소 검색 기능 구현 (0) 2020.08.15 [iOS] Coordinator Pattern 적용 (0) 2020.07.31