Twitterでゲームのスクショを共有する処理を作った時にハマった話

# 前置き
- twitterでスクショを共有する処理を作ろうとした
- 対応ビルドは `iOS/Android/WebGL` の3つにした
- キャプチャ画像のアップロード先は `Imgur` を使用することにした
- なのでImgurのAPIを使用してUnityからhttpリクエストしてアップロードすることにした
- Unityは `2018.4.12f1`
- 大きく3つの問題にぶつかった

# 作ってみました
https://github.com/nir-takemi/UnityTweet


# ハマった話

## card表示がアップロードした画像の直URLだと表示されない
### 事象
APIのレスポンスがアップロードした画像の直URLなので、そのURLをそのまま利用したがcard表示されなかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/3e3e4818-3d33-474b-d9b3-ad9f2c5f2e5b.png)

```xml:responseはこんな感じ
<?xml version="1.0" encoding="utf-8"?>
<data type="array" success="1" status="200">
  <id>xxxxx</id><title/><description/><datetime>1574052543</datetime><type>image/png</type><animated>false</animated><width>1082</width><height>646</height><size>34163</size><views>0</views><bandwidth>0</bandwidth><vote/><favorite>false</favorite><nsfw/><section/><account_url/><account_id>0</account_id><is_ad>false</is_ad><in_most_viral>false</in_most_viral><has_sound>false</has_sound><tags/><ad_type>0</ad_type><ad_url/><edited>0</edited><in_gallery>false</in_gallery><deletehash>yyyyy</deletehash><name/>
  <link>https://i.imgur.com/xxxxx.png</link>
</data>
```

### 解決方法
レスポンスで返ってくるアップロードした画像の直URLの拡張子（上記例だと `.png` ）を削除すると、画像のページのリンク(※)になるため、そのリンクであればcard表示されるようになるので、拡張子を排除した形でurlパラメータに渡してあげるようにした。

※こんなページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/cde61df2-6706-4f23-2401-2486a3b2a4ab.png)


## ScreenCapture.CaptureScreenshotでAndroidビルドでエラーになった
### 事象

`ScreenCapture.CaptureScreenshot` は保存パスを設定すればそのパスに保存できるらしいという前提で実装していた。
Editor/WebGLビルドでは確かに問題なかった。
Androidビルドで実行した途端こんな感じのエラーに。。

```
11-15 21:10:56.490 12383 12401 I Unity   : capture_path = /storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/201911152110564885.png
11-15 21:10:56.490 12383 12401 I Unity   :
11-15 21:10:56.490 12383 12401 I Unity   : (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
11-15 21:10:56.490 12383 12401 I Unity   :
11-15 21:10:56.801 12383 12547 E Unity   : Failed to store screen shot (/storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/201911152110564885.png)
```

`capture_path = xxx` は自前でloggingしたので、パス自体は問題なさそう……ただ
`Failed to store screen shot` の後ろに出力されてるパスが何かおかしい……

### 解決方法

こんな感じでモバイル向けはファイル名だけ指定して実行するようにした。

```c#
string fileName = string.Format("{0:yyyyMMddHmmssFFFF}.{1}", DateTime.Now, cImageSuffix);
string filePath = Application.persistentDataPath + "/" + fileName;

// モバイルプラットフォームはファイル名指定で、勝手にpersistentDataPath配下となる
#if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS)
ScreenCapture.CaptureScreenshot(fileName);
#else
ScreenCapture.CaptureScreenshot(filePath);
#endif
```

### ちゃんとドキュメントを読みましょう

公式ドキュメントにはちゃんと書いてありました。
[ScreenCapture.CaptureScreenshot](https://docs.unity3d.com/2018.3/Documentation/ScriptReference/ScreenCapture.CaptureScreenshot.html)
なので安心して `Application.persistentDataPath` 配下に保存される前提で処理が書けそう。

```
On mobile platforms the filename is appended to the persistent data path.
See Application.persistentDataPath for more information.
```

## card表示の仕方がWeb版とTwitterクライアント版とで異なってた

### 事象
作りとしてキャプチャ画像のアップロード先のURLと、ゲームのURLの二つを共存する形でつぶやきたかった。
しかし、Web版はurlパラメータで指定したURLをcard表示してくれそうで、Twitterクライアント側ではURLの順序が早い方がcard表示対象になってしまうよう。

つまり、
こうしたかったけど
<img width="375" alt="IMG_5367.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/71bc530c-d8ae-4dcd-8bc9-6f7bf77fd190.png">

こうなってしまった
<img width="375" alt="IMG_5368.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/fad4a6dc-cbc0-91d9-b78c-3eb38e8d3fa6.png">

### 解決方法
こちらで解決できるような問題じゃなさそうだったので、パラメータを指定してあげることでImgurAPIを `text/url` 指定（Web版向け）で実行、もしくは `textのみ` 指定（URLの順序を画像URL優先にする）で実行できるようにちょっと無理矢理処理にした。

# 感想
- 何でプラットフォーム間で動作が異なるんだ……
- 困ったら公式ドキュメント。
- ただ日本語ドキュメントは一部よくわからん翻訳になってたのでちょっと危険。