データストア(Swift)
基本的な使い方
Contents |
概要
このページでは、データストア機能の基本的な使い方について解説していきます。
データストアで利用可能なデータ型
データストアでは、以下の値が利用可能です。
種類 | サンプル |
---|---|
文字列 | ABC |
配列 | ["orange", "apple", "grape"] |
数字 | 123 |
日付 | 2013-09-06T01:51:03.606Z |
真偽値 | true または false |
オブジェクト | {"name":"orange"} または null |
緯度経度(位置情報) | 33.857619,122.378986 |
- null はオブジェクト型です。
- フィールドにデータが登録されていない場合、管理画面では (undefined) と表示されます。
なお、一度フィールドにデータを登録した後に、登録前の状態に戻すことは出来ません。
データ未登録状態として扱いたい場合は、null を設定してください。
アプリでの実装
NCMBObjectについて
ニフクラ mobile backendのデータストア機能はNCMBObjectを通じて利用します。
NCMBObjectはスキーマレスなJSON互換のkey-value形式のオブジェクトを扱うことができます。
オブジェクトの保存先はNCMBObjectの初期化時に指定したクラスで識別されます。
オブジェクトをデータストアに保存する
オブジェクトをデータストアに非同期で保存するには、saveInBackgroundメソッドが利用できます。
指定したクラスがデータストアに存在しない場合は、新規にクラスが作成されます。
role, file, push, user, installation などは標準クラスとして作成されているので、
新規クラス作成時にはクラス名にセットできません。
// testクラスのNCMBObjectを作成
let object : NCMBObject = NCMBObject(className: "test")
// オブジェクトに値を設定
object["fieldA"] = "Hello, NCMB!"
object["fieldB"] = "日本語の内容"
object["fieldC"] = 42
object["fieldD"] = ["abcd", "efgh", "ijkl"]
// データストアへの登録を実施
object.saveInBackground(callback: { result in
switch result {
case .success:
// 保存に成功した場合の処理
print("保存に成功しました")
case let .failure(error):
// 保存に失敗した場合の処理
print("保存に失敗しました: \(error)")
}
})
Swiftには、非同期のasync/awaitメソッドを使用します。
Swift SDK 1.3.0 を使用し、デプロイ端末がiOS 13以降のみ使用できます。ご注意ください。
// testクラスのNCMBObjectを作成
let object : NCMBObject = NCMBObject(className: "test")
// オブジェクトに値を設定
object["fieldA"] = "Hello, NCMB!"
object["fieldB"] = "日本語の内容"
object["fieldC"] = 42
object["fieldD"] = ["abcd", "efgh", "ijkl"]
// データストアへの登録を実施
Task(priority: .background) {
let result = await object.saveInBackground_async()
switch result {
case .success():
// 保存に成功した場合の処理
print("保存に成功しました")
case let .failure(error):
// 保存に失敗した場合の処理
print("保存に失敗しました: \(error)")
}
}
オブジェクトの取得
データストアにある内容を取得する場合は、オブジェクトの検索を実施するか
以下のようにobjectIdを指定してfetchInBackgroundメソッドを利用します。
// testクラスへのNCMBObjectを設定
let object : NCMBObject = NCMBObject(className: "test")
// objectIdプロパティを設定
object.objectId = "Mz6xym6wNi63lxb8"
object.fetchInBackground(callback: { result in
switch result {
case .success:
// 取得に成功した場合の処理
print("取得に成功しました")
if let fieldB : String = object["fieldB"] {
print("fieldB value: \(fieldB)")
}
let str: String? = object["string"] // 文字列の場合
let number: Int? = object["number"] // 数字の場合
let bool: Bool? = object["bool"] // 真偽値の場合
let date: Date? = object["date"] // 日付の場合
let numbers: [Int]? = object["numbers"] // 数字の配列の場合
let geo: NCMBGeoPoint? = object["geo"] // 位置情報
// オブジェクトの場合
let object: [Any]? = object["object"]
// オブジェクトから数字取り出し
let num2: Int? = object![0] as? Int
// オブジェクトから文字列取り出し
let str2: String? = object![1] as? String
// オブジェクトから数字の配列取り出し
let numbers2: [Int]? = object![2] as? [Int]
// 配列からDictionary取り出し
let obj2: [String: String] = object![3] as? [String: String] ?? ["":""]
case let .failure(error):
// 取得に失敗した場合の処理
print("取得に失敗しました: \(error)")
}
})
オブジェクトの更新
保存済み(または、objectIdを持っている)のオブジェクトに新しい値をセットして
saveInBackgroundメソッドを実行することでデータストアの値が更新されます。
データストアに対しての操作を設定する
下記のような更新オペレーションを利用することで、オブジェクト全体を上書きすることなく、指定の値を更新できます。
※これらのオペレーション設定後にupdateを実行する必要があります。
- 指定したフィールドの値をインクリメントする(すでに該当フィールドに値が存在する場合にのみ更新可能)
object["fieldC"] = NCMBIncrementOperator(amount: 1)
- 指定したフィールドの配列内で重複しなければ追加する
object["fieldD"] = NCMBAddUniqueOperator(elements: ["food", "fish"])
オブジェクトの削除
オブジェクトをデータストアから非同期で削除する場合は、
deleteInBackgroundメソッドを利用します。
object.deleteInBackground(callback: { result in
switch result {
case .success:
print("削除に成功しました")
case let .failure(error):
print("削除に失敗しました: \(error)")
}
})
オブジェクトの関連付け
NCMBObjectのインスタンスに、別のNCMBObjectを設定すると、
設定したNCMBObjectへのポインタ(参照)が設定されます。
ポインタ先のオブジェクトがデータストアに登録されていない場合は、
ポインタ元のオブジェクト保存前に自動で保存されるようになっています。
// testクラスへのNCMBObjectを設定
let object : NCMBObject = NCMBObject(className: "Posts")
let comment = NCMBPointer(className: "Comments", objectId: "NPeRREGPPubPhYLg")
object["topComment"] = comment
// データストアへの登録を実施
object.saveInBackground(callback: { result in
switch result {
case .success:
// 保存に成功した場合の処理
print("保存に成功しました")
case let .failure(error):
// 保存に失敗した場合の処理
print("保存に失敗しました: \(error)")
}
})
ポインタは1つのオブジェクトへの参照しか持つことができませんが、
リレーションを利用することで、特定クラスの複数オブジェクトと関連づけることが可能です。
リレーションを追加・削除する場合は、NCMBRelationクラスを利用します。
ポインタとは異なり、データストアに未登録のオブジェクトが
自動的に保存されることはありません。
// testクラスへのNCMBObjectを設定
let object : NCMBObject = NCMBObject(className: "test")
let pointerA = NCMBPointer(className: "test", objectId: "84lywBlhwuA8SeUo")
let pointerB = NCMBPointer(className: "test", objectId: "SqG3oH0tgXx50hT7")
object["NewRelation"] = NCMBAddRelationOperator(elements: [pointerA, pointerB])
// データストアへの登録を実施
object.saveInBackground(callback: { result in
switch result {
case .success:
// 保存に成功した場合の処理
print("保存に成功しました")
case let .failure(error):
// 保存に失敗した場合の処理
print("保存に失敗しました: \(error)")
}
})
オブジェクトの検索を行う
データストアを検索する場合は、NCMBQueryクラスを利用します。
デフォルトでは条件なしでの検索が行われますが、
以下のサンプルコードでは検索条件を設定しています。
※limitを指定していない場合、検索結果として取得される最大データ件数は100件です。
検索結果のデータ件数が多い場合は、limitとskipを活用してください。
詳細はクエリのオペレータを利用するをご覧ください。
//testクラスを検索するNCMBQueryを作成
var query : NCMBQuery<NCMBObject> = NCMBQuery.getQuery(className: "test")
//fieldCが42と一致するデータを検索する条件を設定
query.where(field: "fieldC", equalTo: 42)
// 検索を行う
query.findInBackground(callback: { result in
switch result {
case let .success(array):
print("取得に成功しました 件数: \(array.count)")
case let .failure(error):
print("取得に失敗しました: \(error)")
}
})
標準クラスを検索する場合のクラス名
会員、ロール、ファイルなど、ニフクラ mobile backendに標準で存在するクラスに対して
データの検索を行う場合は、標準クラス用のクラスを利用してください。
mobile backend のクラス名 | SDK のクラス名 | 役割 |
---|---|---|
user | NCMBUser | 会員管理のクラス |
role | NCMBRole | ロールのクラス |
file | NCMBFile | ファイルストアのクラス |
installation | NCMBInstallation | 端末情報一覧のクラス |
push | NCMBPush | プッシュ通知のクラス |
//userクラスを検索するクエリを作成
var query: NCMBQuery<NCMBUser> = NCMBUser.query
各クラスのデータをより効率的に検索するにはこちらをご参考ください。
検索条件を設定する
上記で使用したwhereKey:equalToメソッド以外にも、
いろいろな検索条件を設定することができます。
詳細はSDKリファレンス:NCMBQueryをご覧ください。
- 配列に対する条件の設定
// arrayKey: [1, 2, 3]
query.where(field: "arrayKey", equalTo: [2])
// 指定した複数の値がすべて含まれるものにマッチする
query.where(field: "arrayKey", containsAllObjectsInArrayTo: [2, 3, 4])
クエリの合成
条件を複数指定することで、and検索を行うことができます。
以下の例では、intというキーが30を超え、50未満の値となるよう条件を設定しています。
// クエリの作成
var query = NCMBQuery.getQuery(className: "test")
query.where(field: "fieldA", equalTo: "Hello, NCMB!")
query.where(field: "fieldC", greaterThanOrEqualTo: 40)
// 検索を行う
query.findInBackground(callback: { result in
switch result {
case let .success(array):
print("取得に成功しました 件数: \(array.count)")
case let .failure(error):
print("取得に失敗しました: \(error)")
}
})
また、orQueryメソッドを利用することで、複数のクエリをOR合成することができます。
// 一つ目のクエリの作成
var query1 = NCMBQuery.getQuery(className: "test")
query1.where(field: "fieldB", equalTo: "日本語の内容")
// 二つ目のクエリの作成
var query2 = NCMBQuery.getQuery(className: "test")
query2.where(field: "fieldC", lessThan: 50)
// OR検索を行うためにクエリを合成する
let query = NCMBQuery.orQuery(query1, query2)
// 検索を行う
query.findInBackground(callback: { result in
switch result {
case let .success(array):
print("取得に成功しました 件数: \(array.count)")
case let .failure(error):
print("取得に失敗しました: \(error)")
}
})
クエリのオペレータを利用する
limitやskipを指定して、検索結果の取得件数を設定することができます。
※limitを指定していない場合は、limitはデフォルトである100として検索が行われます。(REST API リファレンス:クエリの指定方法 参照)
limitの値については、必ず適切な値を設定してください。詳細はこちらをご覧ください。
使用可能なオペレータに関してはこちらをご確認ください。
var query = NCMBQuery.getQuery(className: "test")
//取得件数の指定
query.limit = 5;
//取得開始位置の指定
query.skip = 5;
管理画面での操作
クラスを新たに作成する
管理画面左側メニューのデータストアをクリックしてください。
緑の「+作成」ボタンをクリックして、新規作成を選択します。
すると以下のようなポップアップが表示されます。
クラス名を入力し、「作成する」ボタンをクリックすると、クラスが新規に作成されます。
データストアでも作成したクラスが表示されます。以下の例では作成したClass_Testが表示されています。
ファイルからクラスをインポートする
データストアでは、エクスポートしたデータや、お客様がカスタマイズしたJSON形式・テキスト形式(.txt)・CSV形式のファイルをインポートすることにより、クラスを作成することが可能です。
- JSON形式
JSON形式のデータをインポートする場合、インポートしたいデータは以下の例のように「results」をキーとする配列に格納されている必要があります。
- テキスト形式(.txt)・CSV形式
テキスト形式やCSV形式のファイルからインポートした場合、1行目がフィールド名として認識され、2行目以降の内容がデータとしてインポートされます。
以下の例では、name、flag、numberというフィールドが作成され、2行目以降がデータとして登録されます。
ダブルクォーテーションで囲った文字は、文字列として認識されます。それ以外の記述方法は、データストアで利用可能な型に準じています。
- 注意
- カンマの直後に半角スペースを入れると正しく値が認識されない場合があります
- オブジェクト形式(緯度経度、日付型、ポインタ型 等)はインポートできません
- 注意
name,flag,number
"hoge",true,123
"fuga",true,10
ファイル形式の種類に関係なく、インポートするファイルは、日本語の文字化けを防ぐために、文字コードをUTF-8にして保存してください。また、UTF-8のファイルでもBOMがついているファイルをインポートしようとすると、エラーが返却されますので注意してください。
インポート可能な最大ファイルサイズは2GBとなっています。
インポートしたい場合は、データストアの画面にて、緑の「+作成」ボタンをクリックしてインポートを選択します。
以下のようなポップアップが表示されますので、クラス名を入力し、インポートするファイルを選択して、「インポート」ボタンをクリックしてください。
エクスポートしたデータをインポートするなど、すでに同じ名前のクラスがデータストア内に存在している場合、重複エラーが発生します。
その場合は、既存のクラスを削除してからもう一度インポートしてください。
データをエクスポートしたい場合には以下のページをご覧ください。
エクスポート機能を利用する
クラスを削除する
上で作成したClass_Testをクラスを削除するには、データストアの右上にある「クラスの編集」ボタンをクリックします。
以下のページに遷移するので、「クラスの削除」ボタンをクリックします。
右上にある「クラスの削除」ボタンをクリックすると、以下のポップアップが表示されます。
クラスを削除していいか確認してから、クラスの削除を実行してください。
フィールドを新たに作成する
データストアの画面で、フィールドを作成するクラスをクリックしてください。
データストアの上側にある「+新しいフィールド」ボタンをクリックします。
フィールド名を入力して、「作成する」ボタンをクリックしてください。
フィールドを削除する
フィールドの削除は、クラスの編集画面から行います。データストアの右上にある「クラスの編集」ボタンをクリックしてください。
作成したフィールドの左側にチェックボックスがあります。削除するフィールドのチェックボックスをクリックし、「+新規フィールド」ボタンの横にある削除ボタンをクリックすると、ポップアップが表示されます。
フィールドを削除していいか確認してから、フィールドの削除を実行してください。
レコードを追加する
データストアの画面で、レコードを追加するクラスをクリックしてください。
データストアの左上にある「+新しいレコード」をクリックすると、空のレコードが表示されます。
また、レコードが1つも存在しないクラスの場合、データストアの中央にも、レコード追加のボタンが表示されます。
データストアでは、追加したフィールドのみ編集可能で、その他のフィールドは自動的に値が格納されます。
以下の例では、nameというフィールドを追加したので、空のレコードをダブルクリックし、nameフィールドに「tarou」と入力しました。
エンターキーを押すと値が登録され、objectIdやcreateDateなどが自動的に登録されます。
値を編集中の時は、データ型を選択する吹き出しが表示されるので、文字列や数値など、どのデータ型で値を登録するのか設定することができます。
レコードを削除する
各レコードの左側にあるチェックボックスをクリックし、「+新しいフィールド」ボタンの横にある「削除」ボタンをクリックすると、ポップアップが表示されます。
レコードを削除していいか確認してから、レコードの削除を実行してください。
レコードの検索
データストアにあるデータが増えてきた場合などに、絞り込み検索を使って効率的にデータストアを閲覧することが可能です。
データストアの左下にある、「絞り込み」ボタンをクリックすると、検索条件を設定することができます。
絞り込み検索の条件は、以下のように設定します。
- フィールド名を指定する
- 検索する値を入力する
- 検索する値のデータ型を指定する
- 検索条件を指定する
- 適用ボタンをクリック
この時、検索条件で「いずれかと同じ」「いずれかを含む」「いずれとも違う」を選択した場合は、配列形式で異なったデータ型の値を検索条件に指定することが可能です。
以下の例では、numberというフィールドで、数値として登録された「1」と、文字列として登録された「1」を検索条件で指定しています。
また、のアイコンをクリックすることで、検索条件を複数設定できます。
※ null(オブジェクト)のデータを検索した場合、データ未登録の(=管理画面上で(undefined)と表示されている)データも検索されます。
※「リレーションを見る」をクリックし遷移した画面にて検索を行う場合は、開発ガイドラインの「リレーションについて」をご確認ください。
クラスのパーミッションを設定する
クラスの編集画面で、右上の「パーミッションの設定」ボタンをクリックします。
ポップアップが表示されるので、「+新しいパーミッション」をクリックしてパーミッションの設定を追加してください。
対象を会員やロールに限定することで、パーミッションを一部の会員に限定することが可能です。
クラスのパーミッションを削除する
クラスのパーミッションは、各行の左側にあるチェックボックスをクリックし、削除ボタンをクリックすると削除できます。
レコードのパーミッションを設定する
レコードのパーミッションを設定するには各レコードの右側にあるパーミッション編集ボタンをクリックします。
パーミッション設定画面が表示されますので、「+新しいパーミッション」ボタンをクリックして、パーミッションを設定してください。
レコードのパーミッションを削除する
レコードのパーミッションは、各行の左側にあるチェックボックスをクリックし、削除ボタンをクリックすると削除できます。
暗号化の設定
mobile backendへのデータ保存時に、暗号化を実施するかフィールドごとに設定することが可能です。
※暗号化処理に関する詳細情報については、開発ガイドライン:内部データベースについてをご参照ください。
各データ型の暗号化可否については以下の通りです。
種類 | 暗号化可否 | 備考 |
---|---|---|
文字列 | 可 | |
配列 | 可 | 各要素のデータ型の暗号可否に従う |
数字 | 否 | 暗号化されずに保存されます |
日付 | 否 | 暗号化されずに保存されます |
真偽値 | 否 | 暗号化されずに保存されます |
オブジェクト | 可 | { key : value } のvalueのみ、各データ型の暗号可否に従って暗号化されます |
緯度経度 | 否 | 暗号化されずに保存されます |
管理画面での暗号化設定方法
データストアを開き、クラスを選択して右上の「クラスの編集」ボタンをクリックしてください。
フィールドの一覧が表示され、暗号化が可能なフィールドのみ「暗号化する」ボタンがクリックできるようになっています。
※なお、暗号化が可能であっても既にデータが存在しているフィールドについては、値を持つレコードを削除していただかないと、暗号化への切り替えはできません。ご注意ください。
「暗号化する」ボタンをクリックすると以下のような確認画面が表示されますので、問題なければ暗号化してください。
暗号化を解除する場合は、クラスの編集画面にて「暗号化を解除する」ボタンをクリックしてください。
※会員クラスのpasswordフィールドについては、暗号化有無にかかわらず管理画面上では表示されません。
※一度暗号化したフィールドは、クラス内該当フィールドのデータが全て削除されない限り、暗号化の設定を解除することはできません。
※暗号化したフィールドでは、下記記載のオペレータが利用不可となります。
- 項目の検索
機能 | オペレータ |
---|---|
より小さい | $lt |
より大きい | $gt |
以下 | $lte |
以上 | $gte |
正規表現での比較 ※文字列のみ | $regex |
- 複合条件検索
機能 | オペレータ |
---|---|
サブクエリと合致するデータのうち、クエリとサブクエリで指定したキーの値が一致するデータを取得 | $select |
- ポインタの検索(リレーションも含む)
機能 | オペレータ |
---|---|
等しい(1項目) | なし |
サブクエリに合致するデータを、ポインタとして持っているデータを取得 | $inQuery |
オブジェクトIDが指定された親のリレーションにひもづく子のデータを取得 | $relatedTo |
- 位置情報検索
機能 | オペレータ |
---|---|
指定位置から距離が近い順でデータを取得 (orderを指定した場合は、orderが優先される) オプションで最遠距離を以下の単位で指定可能 $maxDistanceInMiles → マイル $maxDistanceInKilometers → キロメートル $maxDistanceInRadians → ラジアン |
$nearSphere |
指定矩形の内側に存在するデータを取得 矩形は$boxを使って左下、右上を指定 |
$within / $box |
- その他クエリのキーについて
機能 | キーの名前 |
---|---|
並び順を指定する (降順はマイナス付与) カンマで区切ると複数項目の並べ替えが可能 |
order |
お探しの内容が見つからなかった場合はユーザーコミュニティ
もご活用ください。(回答保証はいたしかねます)
なお、 Expertプラン以上のお客様はテクニカルサポートにてご質問を承らせて頂きます。
推奨画面サイズ1024×768px以上