[Flutter開発]FlutterとARKitを組み合わせてiPhoneのARアプリを作成してみる

# はじめに
iPhoneでAR（拡張現実）を表示できるアプリを作ってみようと思う。
iOSでARアプリを作る場合はApple公式のARkitを使用するのが一般的だと思うが、このARkitをクロスプラットフォームアプリを作成できるFlutterで使えるようにしたい。

有り難いことに、FlutterでARkitを使用するための「arkit_flutter_plugin」というパッケージがpubで公開されており、さらにこのパッケージを使用したサンプルも公開されているので、まずはこのサンプルをiPhone上で動かすことを目標とする。

## AndroidでARアプリを作成したい場合
[[Flutter開発]FlutterとARCoreを組み合わせてAndroidのARアプリを作成してみる](https://qiita.com/s_harada/items/44c50ea22d006b972897) という記事も作成しているので、こちらを参考にしてほしい。

# 環境情報
## 開発環境
* MacOS Mojave `10.14.6`
* Android Studio `3.5`
* Flutter `1.10.3-pre.66`
* arkit_plugin `0.2.1`

## 端末環境
* iPhone7(Simulator) `iOS 12.4`
* iPhone7(実機) `iOS 12.3.1`

# 作成手順
## 新規のFlutterプロジェクトを作成
新規のFlutterプロジェクトを作成する。名前は「flutter_arkit_test_app」としてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/b446ec59-c151-7e86-3366-314cd651311e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/e2131327-278a-ab92-ecba-9e823c205c40.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/32f18840-2a27-4fbe-fc67-40bd8091ae88.png)


## arkit_pluginのインストール
Flutterプロジェクトを作成できたら、pubspec.yamlを開いてarkit_pluginの記述を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/67befb09-9153-f61b-94b3-7fed63190d26.png)

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

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  arkit_plugin: any #この行を追加
```

main.dartを開き、「Get Dependenceis」を押してarkit_pluginをインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/0f38f401-c3ee-946d-1b88-7efafe2b61bd.png)

コード0が表示されればインストールは成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/2a208bd8-e52d-3c2a-6a3b-d06b20754adf.png)

## main.dartの書き換え
main.dartを以下の内容に書き換える。

```main.dart
import 'package:flutter/material.dart';
import 'package:arkit_plugin/arkit_plugin.dart';
import 'package:vector_math/vector_math_64.dart';

void main() => runApp(MaterialApp(home: MyApp()));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ARKitController arkitController;

  @override
  void dispose() {
    arkitController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(title: const Text('ARKit in Flutter')),
      body: ARKitSceneView(onARKitViewCreated: onARKitViewCreated));

  void onARKitViewCreated(ARKitController arkitController) {
    this.arkitController = arkitController;
    final node = ARKitNode(
        geometry: ARKitSphere(radius: 0.1), position: Vector3(0, 0, -0.5));
    this.arkitController.add(node);
  }
}
```

## /ios/Runner/Info.plist の書き換え
Android Studioで`/ios/Runner/Info.plist`を開き、以下の4行を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/ee908a2d-e60d-266f-02bf-8c73f3c4dda1.png)

```Info.plist
    <key>io.flutter.embedded_views_preview</key>
    <string>YES</string>
    <key>NSCameraUsageDescription</key>
    <string>Describe why your app needs AR here.</string>
```

※「Describe why your app needs AR here.」の部分は用途に応じて書き換えたほうが良いかもしれないが、とりあえずサンプルのままとしている。

# 実行してみる
## iPhone7(Simulator)で実行してみた結果
なにやらデバイス周りのエラーが出ていてシミュレータでは素直に動いてくれない模様。
こういうときは実機のほうが早いので（特にiOSシミュレータでカメラ周りの機能を使う場合）、実機での動作確認に切り替える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/37846679-e75e-cb8a-d2ba-1a1126ca215f.png)

## iPhone7(実機)で実行してみる
実機で実行しようとした場合でもエラーが出たが、このエラーはだいたい予想がつく。
Provisioning Profileが見つからないという内容だ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/b1d95add-926d-9251-bb6f-9367694f6442.png)

Xcodeを起動し、Flutterプロジェクトの`/ios/Runner/`を開く。
RnnnerのSigningで、Termが指定されていない類のエラーが表示されていると思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/c8c50eb6-edbd-e9bd-566f-e8a4e1d9ec5a.png)

TermにiPhoneと同一のAppleIDを指定してエラーが解消されることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/9116d5a8-c6f5-6d06-5684-e61206ab1dbe.png)

再度Flutterプロジェクトを実行し、サンプルをiPhone上で確認できれば成功。
カメラの映像上に3Dの球体がARで合成されて表示されるはずだ。
![iOS の画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/b027e9f9-6b3e-c978-8dec-b7350c930e16.png)

## その他のサンプル
以下のGithubリポジトリをクローンし、exampleをAndroid Studioで開いてこれまでの流れと同様の手順で実行すれば、各種ARのサンプルを見ることができる。
[ARKit Flutter Plugin](https://github.com/olexale/arkit_flutter_plugin)

各種ARサンプルの概要はpub.devの[arkit_flutter_plugin](https://pub.dev/packages/arkit_plugin#examples)を参照。

### サンプル実行時の注意点
サンプルのRnnnerも、そのままだと動かないので自分の環境に合わせて変更する必要がある。
まず「Bundle Identifier」は、自身のCompany domainに書き換える。（Flutterの新規プロジェクトを作成するときにデフォルトで表示されているCompany domainと同じでよい）
あと、Termでもエラーが出ていると思うので、ここもこれまでの手順と同様に自分のAppleIDに変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329353/3641a7e6-20be-0b0b-99b8-d93907b165b9.png)

# まとめ
Provisioning Profileまわりのエラー以外は特に難しい問題もなく、意外とあっさりとサンプルを動かすことができた。
まだサンプルの内容を読み込めていなが、実装は通常のFlutterとDartの書き方に則っており、読み進めることや試しに改変してみることはやりやすそうだ。
このサンプルを足がかりに、次のステップはオリジナルのARアプリを作成してみたいと考えている。

# 参考URL
* [pub.dev (arkit_flutter_plugin)](https://pub.dev/packages/arkit_plugin)
* [Github (arkit_flutter_plugin)](https://github.com/olexale/arkit_flutter_plugin)