0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Parse Server Swift SDKの使い方(データストアオブジェクトの複数CRUD操作)

Posted at

ニフクラ mobile backendは3月末で終了します

ニフクラ mobile backendからの移行先として、お勧めしているのがParse Serverです。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

Parse ServerではiOS向けにSDKを提供していますが、Swift SDKについてはあまりドキュメントが充実していません。そこで、各機能の使い方を解説します。今回はデータストアオブジェクトの使い方で、特に複数データをまとめて処理する方法を解説します。

Swift SDKとObjective-C SDKのどちらを使うべきか

Parse ServerにはSwift SDKとObjective-C SDKが用意されています。機能的にいうと、Objective-C SDKの方が多いようです。しかし、公式メッセージとしてはSwift SDKを使っていくのを奨励しています。

Parse Server Swift SDKのインストール

Swift SDKのインストールは、CocoaPodsやCarthageなどが使えます。しかし、一番簡単なのはXcodeのPackage Dependenciesを使う方法でしょう。

XcodeのFileメニューより、Add Package Dependenciesを選択して、出てきたダイアログで以下のURLを指定します。

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

そして、利用するファイルでSDKをインポートします。

import ParseSwift

初期化

SwiftUIの例です。初期化は (アプリ名)App.swift にて行います。そして、初期化は ParseSwift.initialize にて行います。指定するアプリケーションID、クライアントキー、サーバーURLはそれぞれParse Serverを立ち上げる際に指定したものを使います。

マスターキーも指定できるようですが、アプリ側では使わない方が良いかと思います。

import SwiftUI
import ParseSwift

@main
struct ParseDemoApp: App {
    init() {
        ParseSwift.initialize(applicationId: "YOUR_APP_ID", clientKey: "YOUR_CLIENT_KEY", serverURL: URL(string: "https://example.com/parse")!)
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

データストアオブジェクトの定義

データストアで利用するオブジェクトは 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
    }
}

複数オブジェクトを保存する

データストアのオブジェクトを配列にし、 saveAll メソッドを使えば一回で保存処理を実行できます。

[score, score2].saveAll { results in
    switch results {
    case .success(let otherResults):
        var index = 0
        otherResults.forEach { otherResult in
            switch otherResult {
            case .success(let savedScore):
                print("""
                    Saved \"\(savedScore.className)\" with
                    points \(String(describing: savedScore.points)) successfully
                """)
                if index == 1 {
                    score2ForFetchedLater = savedScore
                }
                index += 1
            case .failure(let error):
                assertionFailure("Error saving: \(error)")
            }
        }
    case .failure(let error):
        assertionFailure("Error saving: \(error)")
    }
}

一括保存時のトランザクション

これはMongoDBの設定によっては機能しないとのことですが、トランザクションも利用できます。

[score, score2].saveAll(transaction: true) { results in
    switch results {
    case .success(let otherResults):
        var index = 0
        otherResults.forEach { otherResult in
            switch otherResult {
            case .success(let savedScore):
                print("Saved \"\(savedScore.className)\" with points \(savedScore.points) successfully")
                if index == 1 {
                    score2ForFetchedLater = savedScore
                }
                index += 1
            case .failure(let error):
                assertionFailure("Error saving: \(error)")
            }
        }

    case .failure(let error):
        assertionFailure("Error saving: \(error)")
    }
}

複数データの取得

objectIdを指定してフェッチできますが、これも複数データに対して一括処理を行えます。

let score = GameScore(objectId: "ABCDE")
let score2 = GameScore(objectId: "01234")

[scoreToFetch, score2ToFetch].fetchAll { result in
    switch result {
    case .success(let fetchedScores):
        fetchedScores.forEach { result in
            switch result {
            case .success(let fetched):
                print("取得成功しました: \(fetched)")
            case .failure(let error):
                print("取得失敗しました: \(error)")
            }
        }
    case .failure(let error):
        assertionFailure("エラーが発生しました: \(error)")
    }
}

fetchAll も同期処理が可能です。

do {
    let fetchedScores = try [scoreToFetch, score2ToFetch].fetchAll()
    fetchedScores.forEach { result in
        switch result {
        case .success(let fetched):
            fetchedScore = fetched
            print("Successfully fetched: \(fetched)")
        case .failure(let error):
            print("Error fetching: \(error)")
        }
    }
} catch {
    assertionFailure("Error fetching: \(error)")
}

更新の一括処理

更新は save メソッドを使います。同期、非同期ともに、保存時と同じように処理します。

削除の一括処理

削除は deleteAll を使います。

[scoreToFetch, score2ToFetch].deleteAll { result in
    switch result {
    case .success(let deletedScores):
        deletedScores.forEach { result in
            switch result {
            case .success:
                print("Successfully deleted score")
            case .failure(let error):
                print("Error deleting: \(error)")
            }
        }
    case .failure(let error):
        assertionFailure("Error deleting: \(error)")
    }
}

同期処理は try を使う点も同じです。

do {
    let fetchedScores = try [scoreToFetch, score2ToFetch].deleteAll()
    fetchedScores.forEach { result in
        switch result {
        case .success(let fetched):
            print("Successfully deleted: \(fetched)")
        case .failure(let error):
            print("Error deleted: \(error)")
        }
    }
} catch {
    assertionFailure("Error deleting: \(error)")
}

まとめ

NCMBにはデータの一括処理がなかったので、これはParse Server特有の機能です。複数データをまとめて登録する際などに便利そうです。

Parse ServerとNCMBのデータストア操作は、SDKの仕組みで異なる部分が多いです。載せ替える際には、コードの修正が必要になるでしょう。

とはいえ、データの管理方法などはParse ServerとNCMBで似ています。他のmBaaSと比べると、修正量はそこまで多くないと思われます。載せ替え先として検討に挙げてください。

parse-community/Parse-Swift: The Swift SDK for Parse Platform (iOS, macOS, watchOS, tvOS, Linux, Android, Windows)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?