FlutterでAppleID登録から始めてiOSアプリをリリースした時に解決したつまづきポイントメモ。

# 検証日時

2019年11月28日~2019年12月12日（リリース日）

#全体的な流れリリースまでの流れと、本記事の概要

公式チュートリアルです。
https://flutter.dev/docs/deployment/ios

英文がよくわからないという場合は、Chromeで日本語翻訳にかければほぼほぼ内容わかります。Appleのコンソールが英語なので、対応している単語がわからないときは翻訳を切って見比べると解決します。

このチュートリアルを進める時にエラーが出た部分にフォーカスして、その解決法などを共有します。

↓Android版のレポートもありますのでお役に立てば！↓
https://qiita.com/k_mawa82/items/2a519b2f4cb135d2921b


# ローカル動作確認した時のFlutter周り環境情報とパッケージの各バージョン

```
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.14.6 
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.2)
//↑普段のローカル動作確認ビルドはXcode11.2になってたんですが、リリース時は下記のように違うバージョンが必要でしたのでご注意ください！

```
パッケージ

```#pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  rflutter_alert: ^1.0.2
  flutter_launcher_icons: any
  firebase_core: ^0.4.2+1
  firebase_auth: ^0.15.1
  cloud_firestore: ^0.12.11
  firebase_analytics: ^1.0.6
  modal_progress_hud: ^0.1.3
  provider: ^3.2.0
  keyboard_actions: ^3.1.2

```

# 事前準備 Apple Developer 登録

すでに登録済の方はスキップできます。

Apple Developer Programに登録するのが第一段階です。

法人だと時間がかかります。理由はD-U-N-S番号必要なためです。これは無料で手に入ります。急いでいて面倒な方は商工リサーチで代行依頼できるようです。

なお、個人リリース→必要になった際は法人にオーナー切り替えができるとのことで、後々再検討も可能です。
http://apli-kaihatsu.com/index.php/2018/06/28/appstore_account_henko/

自分は、個人で年間開発者アカウントの権利を購入してから、アクティベートまで２４時間くらいかかりました。次の日にできるようになってました。長い人はもうちょっとかかるみたいです。

# Certificate（証明書）の作成

下記記事が参考になりました。
https://i-app-tec.com/ios/apply-application.html

なおこの辺りの手続きはsafari推奨らしいのですが、自分はリリースまでChromeで全て行いましたが問題ありませんでした。

Certificateの選択では
```iOS Distribution (App Store and Ad Hoc)```を選択しました。（あとでこの辺の情報切り替えてまた証明書とり直すの面倒そうだなと思ったため）

上記記事に沿ってキーチェーンに登録するまでを完了させます。

__あとでここで得られるCertificate情報が必要になります。__

ポイント：開発しているMacとキーが連携するためデプロイ機材を変更する際は注意必要。

# iOS App IDs の登録

同じ著者さんの次の記事が参考になりました。
https://i-app-tec.com/ios/ios-app-ids.html

アプリごとにIDを登録が必要です。

__あとでここで得られるBundle IDが必要になります。__

# $flutter build iosする

次はビルドします。自分は開発で使っていたAndroid StudioのTerminalから打ちました。

```$flutter build ios```

もし上記のAppleの認証関係のデータを組み込んでないで```$flutter build ios```コマンドを打つと下記のエラーがでます。

```
No development certificates available to code sign app for device deployment
```

エラー文にも詳細が記載されています。
図示つきの下記の記事が参考になります。

記事ののようにしてXcodeでFlutterプロジェクトを開きなおして設定したあとで、__さらにAndroidStudioでFlutterプロジェクトを開き直して、コマンド```$flutter build ios```でうまくビルドできました。
http://shinriyo.hateblo.jp/entry/2018/03/04/flutter%E3%81%AEiOS%E5%AE%9F%E6%A9%9F%E3%81%AE%E8%B5%B7%E5%8B%95

うまくいった場合

```
$ flutter build ios
Building <APPID> for device (ios-release)...
Automatically signing iOS for device deployment using specified development team in Xcode project: //省略
Running Xcode build...                                                  
 ├─Building Dart code...                                    16.9s
 ├─Generating dSYM file...                                   0.1s
 ├─Stripping debug symbols...                                0.4s
 ├─Assembling Flutter resources...                           0.7s
 └─Compiling, linking and signing...                        31.6s
Xcode build done. 
```
ここまできたらあと少し・・・です。一休みして、続きを行います。

# App Store Connectでアプリの詳細情報登録

紹介文とか、スクショとかあげます。やや時間がかかります。
そして、このアプリごとのページにビルドしたアプリデータをアップするのですが、それにはXcodeで行います。これが最後の難関（エラーが出やすい）ポイントです。頑張ります。

# Archive

Xcode Product の Archive を選びます。

でビルドでこけなければ次に進めます。自分はここでFirebaseを入れた時にエラーが出たので解決策も記載します。

Archiveの手続きは、
まずアップできる状態か、Validate　App　→　OK　なら
アップする　Distribute　App　→　アップ形式選択　→　uploadという流れです。
ウインドウを見てると直感的にわかる感じに思いました。

### Archiveしようとして、build failedになった場合。
自分の場合、firestoreがうまく入らない的なエラーがごちょごちょ出ました。```'cloud_firestore/CloudFirestorePlugin.h' file not found```と```AFNetworking/AFNetworking.h file not found```が出てました。
と、Firebase系のパッケージのバージョンはそのままでOKです。いじっても意味なかったです。pubspec.yamlもPodfileなども結局Flutterプロジェクトの場合、いじらなくてよかったことがわかりました。

__原因は、Runner.xcodeprojでリリースビルドのArchiveしようとしていたからでした。__ チュートリアルにもちゃんと書いてありますが、__本来は、Runner.xcworkspaceを開いて署名とかバンドルIDをRuunerとPodに書き入れないとエラーになる__のが初回はなぜか依存パッケージが少ないためか通ったのがエラーの原因でした。Runner.xcworkspaceで開くと依存パッケージを管理してくれるCocoaPodが動くんだそうです。Ruunerの署名とかバンドルID　と　Podの　署名とかバンドルIDの書くところ２箇所を埋めると普通にArchiveできました。

``` Cocoapods will only work in xcworkspace. ```
引用元
https://stackoverflow.com/questions/37377450/cocoapods-1-0-header-files-not-found


#Podに書くバンドルIDにも注意。

もう一つ注意事項あります。Podの方のバンドルIDですが、本来のバンドルIDに```.ios```をプラスして書く（例 本来のAppコンソールで設定したバンドルIDは```com.cocoapod.App```の場合```com.cocoapod.App.ios```　と書く。 ）と通りました。Runnerと全く同じIDだとなぜかエラー```CFBundleIdentifier collision```が出ました。下記記事参考に解決しました。

参考記事
https://github.com/CocoaPods/CocoaPods/issues/9135

### Validate時に出たエラーと解決法

 - iconのpngが透過レイヤーが入っていた

解決法→透過レイヤーをPhotoshopで消して背景も白で透けないようにして登録しなおす（flutter_launcher_iconsの一連の登録の流れをもう一度行いました。）

参考記事
https://qiita.com/rkowase/items/e0f3f8aec207ed8567aa

 - Xcode現時点最新版（Version 11.2）だとエラーがでた

```Invalid Tool chain・・・``` というエラー

https://si-best.com/wp/2019/11/10/%E6%9C%80%E6%96%B0%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%81%8C%E9%9D%9E%E6%8E%A8%E5%A5%A8%E3%81%AB%EF%BC%81%EF%BC%9F/

解決法→最新版だとなんかダメらしい。Xcode10.1を入手して、同じことやると無事通りました。


# 「輸出コンプライアンス何とかかんとか・・・」

App登録時に提出を押すとアンケートが出てきます。
ここはssh通信あればはいなど細かな規定があり。下記の記事が参考になりました。
https://www.ateliee.com/archives/3363

# TestFlight

###upload後もメールでエラーがお知らせされてきた！苦笑

```ITMS-90078: Missing Push Notification Entitlement```というエラーでした。これはXcodeでPush通知設定をONにし直して際ビルド→Archive→Distributeで回避できました。

参考記事
https://qiita.com/kokogento/items/f088f75688f44b797c2c

内部での端末を限定したテストプレイですね。
以下の記事が参考になりました。
https://qiita.com/ya8612tec/items/c72aed03749bb651ff44

# Guideline 4.2 - Design - Minimum Functionality 対策

この審査却下理由対策が一番大変でした。どういうことかというと、下記参考記事に詳しいですが、もっと機能追加などしてより良いアプリにして再提出よろしくって意味でした。

参考記事
https://kanasys.com/tech/669

審査担当者の判断にここはかかってますので、明確な改善基準はこちらで手探りで企画→実装しなければならないです。自分のケースを比較で紹介します。

### iOSリジェクト例

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">作っている最中のクイズアプリのその後のデモ進捗です。動的な値のクラス間取り扱いも解決して集計などできるようになりました。問題の中身が会社内でも発表するので取引業界色MAXの内容になっていますが、仕事でようやっとゲームアプリを扱う実績が出せそうで、嬉しいです^^ <a href="https://twitter.com/hashtag/Flutter?src=hash&amp;ref_src=twsrc%5Etfw">#Flutter</a> <a href="https://t.co/bgdz6I46gP">pic.twitter.com/bgdz6I46gP</a></p>&mdash; mawa (@k_mawa82) <a href="https://twitter.com/k_mawa82/status/1199701679865659393?ref_src=twsrc%5Etfw">November 27, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

__実装した機能__

 - 表紙
 - クイズ１種類　13問マルバツクイズ　１セット　
 - 得点集計機能

これだとダメでした。ちなみにAndroidはこれで通ってます。

### iOSアクセプト例

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今週の進捗です。ユーザー登録・ログインするとおまけにさらに３つのクイズを選べるようなメニューをつけました。ちょっとクイズあと50問くらい来週増やしてもう一度appleチャレンジするか〜^^/ DBはFirebaseで実装しています。得られた知見はそのうちQiitaにまとめる予定です。 <a href="https://twitter.com/hashtag/flutter?src=hash&amp;ref_src=twsrc%5Etfw">#flutter</a> <a href="https://twitter.com/hashtag/Firebase?src=hash&amp;ref_src=twsrc%5Etfw">#Firebase</a> <a href="https://t.co/8AuIDbkitf">pic.twitter.com/8AuIDbkitf</a></p>&mdash; mawa (@k_mawa82) <a href="https://twitter.com/k_mawa82/status/1203320493392068608?ref_src=twsrc%5Etfw">December 7, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

__実装した機能__

前回と同じ部分

 - 表紙
 - クイズ１種類　13問マルバツクイズ　１セット　
 - 得点集計機能

追加分

 - メールとパスワードでのユーザー登録・ニックネーム参加機能
 - クイズを増量 10問マルバツクイズ 5セット
 - クイズを５セットの中からどれにチャレンジするか選べるステージセレクト画面
 - ニックネームつき特典集計機能

これで通りました。なお審査はアメリカのアップル本社でしているのか知らないですが、アメリカの西海岸の日中、日本での深夜帯にリジェクトやアクセプトメールが着てましたので、返事は深夜に着やすいのかなという経験則もえました。

# リリースまでの時間計測

TestFlightで内部テスター公開は、XcodeのArchiveが完了したらその日にすぐできました。とりあえずここまでこぎ着ければFlutterプロジェクトでのコードでもiOSアプリリリースがしっかりできることがわかるので一安心しています。

TestFlightで外部テスター公開は、登録翌日に問題２点ありで審査落ち。これは、アプリの目的とターゲットは誰ってのを聞かれたのでDeveloperコンソール内のメールボックスみたいなもので直接Apple審査チームに返信を行いました。

11月28日日本時間夜 Archive→TestFlight外部テスター審査申請
↓
11月30日 TestFlight　外部テスター審査でメールで応答要請。答える。
↓
12月2日 TestFlight 外部テスター審査通過
↓　
12月4日本番審査申請
↓
12月5日日本時間早朝　審査落ち
↓
企画し直して、追加実装
↓
12月10日日本時間夜　新バージョンArchive→再審査申請
↓
12月12日日本時間早朝　アクセプト・本番リリース完了

外部テスター審査はすっ飛ばしてもいいことも判明したので、ローカル動作確認できたら、１〜２日で最速リリースできますね。エラー対応の予備日を２週間〜１ヶ月くらいは持っておいたほうがより安全かなと思いました。

↓Android版のレポートもありますのでお役に立てば！↓
https://qiita.com/k_mawa82/items/2a519b2f4cb135d2921b