iOSアプリ開発でSQLite Databaseを操作するならFMDBを使うと楽で良いです。直接使うのはなかなか大変です。素直にサードパーティ製のライブラリを使いましょう。

ccgus/fmdb

2015/3/20現在、最新のVer2.5を前提に記事を書きます。

  • ライセンスは制約の緩いMIT Licenseです。
  • Objective-Cで書かれていますが、Swiftでも問題なく使えます。

SwiftからFMDBを使えるようにする

  • 上記githubからFMDBをsubmoduleにするなりでプロジェクトから参照できる場所に配置します。
  • src/fmdbにある*.m、*.hファイルをプロジェクトに追加します
  • すでにObjective-CとSwiftが共存しているプロジェクトなら以下の様なBridging Headerファイルがあるはずです。
    • {プロジェクト名}-Bridging-Header.h
  • ここにFMDatabaseをimportするだけです。
#import "FMDatabase.h"

{プロジェクト名}-Bridging-Header.hがない場合。

  • {プロジェクト名}-Bridging-Header.hを作る
  • プロジェクトのBuild SettingsのObjective-C Bridging Headerに作ったヘッダファイル名を入れます
    • 通常プロジェクト名のフォルダ配下にあるので、{プロジェクト名}/{プロジェクト名}-Bridging-Header.hとなるでしょう

fmdb01

Documentディレクトリにあるデータベースファイルのパスを得る

たいていDatabaseファイルはDocumentディレクトリに置くでしょう。DocumentディレクトリにあるDatabaseファイルのパスは以下のようにして取得できます。

var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
// Documentディレクトリ
var dirPath = paths.first! as String
// pathにDocumentディレクトリにあるtest.dbのフルパスを入れる
// dirPathはStringだがNSString#stringByAppendingPathComponentが使える
var path = dirPath.stringByAppendingPathComponent("test.db")
db = FMDatabase(path: path)
if !db.open() {
   // Openできなかった時の処理。たいていパスが違っているとかです。
}

SELECT文

SELECT文などはexecuteQueryメソッドを使います。

// resultSetはFMResultのオブジェクト
// notesテーブルの全レコードを得る
var resultSet = db.executeQuery("SELECT * FROM notes", withParameterDictionary: nil)
while resultSet.next() {
    // idカラムの値を得る
    var id = resultSet.stringForColumn("id")
    // nameカラムの値を得る
    var name = resultSet.stringForColumn("name")
    println("ID:(id) title:(name)")
}

条件、パラメータ指定は以下のようにします。priceが100以上のものを検索しています。

var params = ["price" : 100]
resultSet = db.executeQuery(
    // :priceはparamsのpriceキーの値が展開される
    // paramsを通すことでSQLインジェクション対策にもなる
    "SELECT * FROM notes WHERE price >= :price",
    withParameterDictionary: params)
while resultSet.next() {
    var id = resultSet.stringForColumn("id")
    var name = resultSet.stringForColumn("name")
    println("ID:(id) title:(name)")
}

INSERT文

var now = NSDate()
var insertSQL =
    "INSERT INTO notes (name,price,created_at,updated_at)" +
    " VALUES (:name,:price,:created_at,:updated_at)"

var params = ["name": "note01",
    "price": 100,
    "created_at": now.timeIntervalSince1970,
    "updated_at": now.timeIntervalSince1970]
if !self.db.executeUpdate(insertSQL, withParameterDictionary: params) {
    // エラー時処理。SQL構文エラー、外部キー制約エラーなど
}

UPDATE文

var now = NSDate()
var updateSQL =
    "UPDATE notes SET name = :name,price = :price,updated_at = :updated_at"

var params = ["name": "note01-updated",
    "price": 150,
    "updated_at": now.timeIntervalSince1970]
if !self.db.executeUpdate(updateSQL, withParameterDictionary: params) {
    // エラー時処理。SQL構文エラー、外部キー制約エラーなど
}