iOSでRealmのデータファイルの場所の見つけ方
初期データのあらかじめ入ったRealmのファイルを用意しておき、
アプリに組み込んで使いたいと思っています。
それにはデータが入ったDBのファイルが必要です。
Realmの保存場所を特定する方法をメモしておきます。
前提
環境はXcode9.2、Swift4.0を使用しています。
初期データ作成用のXcodeプロジェクトを作っておきます。
実機かシミュレーターにRunしておきます。
参考サイト様
ありがとうございます!!!
https://realm.io/docs/swift/latest/#copying-objects-between-realms
How to find my realm file? - Stack Overflow
シミュレーターにインストールした場合の場所
// DBのファイルの場所 print(Realm.Configuration.defaultConfiguration.fileURL!)
このコードでファイルパスを表示してくれます。
これをコピーします。
finderを開いてCommandキー+Shiftキー+Gを押します。
先ほどのパスを貼り付けます。
先頭の「file://」は削除して移動します。
実機にインストールした場合
Xcodeのメニューから Window > Devices and Simulators を選択します。
実機にインストールされているアプリが一覧で表示されます。
アプリを選択します。
左下の設定アイコンをクリック > “Download Container…“を選択します。
保存ダイアログが開きます。プロジェクトルートがデフォルトの保存場所になっています。
◯◯.xcappdataという名前がセットされているのでそのまま保存します。
Finderで保存した場所を開きます。
◯◯.xcappdataを右クリックして「パッケージの内容を表示」(英語表示の場合「“Show Package Contents”」)をクリックします。
ここにあります。
AppData / Documents / default.realm
以上です。
iOSのNsPredicateを使ってスペース区切りの文字列の検索条件を指定する&RealmでDBから読み込むメモ
こんにちは。自分の勉強メモです。
間違っていたらお声がけ下さると嬉しいです(●´ω`●)
前提
環境はXcode9.2、Swift4.0を使用しています。
Realmを使ったDBの処理を書いている最中です。
やりたいこと
よくあるキーワード検索がやりたいです。
・スペース区切りの文字列を入力された時に、スペースで文字列を分割する。
・対象のフィールドに分割した文字列がそれぞれ含まれているものを抽出する。
このように検索条件を入力したとすると
SQL文は次のようになります。
SELECT "foods".* FROM "foods" WHERE (("foods"."name" LIKE '%たま%' OR "foods"."search_word" LIKE '%たま%') AND ("foods"."name" LIKE '%豆%' OR "foods"."search_word" LIKE '%豆%'))
この例では"foods"というテーブルから"name"または"search_word"というフィールドに
入力した文字列があった時にデータが抽出されます。
検索条件を指定するには
NsPredicateクラスを使っての検索条件を指定するのが定石のようです。
RealmでもNsPredicateがサポートされておりNSPredicate Cheatsheetという資料が用意されています。
NSPredicate Cheatsheet
前処理
検索する文字列をスペースで分割して配列に入れておきます。
有効な文字列が入っている前提です。
let words = " たま 豆" // 全角スペースを半角スペースに置き換え余計なスペースはトリムする let newWords = words.replacingOccurrences(of: " ", with: " ").trimmingCharacters(in: .whitespacesAndNewlines) // componentsメソッドで指定の区切り文字で配列に分割する let wordsArray = newWords.components(separatedBy: " ") print(wordsArray) // ["たま", "豆"]
↑2018/03/18追記 トリム以外にも大文字小文字の区別も無くしたいという要望が多いと思うので、lowercased()などの関数を利用してもいいですね。
NsPredicateに条件を指定する
Swiftでは「let predicate = NSPredicate(format: "search_word CONTAINS %@", "たま")」
のようにformatに条件文を入れていきます。
NSPredicate - Foundation | Apple Developer Documentation
私の例ですと、SQLのLIKE、つまり文字列の部分一致に対応するオペレーターは
「CONTAINS」を使います。
また、比較したい文字列が複数あるかもしれない前提なので
NSPredicateオブジェクトを配列に格納してから「NSCompoundPredicate」クラスを利用してそれぞれの条件を結合します。
AND条件なので「andPredicateWithSubpredicates」を指定します。
比較したい文字列が1つしかなくてもこのコードで問題ありません。
var predicates: [NSPredicate] = [] for word in wordsArray { predicates.append(NSPredicate(format: "search_word CONTAINS %@ OR name CONTAINS %@", word, word)) } print(predicates)// [search_word CONTAINS "たま" OR name CONTAINS "たま", search_word CONTAINS "豆" OR name CONTAINS "豆"] let compoundedPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates) print(compoundedPredicate)//(search_word CONTAINS "たま" OR name CONTAINS "たま") AND (search_word CONTAINS "豆" OR name CONTAINS "豆")
Realmで検索する
filterメソッドに先程のNSCompoundPredicateオブジェクトをセットすればOKです。
公式ドキュメントはこちらです。
https://realm.io/docs/swift/latest/#queries
let result = realm.objects(Foods.self).filter(compoundedPredicate)
以上です。
Swift4のCodableプロトコルをRealmのモデルクラスに適用してJsonをパースした後にDBに投入するサンプル
RealmのモデルクラスにSwift4のCodableプロトコルを実装したいと思いましたのでサンプルを作りました。
環境はXcode9.2、Swift4.0を使用しています。
作成にあたってこちらのスライドを参考にさせていただきました。
ありがとうございます。
speakerdeck.com
サンプルの仕様
ローカルの「Kinds.json」を読み込み、モデルのオブジェクトに変換し
DBに書き込む。