Parse Server Java SDKの使い方（Kotlinでのオフライン時のデータストアオブジェクト操作）

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

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

Parse ServerではAndroid向けにSDKを提供していますが、言語はJavaのみとなっています。そのため、Kotlin向けには、Java SDKの内容を翻訳しながら実装する必要があります。そこで、本記事にて、各機能の使い方を解説します。今回はオフライン時のデータストアオブジェクトの使い方です。この機能はおそらくAndroid SDKのみの機能です。

## Android SDKのインストール

Android SDKのインストールは幾つかの設定が必要です。

### settings.gradleの修正

プロジェクトルートにある `settings.gradle` を修正します。

```groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
				// 以下を追加
        maven {
            url "https://jitpack.io"
        }
    }
}
```

### app/build.gradleの修正

app以下にある `build.gradle` を修正します。

```groovy
dependencies {
	// 以下を追加
	implementation "com.github.parse-community.Parse-SDK-Android:parse:4.2.1"
}
```

バージョンはインストールするタイミングによって異なりますが、現在は以下です。

![](https://jitpack.io/v/parse-community/Parse-SDK-Android.svg)

### AndroidManifest.xmlの修正

開発中で、ローカルのParse Serverを使う場合には、以下の設定が必要です。

```xml
<application
	android:usesCleartextTraffic="true" <!-- 追加 -->
>
```

## 初期化

SDKの初期化は `MainActivity` にて行います。Androidはエミュレーターなので、 `localhost:1337` ではなく、 `192.168.0.2:1337` などがParse ServerのURLになるでしょう。

オフライン対応する際には `.enableLocalDataStore()` を追加します。これがないと、オフライン時にデータ操作できないので注意してください。

```kotlin
import com.parse.Parse

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Parse.initialize(
            Parse.Configuration.Builder(this)
                .applicationId("appId")
                .clientKey("clientKey")
								.enableLocalDataStore()
                .server("http://your_parse_server/parse/")
                .build()
        )
				// 省略
		}
}
```

## ローカルでのデータ保存

ローカルにデータ保存する際には `pin` または `pinInBackground` メソッドを使います。利用方法は以下の通りです。

```kotlin
val gameScore = ParseObject("GameScore")
gameScore.put("score", 1337)
gameScore.put("playerName", "Sean Plott")
gameScore.put("cheatMode", false)
gameScore.pinInBackground {
		Log.d("DEBUG", "Game Score saved")
}
// または
gameScore.pin()
```

なお、これはローカルにデータを保存しただけで、 `objectId` は `null` になるので注意してください。

## データの取得

データの取得は2つの方法があります。まず一つ目は `fromLocalDatastore` メソッドを使う方法です。これは、ローカルに保存したデータを取得する際に使います。

```kotlin
val query = ParseQuery.getQuery<ParseObject>("GameScore")
query.fromLocalDatastore()
query.findInBackground {ary, err ->
		if (err == null) {
				Log.d("DEBUG", "Count -> " + ary.size)
				val obj = ary[0]
				Log.d("DEBUG", obj.getString("playerName") ?: "")
				Log.d("DEBUG", "Local data, id: " + obj.objectId )
				ary.forEach { obj ->
						obj.unpin()
				}
		} else {
				Log.d("DEBUG", err.toString())
		}
}
```

サーバーにある既存データをローカルに保存した場合、 `fetchFromLocalDatastoreInBackground` で取得できます。

```kotlin
val obj = ParseObject.createWithoutData("GameScore", "ABCDEF")
obj.fetchFromLocalDatastoreInBackground<ParseObject?> { _, e ->
		if (e == null) {
				// エラーなし（ただし、データが存在しない場合もあります）
		} else {
				// エラー
		}
}
```

## データの更新

データの更新も `save` または `saveInBackground` メソッドを使います。非同期、同期処理も保存時と同じです。

## データの削除

データの更新も `unpin` または `unpinInBackground` メソッドを使います。

```kotlin
obj.unpinInBackground {err
		if (err == null) {
				Log.d("DEBUG", "Deleted")
		} else {
				Log.d("DEBUG", err.toString())
		}
}
// または
obj.unpin()
```

## まとめ

Parse ServerとNCMBのデータストア操作は、Android SDK同士では大きくは異なりません。載せ替える際には、大きなコードにはならなそうです。

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

[Android Developers Guide \| Parse](https://docs.parseplatform.org/android/guide/#saving-objects)