NearbyMessage API SDKについて


# まず軽くNearbyMessage APIについて説明

[Googleの公式サイト](https://developers.google.com/nearby/)を見たほうが早いけど、Nearbyを使えるNearbyMessage APIについてまず軽く説明しとく

![Googleのサイトより](https://lh3.googleusercontent.com/vrXAjir6HhotpOHeRrakDMoC9z8GHnb98bjGWEyIP3lFuMDsru6al3rxgRtRBcdquIgl9xlPNyVfRLPSE1uQmMCHac3s2hA=s688)

内部実装を意識しないイメージとしては、「端末自体が他の端末と文字列のやり取りが出来る」と思うと良さそう。実際はGoogleのサーバーを介しているが、そこは考えないほうがイメージしやすさはある。

注意しておくこと

- セッション管理などはない
	- 誰から何度データを送ってきたかという仕組みが必要であれば自分で設計し実装する必要がある
- Webアプリケーションのようなクライアント/サーバモデルではない
	- つまりリクエストに対してレスポンスを期待するものではない
- 利用制限がある
- Rxのような川のイメージではない
	- 先述の図のような送信と受信のイメージのほうが近い
		- 多人数でおしゃべりしているイメージ

# 利用制限

## リクエスト上限

NearbyMessage APIは実際はGoogleのサーバーを介して端末間のやり取りを行う。SDKを使うことでそれはこちらが意識をすることはないが、処理を開始するとポーリングしているようで複数回APIのリクエストが動作している。

- requests/day	8,640,000
- requests/100seconds/user 1,000

制限が2種類、ひとつ目は1日の制限とふたつ目は1ユーザ（端末）あたりの制限。

もしユーザ数がかなり多いサービスで利用する場合、1日の利用数で想定の上限以内かどうかを計算しておいたほうが良いかもしれない。

ただ、デベロッパーコンソールから上限は増やせる様子でもある。おそらく一時的に増やせるような？

## データ

送信できるデータ量はcontentが100KBと、typeがUnicodeで100文字。

typeは何も指定しない事もできるけどcontentが何か、という事に使うと動的に変更する際に良さそう。

例えばこうとか

- type: "token"
	- content: "hoge"
- type: "chat"
	- content: "hello"
- type: "detail"
	- content: {"user_id": "1", "message": "hello"}

制限についてheaderでは下記のように定義されている

```objc
/// The maximum size (in bytes) of the content of a GNSMessage. This is set to 100KiB (that is,
/// 100 * 1024 bytes).
extern const NSInteger kGNSMessageMaximumContentSize;
//=> 102400

/// The maximum length of the message type, in Unicode characters.
extern const NSInteger kGNSMessageMaximumTypeLength;
//=> 100

```

# 設定について

## DiscoveryModeとDiscoveryMediums

特別な場合がない限りデフォルトの設定で良さそう。

DiscoveryModeはブロードキャスト、スキャンのどちらかもしくは両方かを設定。

DiscoveryMediumsはオーディオを使うか、BLEを使うかもしくは両方かを設定。

SDKのヘッダーファイル見ても分かることが多い

```objc
/// Controls broadcasting and scanning.
typedef NS_OPTIONS(NSInteger, GNSDiscoveryMode) {
  /// To discover which devices are nearby, broadcast a pairing code for others to scan. This is
  /// useful for scenarios where the pairing device is guaranteed only to scan.
  kGNSDiscoveryModeBroadcast = 1 << 0,

  /// To discover which devices are nearby, scan for other devices' pairing codes. This is useful
  /// for scenarios where the pairing device is guaranteed only to broadcast.
  kGNSDiscoveryModeScan = 1 << 1,

  /// To discover which devices are nearby, broadcast a pairing code and scan for other
  /// devices' pairing codes.
  kGNSDiscoveryModeDefault = kGNSDiscoveryModeBroadcast | kGNSDiscoveryModeScan,
};

/// Controls the mediums used for discovering nearby devices.
typedef NS_OPTIONS(NSInteger, GNSDiscoveryMediums) {
  /// Use near-ultrasonic audio to discover nearby devices.
  kGNSDiscoveryMediumsAudio = 1 << 0,

  /// Use Bluetooth Low Energy to discover nearby devices.
  kGNSDiscoveryMediumsBLE = 1 << 1,

  /// Let Nearby decide which mediums are used to discover nearby devices.
  kGNSDiscoveryMediumsDefault = kGNSDiscoveryMediumsAudio | kGNSDiscoveryMediumsBLE,
};
```

# パーミッションについて

iOSの標準のマイクアクセス許可とは **別に** 、パーミッションの確認が表示される。これも消せるものではない。

![スクリーンショット 2016-02-05 14.19.12.png](https://qiita-image-store.s3.amazonaws.com/0/16400/976929f5-5d7d-25df-d747-a18c32331bc0.png "スクリーンショット 2016-02-05 14.19.12.png")


日本の一般的なユーザのために日本語とかにしてほしいけどどうやるんだろ？
（ローカライズを日本語に設定したアプリでは日本語で表示されるかもしれません）

## 実験

### APIリクエスト回数

- 端末登録で1回
	- register Device IDで端末にUUIDを作成しサーバーに送信している風
- 1台のパーミッション要求許可時に5増えた
	- そのままほっとくと14増えた
	- さらにそのままほっとくと10増えた
	- ほっとくとどんどん増える

# 考察

サンプルを実行したところNearbyMessage API画面を起動しているだけで通信している。タイマーで5分操作しなければ処理を止めたりしないと、うっかり起動しっぱなし20分とかきつそう。いたずら防止というよりも、うっかりを防止したい。

あとAPIの上限使いきったときの異常系のコードを書くこと。このような端末間通信っぽいものは一見何が起こってるか分かりづらいし開発者が慣れているということもない。異常系を強く意識したい。

1対多で何かをやることに対する制約は少なく、1対1で何かをやる場合は開発者が、送信するmessageに100KB以下のjsonを使うなどして何かしら仕組みを作っていくような感じ。


# やったらいいよね、と思ったこと

- messageはtypeを決める
- 上限があるので本番用とは別にデバッグ用のAPIkeyは用意する
- タイマーで止める
- パーミッション不許可時/エラー時のアラートを出す
- 制限が上限になる場合のアラートを出す