FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

Parse Serverのデータストア操作法(Swift SDK編)

NCMBのクロージングに伴って、アプリのバックエンド移行先を検討する必要が出ています。その開発については申し訳ない限りなのですが、そのために必要な情報は適宜お届けしていきます。

この記事では、移行先の候補であるParse Serverについて、その基本的な使い方を解説します。今回はSwift SDKです。

インストール

Swift Package Manager

Package.swiftを開いて、以下を追加します。そして swift build を実行します。

// swift-tools-version:5.5
import PackageDescription

let package = Package(
    name: "YOUR_PROJECT_NAME",
    dependencies: [
        .package(url: "https://github.com/parse-community/Parse-Swift", .upToNextMajor(from: "4.0.0")),
    ]
)

Xcodeを使う

Project > (プロジェクト名) > Swift Packages とたどって、以下のURLを追加します。

https://github.com/parse-community/Parse-Swift.git

CocoaPods

Podfileに以下を追加します。そして pod install を実行します。

pod 'ParseSwift'

Carthage

Cartfileに以下を追加します。そして carthage update を実行します。

github "parse-community/Parse-Swift"

初期化

まずSDKをインポートします。

import ParseSwift

そして application:didFinishLaunchingWithOptions: にて初期化します。

ParseSwift.initialize(applicationId: "xxxxxxxxxx", clientKey: "xxxxxxxxxx", serverURL: URL(string: "https://example.com")!)

データストアの使い方

オブジェクトの作成

まず基本形です。NCMBでいう NCMBObject(className: 'GameScore') に相当する処理です。ParseObjectを継承する形で、各クラスに合わせた構造体を定義します。

struct GameScore: ParseObject {
    // 以下は必須です
    var objectId: String?
    var createdAt: Date?
    var updatedAt: Date?
    var ACL: ParseACL?
    var originalData: Data?

    // 以下は自分で定義したフィールドです
    var points: Int?

    // 独自のメソッドを追加できます
    func merge(with object: Self) throws -> Self {
        var updated = try mergeParse(with: object)
        if updated.shouldRestoreKey(\.points,
                                     original: object) {
            updated.points = object.points
        }
        return updated
    }
}

新規作成

データストアのアイテムはParseObjectと呼ばれます。

let score = GameScore(points: 10)

保存は save メソッドで行います。

try changedScore.save()

更新

更新は新規保存と同じく save メソッドで行います。

score.set(\.points, to: 200)
try score.save();

特殊な更新操作

特殊な操作の場合、 operation を付与する必要があります。

score.operation
            .increment("points", by: 1)
score.operation
            .addUnique("test", objects: ["hello"]
)
score.operation
            .add(("test", \.levels), objects: ["hello"])
score.operation
            .remove("test", objects: ["hello"])
score.operation
            .unset("points")

削除

データの削除は delete メソッドで行います。

try await score.delete();

値の取得

各フィールドの値を取得する際には、直接プロパティにアクセスします。

score.score;
// 1338

規定のフィールドは以下の通りです。

score.objectId
score.createdAt
score.updatedAt
score.ACL

検索

クエリーオブジェクトの作成

データを検索する際には、 query メソッドを使います。検索条件は分かりやすく書けるようです。

GameScore.query("points" > 9)

既存データの再取得を行う場合には fetch メソッドを使います。

try await obj.fetch();

条件を指定して検索

データを検索する際には、条件を指定して find メソッドで取得します。

let found = try await query.find()

最初の一件を取得する婆には first メソッドを使います。配列ではなく、ParseObjectが返ってきます(またはnull)。

let found = try await query.first()

結果の行数も欲しい場合には withCount を使います。

let found = try await query.withCount()
guard let object = found.0.first else {
    XCTFail("Should have unwrapped")
    return
}

また、クエリーの結果を検索条件に指定する matchesKeyInQuerydoesNotMatchKeyInQuery もあります。

let inQuery = GameScore.query("test" <= "awk")
let constraint = matchesKeyInQuery(key: "yolo", queryKey: "yolo1", query: inQuery)
let query = GameScore.query(constraint)

その他、結果の絞り込みを行うメソッドです。

  • limit
  • skip
  • order

結果からフィールドを取り除く

exclude を使うと、特定のフィールドを取り除いて結果を取得できます。以下の resultsplayerName というフィールドがありません。

query.exclude("playerName");
let results = try await query.find();

ポインター

ParseObject同士をつなげるポインター機能です。NCMBでも同様の機能がありますが、よりパワーアップした使い方ができます。

これはGemeオブジェクトに対して、現在のユーザーを紐付けた例です。

let score = GameScore(createdBy: User.current)

ポインターになるオブジェクトは複数指定できます。

const scimitar = ...
const plasmaRifle = ...
const grenade = ...
const bunnyRabbit = ...

const user = User.current;
user.set(\.weaponsList, to: [scimitar, plasmaRifle, grenade, bunnyRabbit]);

アクセスは他のデータと変わりません。

let weapons = user.weaponsList;

データ取得時にポインターデータも取得する場合には include メソッドを使います。

let userQuery = User.current.query;
userQuery.include("weaponsList");
let results = try await userQuery.find();

まとめ

Parse Serverのデータストア操作はNCMBとほぼ変わりません。ただし、スキーマレスではないので、管理画面であらかじめスキーマ設計を行う必要がある点に注意してください。ParseSchemaという仕組みを使うことでSwiftからスキーマ生成もできますが、あまり頻度が多くはないので管理画面で作る方が手軽でしょう。

Swift SDKはあまりドキュメントが整っておらず、プレイグラウンドをみて実装を確認する必要がありそうです。ご注意ください。

サービス終了に伴って開発が発生してしまう点については、弁解の余地がありません。開発者の皆さんに対して申し訳なく思っております。そうした中、Parse ServerはNCMBと設計思想が似ているので、移行にかかる工数が大きくなりすぎないのが利点です。

NCMBとしては今後、移行に伴う情報を積極的に発信していきます。皆さんには大変ご迷惑をおかけしますが、移行のご検討をお願い申し上げます。

Parse Platform