【個人開発】メモアプリのiOS版をリリースした話【Flutter】

## はじめに
Flutterで開発したメモアプリのiOS版をリリースしました。android版から遅れて約2か月くらいです。android版リリース時の記事は[こちら](https://qiita.com/taki0010/items/c38827089ef04d01c91a)。

今回は、android版リリース後に必要だと感じた機能を実装するために利用したパッケージなどを中心に書きたいと思います。

https://play.google.com/store/apps/details?id=com.karas.notespod

https://apps.apple.com/jp/app/notespod/id1600436936

---
### receive_sharing_intent　[→](https://pub.dev/packages/receive_sharing_intent)
この **Notespod** は、メモにいろんなデータを添付できるアプリです。ストレージ内のデータについては`file_picker` のようなパッケージで持って来ればいいんですが、Web上のデータについてはURLのコピペを前提にしていました。しかしこれはよくないなと思ったので、『共有』ボタンをタップするだけでスムーズにメモに取り込めるようにしました。その際に活用したのが `receive_sharing_intent` です。

android版に関しては特に問題なく実装できたんですが、iOS版に関してはかなり難航しました……Swiftがわからないのでエラーへの対処の仕方がわからない！　しかし何とか実装できたので、自分の環境で動いた方法をまとめます。

#### 1.GitHubの最新のexampleを参照する
鬼門は　`info.plist` と `ShareViewController.swift` だったんですが、Pub.devのReadmeにあるこのふたつと、GitHubのexampleにあるそれが微妙に違います。おそらくGitHubの方が最新だと思うんですが、そちらを参考にして実装したら上手くいきました（最初は普通にPub.devでやっててハマった）
#### 2.パッケージをGitHubから取得する
`type 'SwiftReceiveSharingIntentPlugin' has no member 'instance'` というエラーが出ましたが、これは最新版をGitHubから取得することで解決しました。
#### 3.シミュレーターは無視する
今でもシミュレーター上では落ちたり固まったりするんですが、実機では問題ありません。シミュレーターは無視しましょう（これも何とかしようとして無駄に奮闘してしまった:expressionless:）

これが初iOS開発だったこともあって、Xcodeの扱いも含めて難儀しましたが、結果的には何とか実装できました。ブラウザだけでなく他のアプリからも、テキスト、画像、PDF、URL（Webサイト）といったデータを取り込めます。

下の動画はブラウザからUnsplashの画像の取り込んで既存のメモに追加するものと、ニュースアプリからURLを取り込んで新規メモを作る動画です。
![Simulator Screen Recording - iPhone 12 Pro Max - 2022-02-13 at 15.03.07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369656/8421deb1-815e-2370-37c4-45c682be2bb2.gif)
![Simulator Screen Recording - iPhone 12 Pro Max - 2022-02-14 at 11.41.02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369656/47640dd7-2b92-1d34-7fba-6189bfc7a885.gif)


### Share_plus　[→](https://pub.dev/packages/share_plus)
メモの添付データをSNS等にシェアできるようにする必要性を感じたので、このパッケージを導入しました。下記のツイートのように、アプリ内で簡単に作れるグラフ（後述）なんかも共有できます。

https://twitter.com/taki0010/status/1494119817267548160

###### 単語が共有できないバグ
[こちら](https://github.com/fluttercommunity/plus_plugins/issues/701)ですが、iOS版で単語が共有できない症状に見舞われました。このアプリはフレンドシステムを搭載しているので、フレンドコードを共有できないと不便になってしまいます。後ろにスペースつければ動くので、共有するときにはスペースをつけて入力時に前後のスペースを削除する仕様にしました。


### Fl_chart [→](https://pub.dev/packages/fl_chart)
ちょっとしたグラフを簡単に作れたらイイねと思って導入しました。円グラフと棒グラフがサクッと作れます。共有する際の画像化の処理は、だいたい以下の実装で動くはずです。

```dart
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:fl_chart/fl_chart.dart';

class BarChartView extends StatefulWidget {
  const BarChartView({Key? key}) : super(key: key);

  @override
  _BarChartViewState createState() => _BarChartViewState();
}

class _BarChartViewState extends State<BarChartView> {
  GlobalKey globalKey = GlobalKey();
  
  Future<Uint8List> _capture(GlobalKey key) async {
    final RenderRepaintBoundary boundary =
        key.currentContext!.findRenderObject()! as RenderRepaintBoundary;
    final ui.Image image = await boundary.toImage();
    final ByteData? byteData =
        await image.toByteData(format: ui.ImageByteFormat.png);
    final Uint8List pngBytes = byteData!.buffer.asUint8List();
    return pngBytes;
    }
    
  @override
  Widget build(BuildContext context) {
  return Scaffold(
          appBar: AppBar(
          actions: [
            IconButton(
                icon: const Icon(Icons.share),
                onPressed: () async {
                  final imageData = await _capture(globalKey);
                  // ここに共有処理
		      })
            ],
          ),
	  body:RepaintBoundary(
	    key: globalKey,
	    child: BarChart()
	  )
    )
  }
}
```

### ほかバグ対応
Flutterをアップグレードすると無視できない不具合([これ](https://github.com/flutter/flutter/issues/95343))が出たので、ずっとバージョンを`2.5.3`に固定してたんですが、`2.10.1`で解消したのでやっとアップグレードできました。スレはまだ続いているようですが、似たような症状の方いれば、一度`2.10.1`を試してみることをお勧めします。


### 今後の予定
タブレットのUIを何とかしたい:frowning2:　UIの分離の重要性ってこういうことかと実感（遅い）


### ところで
共有する際に、共有先のアプリ一覧に自分のアプリを出したくないんですが、やり方あるんでしょうか？　ご存知の方いれば教えていただけると……:pray: