mBaaSとしてのApple CloudKit の利用シーンと利用制限についての考察

# はじめに

諸々、想像と推測で書いている部分があるので、恐らく誤りがあります。
CloudKit を実サービスで**本気使い**しているCloudKitエヴァンジェリスト(?)の方いれば、教えてください...
せんだちはあらまほしきことなり


# やる(？)こと

だいぶ旬を過ぎましたが、
Parse.comの衝撃的サービスクローズから早幾星霜...、Facebookによる買収でmBaaS(Mobile Backend as a Service)はParse.com一択の一強時代に突入かと思いきや、
Parse.comはその後早々とクローズされてしまいました。

幸い、Parse.comで提供していたほぼ全ての機能は、オープンソースとして誰でも利用できる状態になっています。
しかしながら、Parse.comの機能を利用するために 
　*「サーバを構築してParse.comのソフトウェアをインストールして環境整えて負荷を監視してスケールアウトして...」* 
というのは、本末転倒も甚だしいです。
（ホスティングするサービスもありますが...）


現在のmBaaSの選択肢はその後も洗練されています。
2018年2月現在では、以下のような選択肢が挙げられます。

* Google Firebase
* Apple CloudKit
* Microsoft Azure
* IBM Bluemix
* Amazon AWS
* ...etc

どれも大手であり、この中からどれを選択するかは、
mBaaSが必要な背景や、予算上・学習上のコストとの兼ね合いや、企業文化や、各企業への好き嫌いもあると思います。

この中で特にiOSアプリケーションと親和性がグンバツだと思われる、
Appleが提供するmBaaS **CloudKit**（[https://developer.apple.com/icloud/cloudkit/](https://developer.apple.com/icloud/cloudkit/)） は、
果たして選択肢足り得るのかということを少し調べてみました。

# 前提

#### 知識

* mBaaSが何であるかを知っている
* iCloud を知っている


# 結論

* **ユーザ自身のデータだけを読み書きするのがメインなら、十分使える** 
    * 日記アプリ
    * スケジュールアプリ
    * ToDoアプリ
    * メモ的なアプリ
    * ...etc
* その中で、ユーザ間で共有するようなデータが一部分の小規模な用途なら、耐え得る 
* iOS, macOS, tvOS, watchOS等でのみ利用するなら、十分使える

---

* **以下のような用途がメインなら、厳しい**
  * SNS、チャットのようにユーザ同士でのコミュニケーションが主なアプリ
  * ファイルのアップロードやダウンロードが頻繁なアプリ
  
* iOS等以外に、Android, Windows, またはWebでも、同様のネイティブアプリを作る必要があるなら、厳しい
  * CloudKit JSを使えばたぶん対応することはできる...が、サーバでロジックを持てないので、プラットフォーム毎に同じロジックを作り込む必要がある 


# ポイント

## CloudKitのコンテナの説明

* Private
    * 各ユーザ自身しか読み書きができない自分だけのデータ領域
    * ユーザ自身のiCloudアカウントのストレージ的な制限以外は、ほぼ無制限
* Public
    * アプリ内の全ユーザが読み書きでき得るデータ領域（厳密には、ACL:権限設定がある）
    * CloudKitが掲げる利用料制限は、この領域にかかる
 

## CloudKitを積極的に利用できるシーン

* 各ユーザ自身のiCloud領域に依存する「private領域」への読み書きがメインであること
* 「public領域」の読み書き1ユーザあたりの利用量がほぼ一定で、極端に多くなったりしないこと
* 主にiOS等のApple製品からの利用が見込まれること
* サーバーサイド側でロジックを書く必要がないこと
* 「iCloudを利用する」ということに抵抗がないユーザ層であること
  * 「iCloudを利用できないユーザ」は、そもそも利用不可（ユーザ認証が必ずiCloudなので）


## CloudKitを積極的に利用できないシーン

* アプリ内のユーザ同士でコミュニケーションすることがメインの場合
* アプリを利用するユーザ全員で共有するデータが多い場合
* アプリ内の各ユーザが持つ情報を、アプリ内で横断的に活用するようなサービスの場合
* iOS以外のデバイスでの利用が見込まれる場合
* サーバサイド側でゴリゴリにロジックを書く必要がある場合


## CloudKitの利用制限

CloudKitの公式サイトのトップページに、「料金Free」という内容とともに、
「アクティブユーザ数によって自動的にスケールアウトするよ！」という旨のスライダーが用意されています。

ここで表示されている数値的な内容は、CloudKit の『public領域』を利用した場合の値です。
『private領域』(=アプリを利用する個人個人のiCloudの領域) は、ある意味無制限です。

### 利用開始時の各制限の意味

(想像を含みます)

初回の利用開始時の値は、後述の1ユーザあたりの値から逆算するに、 **400 ユーザ 分**の値と思われます。

なので、「400ユーザまで」は、提示された初期値の制限になるのかなぁと想像できます。

> 引用：CloudKit: Reach more users for free. 部分
![Reach more users for free.部分のスクショ](https://qiita-image-store.s3.amazonaws.com/0/55620/af5e7391-5d5e-f3d5-dc9c-aa9d8fa700c4.png "Reach more users for free")


### スライダーの意味

(想像を含みます)

スライダーの 0 の次が 100,000 ユーザですが、それに至るまでも、[per user]の値でユーザ数に応じて増える...と思います。
（そうでないと、100,000ユーザ未満の制限がきつすぎて使い物にならないので...）


なので、例えば 401 ユーザの場合は、以下のようになると想定されます。

|Asset Storage|Database Storage| Data Transfer| Request per second| 
|:--:|:--:|:--:|:--:|
|10.25 GB|102.5 MB|2.05 GB| 40 |
|(+250 MB)| (+2.5 MB) | (+50 MB) | (+-0) |

> 引用：CloudKit: Public database capacity scales with your users. 部分 スライダー1メモリ目
![CloudKit: Public database capacity scales with your users. 部分 スライダー1メモリ目](https://qiita-image-store.s3.amazonaws.com/0/55620/9d880c07-a1f4-9811-c17f-7a0f232a37c6.png "CloudKit: Public database capacity scales with your users. 部分 スライダー1メモリ目")


スライダーを弄っていくとアクティブユーザ数によって、 4,000,000 ユーザまでは自動的にスケールアウトされるようです。

4,000,000 ユーザ分がpublic領域の上限値であり、分岐点であり、
それ以上はper userあたりの値が減っていくということを表していると思われます。

> 引用：CloudKit: Public database capacity scales with your users. 部分 スライダーの分岐点
![CloudKit: Public database capacity scales with your users. 部分 スライダーの分岐点](https://qiita-image-store.s3.amazonaws.com/0/55620/d0ca84ea-e850-ff55-ec72-18065ed6342c.png "CloudKit: Public database capacity scales with your users. 部分 スライダーの分岐点")


### データ転送量

データ転送量(Data Transfer)の1ユーザあたり 50MB/月 を、多いと見るか少ないと見るか...？

Assetでファイルを何かしようとしたらすぐ使い切りそうです。
Databaseのレコード操作だけだったとしたら、
　1レコードが1KBのJSONだったとしたら、
　1ユーザあたり、以下程度の読み書き回数が限度になると思われます。

* **50,000 レコード/月**
* **1,666 レコード/日**
* **69 レコード/時**
* **1.15 レコード/分**


ちなみに、Parse.comは、無料範囲は問答無用で *2TB/月* 程度でした。
CloudKitでいうところの、 2TB/月 = **40,000ユーザ 分** になります。


## つまり...？

CloudKit の public領域 は、1ユーザあたりの利用量が決まっていて、
それ以上のスケールアウトはしないようです。
なので、public領域にて、

* 「Assetたくさん使う！」
* 「publicデータベースへのアクセスをすんごいたくさんする！（一覧取得が頻繁、更新が頻繁、...etc）」
* 「ユーザ間ですんごいコミュニケーションいっぱいする！」

というような設計、運用には耐えられないと思われます。


# おわりに

色々皮算用しましたが、
**心配する通りにアプリがバカウケ(死語)することを願ってやまないこと早幾星霜。**