Help us understand the problem. What is going on with this article?

ParseのCloud Codeを使ってサーバーサイドのコードを記述し、ランダムなオブジェクトを取得する方法

More than 5 years have passed since last update.

Parseというサービスを用いると、クラウド上のデータベース機能が簡単に利用できます。
さらに、Cloud Codeを使えばJavaScriptでサーバーサイドの処理を記述することも可能です。

とても便利なParseですが、現在、残念ながらParseにはデータベース上からランダムなオブジェクトを返すAPIが無いようです。
そこで、Cloud Codeを用いてデータベース上のランダムなオブジェクトを取得する方法を実装してみましたので、その手順およびコードを解説してみたいと思います。
ランダムな相手とネットワーク対戦するゲームなどに応用可能かと思います。

Cloud Codeを使わずに、端末からデータベースの行の数をカウントするAPIを使う方法もあるのですが、スケーラブルではなく、通信の回数が増えてしまうのが問題です。
従って、Cloud Codeを用いて、一回の通信で済み、なおかつスケーラブルなコードを書くのがベストかと思います。

Cloud Codeに関して、基本的な使い方は公式サイトに従えば大丈夫かと思います。
https://www.parse.com/docs/jp/cloud_code_guide
以下は、上記の解説の”クラウド関数”までの内容を踏まえた上での解説になります。

まず、Parseのサイトにログイン後、新規アプリを作成します。
その後、Add Classによりクラス(テーブル)の追加を行います。
今回は2つのテーブルを追加します。
一つ目のテーブルは、データの登録数をカウントするためだけのものにします。
今回は、Customを選択しCountという名前で作成します。
そして、Number型のcountという名前の列を追加します。
そして、行を追加しcountの初期値を0にしておきます。
スクリーンショット 2015-02-20 21.30.52.png
このクラスには、行は一つしか配置しません。

次に、もう一つクラスを追加します。
Customを選択し、RandomNumbersという名前で作成してください。
続いて列を追加します。
Number型でindexNumberという名前の列と、Number型でrandomNumberという名前の列を追加します。
スクリーンショット 2015-02-20 21.38.48.png
まだ行を追加する必要はありません。

次に、JavaScriptで書いたCloud Codeをデプロイします。
デプロイの手順は上記のリンクに書かれていますので、ここでは省きます。
JavaScriptのコードは以下の通りです。

main.js
Parse.Cloud.define("randomObject", function(request, response) {
  var count;
  var query = new Parse.Query("Count");
  query.limit = 1;
  query.find({
    success: function(results) {
      count = results[0].get("count");
      if(count <= 0){
        response.error("No records were found!");
      }
      var randNum = Math.floor((Math.random() * count)) + 1;
      var query = new Parse.Query("RandomNumbers");
      query.equalTo("indexNumber", randNum);
      query.limit = 1;
      query.find({
        success: function(results) {
           response.success(results[0]);
        },
        error: function() {
           response.error("Couldn't find the results.");
        }
      });  
    },
    error: function() {
      response.error("Failed!");
    }
  });
});


Parse.Cloud.beforeSave("RandomNumbers", function(request, response) {
  var query = new Parse.Query("Count");
  query.limit = 1;
  query.find({
    success: function(results) {
      results[0].increment("count", 1);
      results[0].save();
      request.object.set("indexNumber", results[0].get("count"));
      response.success();
    },
    error: function() {
     response.error("Failed saving!");
   }
 });
});

2つの関数があります。
randomObjectという名前の関数は、ランダムなオブジェクトを取得するために端末から呼び出す関数です。レスポンスとしてランダムな行のデータを返します。
beforeSave関数は、RandomNumbersという名前のクラス(テーブル)にデータを保存する直前に呼ばれる関数です。これはCloud Codeに最初から備わっている関数です。この関数内で、Countクラスに保存されてる数値を一つ増やして保存します。

端末側にもコードの記述が必要です。iOS、Xcodeの場合は以下のように書けます。

ViewController.m
-(IBAction)add:(id)sender{
    PFObject *todo = [PFObject objectWithClassName:@"RandomNumbers"];
    [todo.ACL setPublicReadAccess:YES];

    int rand = arc4random_uniform(1000);
    todo[@"randomNumber"] = @(rand);

    [todo saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (!succeeded) {
            NSLog(@"%@", error.description);
        }else{
            NSLog(@"Success!");
        }
    }];
}

-(IBAction)show:(id)sender{
        [PFCloud callFunctionInBackground:@"randomObject"
                           withParameters:@{}
                                    block:^(PFObject *result, NSError *error) {
                                        if (!error) {
                                            int randNum = [result[@"randomNumber"] intValue];
                                            NSLog(@"%d", randNum);
                                        }else{
                                            NSLog(@"%@", error.description);
                                        }
                                    }];
}

addメソッドでランダムな値をクラウド上に保存し、showメソッドでオブジェクトをランダムに取得します。
アプリを実行し、addメソッドにひも付けられたボタンをタップすると、RandomNumbersクラスにデータの追加が行われます。
また、showメソッドにひも付けられたボタンをタップすると、RandomNumbersクラスから端末へオブジェクトとしてランダムにデータが渡されます。

このようにParseと端末が連携をとることで、サーバーサイドの開発の手間が大幅に省けるかと思います。アプリエンジニアは端末側の実装に集中できそうですね。

yuky_az
「ヒトとAIの共生」がミッションの会社、SAI-Lab株式会社の代表取締役。 東北大学大学院理学研究科修了。理学博士(物理学)。 著書に「はじめてのディープラーニング」、「No.1スクール講師陣による 世界一受けたいiPhoneアプリ開発の授業」。オンライン教育プラットフォームUdemyで、2万人近くを指導する人気講師。
https://sai-lab.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away