Xamarin.iOSでのストーリーボードを使わない開発

 Visual Studio で Xamarin.iOS のプロジェクトを作成すると、ストーリーボードなどという忌まわしいものがデフォルトで作成されてしまい非常に厳しい気持ちになります。この記事では、それらを削除して、コードでUIを構成していくためのステップを説明します。3分ほど作業をすれば邪魔なものが消えてなくなってくれます。

1. Main.storyboard を削除

2. ViewController.designer.cs を削除

3. ViewController の余計なコードを削除する

ViewController が partial class である必要がなくなったので、partial キーワードを消します。合わせて IntPtr を引数にとるコンストラクタも不要になりました。

4. Info.plist の Main Interface を削除

5. AppDelegate に ViewController を表示するコードを追加

6. 動くサンプル

GitHub で公開しているので適当にどうぞ: https://github.com/pawotter/Xamarin.iOS.NonStoryboard

MySQL スロークエリログを fluentd 経由で elasticsearch に流し込む

MySQL のスロークエリログを fluentd で elasticsearch に流し込む流れをメモ。基本は以下のステップ。

  1. my.conf のスロークエリログ出力設定をして mysql restart
  2. fluent-plugin-mysqlslowquery を導入
  3. ログを elasticsearch に流し込む fluentd の conf を書いて td-agent restart

1. MySQL のスロークエリログ出力設定

  • docs: https://dev.mysql.com/doc/refman/5.6/ja/slow-query-log.html
  • 以下を追加して MySQL を restart すれば OK
  • 起動中の場合は set global で対応できる(restart しないでもOK)

2. fluent-plugin-mysqlslowquery の導入

  • repository: https://github.com/yuku-t/fluent-plugin-mysqlslowquery
  • 以下のような具合でおしまい

3. td-agent の conf 作成

  • 送信側

DelegatingHandlerを用いた快適なiOSアプリのHTTP通信周辺環境の整備

 昨今のネイティブクライアントアプリで、 HTTP 通信を行わないものはないと言っても過言ではないくらい、アプリ開発の基本中の基本だと思います。きっと、開発を行う中で HTTP 通信の前後に色々な処理を挟んでみたいという気持ちが湧いてくるのではないでしょうか。たとえば以下のような話です。

  1. リクエストの内容をログ出力したい
  2. 電波状況が悪いときはリクエストを走らせないようにしたい
  3. 通信中はネットワークアクティビティインジケータを走らせたい

 そんなときに System.Net.Http.DelegatingHandler はとても便利な代物です。公式のドキュメントはこちら: https://msdn.microsoft.com/ja-jp/library/system.net.http.delegatinghandler(v=vs.110).aspx

1. HTTP リクエストのログ出力

 たとえば、Http リクエストの内容をログ出力したいとすれば、以下のような簡単な DelegatingHandler のサブクラスを作ってあげるとよいでしょう。

 実用的には Console.WriteLine をクリティカルセクションに配置したほうが良いかもしれませんが、ひとまずこのような単純なコードでリクエストの手前に処理を挟むことができました。使い方は、単純にこれを System.Net.Http.HttpClient のコンストラクタに渡すだけです。これで全てのリクエストの内容がログ出力されます。

2. 圏外時にリクエストを送らない

Reachability を使えば簡単です。

3. 通信中にネットワークアクティビティインジケータを回す

 ネットワークアクティビティインジケータの管理、非常にめんどうですよね。通信が同時に複数走るのはザラなので、そのあたりを考慮する必要があると思います。だいたい皆さん同じような実装をすると思うのですが、今走っている通信の数が正であれば、インジケータを回しっぱなしにして、0になったら止めるみたいなカウンターを作るのではないかなと思います。ひとまずステップをわけて実装を見ていきます。

3.1. NetworkActivityIndicator の抽象化

 ネットワークアクティビティマネージャは基本的に ON/OFF のインターフェースさえ持っていれば十分でしょう。それぞれActivate(), Inactivate() という名前のメソッドとします。実装クラスは、UIApplication インスタンスを外から受け取り、Activate(), Inactivate() のタイミングで NetworkActivityIndicatorVisible の値に true, false をぶち込んであげれば良いという話になります。

3.2. 走っているリクエストをカウントするクラスの作成

 同時に走っているリクエストが1つ以上ある場合に IIndicatorActivate() を呼び出し、通信が走っていない状態になるとき Inactivate() を呼び出す簡単なカウンタークラスを作りましょう。

 このカウンタークラスは、通信開始時には Attach()、 終了時には Detach() を呼ぶ簡単なインターフェースを持つことになるでしょう。それぞれインターフェースと実装コードは以下のようになると思います。

3.3. DelegatingHandler の実装

 準備ができたので、今まで作ったものを利用してネットワークアクティビティインジケータを通信が走っているときにクルクルまわす DelegatingHandler を実装しましょう。以下のようになります。

 コード全体を GitHub で公開しているので使いたい方はどうぞ。MITライセンスです。 Xamarin.iOSに依存するパッケージの nuget への放流方法イマイチよくわからんので有識者の方、教えていただけると嬉しいです

  • Repository: https://github.com/pawotter/NetworkActivityManager

3.4. Swift での実現方法

 URLSessionラップして、自分で HttpClient 作ればできるよ。実装はだいたい同じ。実装的にもパフォーマンス的にも改善の余地があるコードですが、わかりやすく伝えるとするならば以下のような実装コードになる気がします。

5. おわりに

DelegatingHandler ベンリすぎワロタ。あとこれを使うとリトライ処理とかも挟めてとってもベンリ&ベンリです。良いですね〜。

Route53へのDNSとドメインの移行

次のものを AWS に移行しました。

  • ドメイン移管(53ningen.com): ムームードメインから Route 53 へ
  • ドメインネームサーバー移行: ムームードメインから Route 53 へ

また、もとの運用では存在しなかった、次のようなものを導入しました。

  • L7レイヤーでのヘルスチェック
  • DNSフェイルオーバー

この資料は自分向けの作業ログであるため、実際には各ステップ冒頭に記された公式ドキュメントを理解した上で読むことを強く推奨します。

手元環境

 作業は基本的には terraform を使って行いました。ただし、ドメインの移管に関しては Route 53 のマネジメントコンソールとムームードメインのコントロールパネルを操作する必要があります。

1. DNS を Route 53 へ移行

 ドメインも Route 53 に移管しますが、その際に元のレジストラ(ムームードメイン)が提供するネームサーバーからドメインが削除されてしまうので、前もって DNS を Route 53 に切り替えておきます。

1.1. ホストゾーン(Hosted Zone)の作成

公式ドキュメント: 既存ドメインの DNS サービスを Amazon Route 53 に移行する

 ホストゾーンとはドメインに紐づくリソースレコードのセットです。おおよそゾーンファイルと対応していると考えて良いと思います。実際にゾーンファイルを取り込むこともできるようです(公式ドキュメント: ゾーンファイルをインポートしてリソースレコードセットを作成する)。

 ホストゾーンには、パブリックなものとVPC向けのプライベートなものがあります。マネジメントコンソールからドメイン名を入力すれば作成が完了しますが、今回はこのリソースを terraform で管理します。

terraform plan は以下のとおり

 terraform apply してホストゾーンを作成すると SOA レコードNS レコード も自動的に作成されます。今回はドメイン名とIPアドレスを紐づけるために A レコード の追加が必要になります。そのため、その記述を追加します。メールサーバーの移行が必要であれば MX レコード、サブドメインなどの運用をやっているのであれば CNAME レコード など適当な感じに必要なものも移行しておきましょう。ひとまず今回は A レコード のみを作ります(Route 53 が対応しているDNSリソースは サポートされる DNS リソースレコードタイプ を参照)。terraform apply を実行するとレコードが作成されます。

1.2. DNSの変更

 マネジメントコンソールの NS レコード欄の DNS サーバーを、ムームードメインのコントロールパネルで指定します。反映が有効になるまで少し時間がかかるため、少し待って dig で確認すると良いとおもいます。

1.3. コストの計算

公式ドキュメント: 料金

 お仕事ならこの計算作業する前にやるべきですが、個人のお遊びサーバーなので作業後に計算しました。

  • ホストゾーン
    • 0.50 USD(ホストゾーンごと)/月 – 最初の25のホストゾーン
    • 0.10 USD(ホストゾーンごと)/月 – それ以上のホストゾーン
  • 標準的クエリ
    • 0.400 USD(100 万クエリごと) – 最初の 10 億クエリ/月
    • 0.200 USD(100 万クエリごと) – 10 億クエリ以上/月

おおよそ 1ホストゾーン + 最初の10億クエリ = 0.50 + 0.40 = 0.90 USD

1.4. ヘルスチェックの設定 (Optional)

公式ドキュメント: Amazon Route 53 ヘルスチェックの作成と DNS フェイルオーバーの設定

 ヘルスチェック(L7)とDNSフェイルオーバーが利用できます。ヘルスチェックで障害を検知した場合に Cloudwatch Alarm と連携をさせたり、DNSフェイルオーバーを利用して待機系に参照を向けたりすることが可能です。

 ひとまずベーシックなウェブサーバーのヘルスチェックは以下のように設定できます。その他諸々 terraform を利用する際にオプション記述については terraform 公式ドキュメント: aws_route53_health_check を参照してください。

ヘルスチェックに関しては、

  • AWSエンドポイント
    • ヘルスチェック 1 件につき 0.50 USD*/月
    • オプション機能 1 件につき 1.00 USD/月
  • AWS以外のエンドポイント:
    • ヘルスチェック 1 件につき 0.75 USD*/月
    • オプション機能 1 件につき 2.00 USD/月
  • 任意のヘルスチェック機能は以下の通りです。
    • HTTPS
    • 文字列マッチング
    • 短インターバル
    • レイテンシー計測

となっています。

「AWS エンドポイント」とは、AWS の中で稼働するリソース(たとえば Amazon EC2 インスタンス)のうち、ヘルスチェックと同じ AWS アカウントの中でプロビジョニングされるか、ヘルスチェックと同じアカウントが請求先となっているものを指します。計算済みヘルスチェックとメトリクスベースのヘルスチェックは AWS エンドポイントのヘルスチェックとして請求されます。Elastic Load Balancing のリソースまたは Amazon S3 ウェブサイトバケットがエンドポイントであるヘルスチェックについては、お客様への請求は発生しません。Elastic Load Balancing のリソースおよび Amazon S3 ウェブサイトバケットをエンドポイントとするヘルスチェックについては、AWS によって自動的にプロビジョニングされ、Amazon Route 53 の一部として追加料金なしでご利用いただけます。

1.5 DNSフェイルオーバーの設定 (Optional)

公式ドキュメント: DNS フェイルオーバーの設定
terraform 公式ドキュメント: aws_route53_record

 ヘルスチェックを入れたついでに、障害発生時に S3 の静的ホスティング機能 + Cloudfront によるメンテナンスページのほうへ参照を向けるようなDNSフェイルオーバー設定を入れてみます。DNSフェイルオーバー設定については無料で利用することができます。最終的な構成図は以下のような形になります。


 
 ディザスタリカバリを想定した構成として、ap-northeast-1 リージョンで稼働させるアプリケーションサーバーに対して、メンテナンスページを静的ホスティングする際の S3 リージョンは地理・物理的に違う系統の適当なリージョンを選択します。今回は us-east-1 を選択しました。

 S3 の前段に置いた Cloudfront は主に S3 からの配信をキャッシュする役割と、メンテナンスを表すステータスコード 503 でリソースを返す役割を持っています。S3 バケットの作成とファイルの配置、静的ホスティング機能の有効化および Cloudfront の設定は以下のように terraform で記述することができます。

terraform 公式ドキュメント: aws_s3_bucket
terraform 公式ドキュメント: aws_cloudfront_distribution

resources/error には、適当なメンテナンス表示 html ファイルを、 policies/maintenance.53ningen.com_s3_policy.json には以下のようにバケットのファイルの読み取りを許可するポリシーを配置します。

つづいて Route 53 ホストゾーンにフェイルオーバーの設定をします。通常時は既存の A レコードが有効になるようにしつつ、ヘルスチェックに失敗した場合にメンテナンスページを静的にホスティングしている S3 のほうに参照を向けるような設定を入れます。また ttl を最初の設定より短く 60 秒に変更します。 terraform を用いて次のように記述できます。

 最後に動作確認として、動いているウェブサーバーを停止し、きちんとメンテナンス表示に切り替わるか確認します。またウェブサーバーを起動したときに、ヘルスチェックが通るようになり、きちんとアプリケーションサーバーに参照が戻るかも合わせてチェックしておきましょう。

2. ドメインを Route 53 に移管する

公式ドキュメント: ドメインの移管

ムームードメインで購入した 53ningen.com ドメインを Route 53 に移管します。ステップとしては以下のとおりです。

  1. WHOIS 情報としてレジストラの情報を代理公開している場合は、ムームードメインのコントロールパネルから自分のものに変更する
  2. 確認のメールが飛んでくるので踏む
  3. AUTH_CODE をメモ
  4. Route 53 の Domain registration から Transfer Domain to Route 53 に進みドメイン名を入力
  5. AUTH_CODE を入力
  6. 移管後のDNSとして先ほど作った Route 53 の Hosted Zone を指定する
  7. AWSから移管確認のメールが飛んでくるので踏む
  8. そのうち移管が完了する

Waiting for the current registrar to complete the transfer (step 7 of 14)
ドメインが移管の要件を満たしているか現在のレジストラが確認しています。このステップは、ドメインの TLD に応じて最大 10 日かかる場合があります。

結構待ったりいろんな確認メールのリンクを踏んだりする必要がありますが、あまりテクニカルな手順はないはず…。

iOSDC Japan 2017にてベストトーク賞をいただきました

 2017/09/15〜17 の 3日間にわたって開催されたカンファレンス iOSDC Japan 2017 に参加してきました。私は2日目の 14:20〜14:50 に Track A 会場にて「RxSwift の Observable とは何か」というタイトルでセッションを持たせていただきました。

 このまわりの話をちゃんと解説しようとすると、最低でも60分は必要かなと思っていたのですが、最長の枠が30分しかなかったのでやむなしで CfP を提出しました。発表内容については以前からコードを追っかけてた分野だったので改めてする作業もそんなになく(とか思ってたんですが、以前に真面目にコードリーディングしたSwift1.2/2.x時代と比較してかったるい diff とかがあって地味に胃が痛かった)、スライドとか口頭発表原稿とかを書き起こす程度でした。ただ当時の自分は頭がおかしかったようでスライドを Illustrator + In Design で作り始めてしまい、次回から素直にパワポで作ろうと思いました(細かいレイアウトを指定できるのはいいけどめんどくさかった)。

 お話の構成をするなかで、300lines近くの実装コード解説をどうやったら、スライドとトークの内容で聴いていただく皆さまに理解してもらえるかをだいぶ悩みました。ただでさえ、発表のスライドにコードがあるとウッとなるはずなのに、それを30分間ひたすらやり続けたら、地獄でしかないので、この部分をクリアする点に力を注ぎました。そこで、ベースとなるソースコードを頭のスタック領域に置いていただくための説明に発表の半分以上の時間かけて、その上で、Reactive Extensions 特有の diff を解説するというトーク構成にしようと決めました(発表の7日くらい前に)。

 実際発表のリハーサル的なものを自分一人でやってみたんですが、どうやっても45分くらいかかってしまい、泣く泣くスライドのタイトルに(余談)という文字列を入れて、口頭発表の内容からは削ったりしました。来年から45分枠とかほしい…。

 今回のお話は決して技術的レベルの高い話ではなくて、まとめてしまうと有名な設計パターンとその発展形についてのお話でした。他の方のセッションをいくつか拝聴させていただいたのですが、私よりも技術的にはるかにハイレベルなことをやっていたり、普段自分が無意識にやっていてわりと共感できるようなお話がいくつもあって楽しかったです。

 特に面白かったセッションは @k_katsumi さんの Building High Performance and Testable UI component で、自分が普段 iOS のプレゼンテーション層を書くときの考え方とだいぶ近くて非常に共感できました。自分のやっている方法を自分自身でしっかり論理的根拠を持ってある程度正しそうという気持ちを持てるようにできるのが一番いいですが、やっぱり似たような手法を他の方もやられているという話を聞くと気持ち的には安心できますね…。

 あとは @kitasuke さんの Introducing protobuf in Swiftのあとに、Ask the speaker まわりで protobuf vs swagger みたいな話ができて楽しかった。サーバー〜モバイルクライアント間での protobuf 利用がどのようにされているのかの事例、ちゃんときいたことがなかったので興味深かった。あと protobuf とエラーハンドリングまわりの話も大変参考になった。最後には、結局APIクライアントを人間が書くことを撲滅していきましょうみたいな気持ちをみなさんと共有できたところがよかったですね…。撲滅していきましょう。

 素晴らしいセッションがたくさんある中、私の稚拙な発表を聴いていただいた皆さま、運営スタッフのみなさまなど本当にありがとうございました。そしてまさか自分がベストトーク賞をいただけるとは本当に思っていなかったので、LT枠の無限ビールタイムの時間にビール4本飲んでいい感じに意識があいまいになっていました。粗相してなかったですか?大丈夫ですか?

 ベストトーク賞の商品としてサイバーエージェントさんから素晴らしいお品をいただけるようで本当にありがとうございます。アベマTVさん最高のサービスです。アメーバブログさんでよく声優さんのブログ記事と写真を見ています。最高のサービスです。いただいたディスプレイでアベマTVさんとアメーバブログさんを見ます!

アメーバブログさんで特に見ているのは以下のブログです

アメーバブログさん最高のサービスです。私も声優さんのブログになりたい。

 2日目の発表が終わったあと、残念ながら Wake Up, Girls! 4th Live Tour 東京公演 夜の部がイベ被りしており、懇親会には参加できませんでしたが、来年 Wake Up, Girls! のイベントが被っていなければ懇親会に参加したいなと思います。ハッシュタグ見てたら美味しそうな料理と充実したクラフトビールとハイレベルなエンジニアがたくさんいてとても楽しそうだった。私、ビール(詳しくはないのですが)大好きなので、スポンサーの転職ドラフトさん来年も無限ビールお願いします。

 1日目夜のスピーカーズディナーは、やっぱり真剣に技術を追っている人たちが集まっているだけあって、楽しかった。まだまだ私は技術的にも精神的にも未熟な社畜4年生で、年上の方はもちろんのこと、最近だと高校生・大学生なのに、いまから自分がどれだけ努力しても追いつけそうにない人がインターネット上にはたくさんいるので、ちゃんと技術やお仕事に真摯に向き合う姿勢だけは忘れずに生きていきたいな、というなんか真面目な文章を、最後に書き残しておきます。

ひとまずみなさまお疲れ様でした。ありがとうございました。

appendix

iOSアプリ開発の全体像

超技術書展で頒布したiOSアプリ開発の全体像をだらだら書いた本を記事として公開。
ただのポエムです。

1. iOSアプリ開発を取り巻く環境

iOSアプリ開発には、基本的にmacOSを搭載したコンピューターとXcodeとよばれるソフトウェアが必要です。もともと主にObjective-Cという言語が使われるケースがほとんどでしたが、2014年6月にAppleがプログラミング言語Swiftを発表して以後の新規開発には、ほとんどの場合Swiftが採用されているようです。またSwiftは、Objective-Cのコードと共存できるため、もともとObjective-Cで開発されていたアプリを徐々にSwiftに移行しているという話もよく聞きます。

ただし、広告やSNSなどのSDKや、幅広く使われることが予想されていて安定性が必要なライブラリについては、依然としてAPIが安定しているObjective-Cで開発が行われているケースが多いと感じます。裏を返すとSwiftは言語としてまだ成熟していないということです。Swift2系までではマイナーバージョンアップデートでも、激しい破壊的変更が行われていました。Swift3系ではある程度落ち着きは見えますが、安定しているとは言い難い状況ではあります。それでもObjective-Cに比べて平易な構文、オプショナルやクロージャといったモダンな言語機能、そして静的型付けによる安全なプログラミングなど、得られる恩恵が大きいのは確かです。

1.1. iOS, Xcode, Swift, macOSのアップデート

Appleは定期的にiOSのメジャーバージョンアップデートをリリースしています。またSwiftのアップデートもさかんに行われています。これらに対応するためにはXcodeの更新が必要になるケースが多いです。Xcodeはファイルサイズが大きく、回線速度にもよりますがダウンロードに数十分、圧縮ファイルの解凍にまた数十分かかります。さらに、新しいXcodeを入れるには、新しいmacOSを入れなければならないことが多々あります。macOSの更新に1〜2時間かかることが珍しくありません。

実際のところ、こうした大きな更新があると最悪、半日ほど開発がストップしてしまいます。また、これらの作業は開発者やCIサーバーも含め全体のマシンでやる必要があり、考慮に入っていないと意外に手痛い時間のロストとなります。

これまでの動向では、Swift下位バージョンの切り捨ては早く、新しいバージョンに素早く追従しないと最新のXcodeではビルドができないなどの問題が発生する可能性があります。Swiftを利用すると決めた時点で、遅くとも2〜3ヶ月以内に最新のSwiftバージョンでビルドできる状態に持っていくような開発体制をとれるよう、あらかじめ開発工数のバッファをとることを強くおすすめします。

1.2. Xamarinという選択肢

iOSアプリ開発にはSwiftやObjective-C以外の言語を使うこともできます。その中でも代表的なものが、クロスプラットフォーム開発ツールのXamarinです。これによりC#やF#といった言語でのiOSアプリ開発が可能になります。これらは言語としては安定していて、C#はエンタープライズ方面での実績も十分にあります。またIDEとしてVisual StudioやXamarin Studioなどを利用することができます。ストーリーボードなどのUIコンポーネントを見た目通りに配置しながら画面を作るためのツールInterface Builder相当のことも、これらのIDEで実現可能です。

Xamarin社はMicrosoft社に買収され、現在個人での利用や特定の条件下において無料で開発環境を手にすることができるようになり、徐々に普及している段階の技術です。とはいえ、すでにフェンリル社が開発を行なったNHK紅白歌合戦のアプリなどで十分な実績があり、実用に耐えうるものといってよいでしょう。

Xamarin.iOSとXamarin.Forms

XamarinのなかでもXamarin.iOSとXamarin.Formsという2つのAPI群の選択肢があります。Xamarin.iOSはiOS SDKのAPIとほとんど1対1に対応しており、SwiftやObjective-Cと似たような感覚でアプリを構成することができます。一方、Xamarin.Formsは各プラットフォームのAPIを抽象化したものを使ってアプリを構成していくため、Xamarin.Formsに特化した知識をつける必要があります。その代わり、1つのコードから複数のプラットフォームをターゲットとしたアプリを作成することができ、開発効率の向上やマルチプラットフォーム間での実装のズレを防げるといったメリットがあります。

1.3. React Nativeという選択肢

Xamarin以外にもクロスプラットフォーム開発ツールとしてFacebookが推し進めるReact Nativeという技術があります。すでにInstagram, airbnb, Facebook Messengerなど大きなアプリですでに利用されています。各プラットフォームにおけるUIコンポーネントを抽象化したReactコンポーネントを組み合わせてアプリを構成するという思想を持っています。おおよそReact.jsと同じような形でアプリケーションを構成することができます。最近流行りのReact+Redux構成を取ることもできるため、JavaScriptに詳しい方はチャレンジしてみるのもありかもしれません。

1.4 iOSアプリ開発未経験者がとるべき選択肢

iOSアプリ開発においては、基本的にiOS SDKの基本的な振る舞いを理解することは必須であるため、経験者がひとりもいないチームでの開発はObjective-CかSwiftを採用するのが良いでしょう。当然ながら書籍や情報の量、サポートできる人材の量も一番多いです。iOSアプリ開発経験者がいるのであれば、どの方法を選んでも良いと思いますが、Xamarin.Formsを選んだ場合には、iOS SDKを直接触った場合とかなり勝手が異なるはずなので、十分な技術調査・検討を行ってから採用することを強くお勧めします。

2. iOSアプリ開発の流れ

iOSアプリはおおまかに「企画」「要件定義」「設計」「実装」という流れで開発を進めていくことが多いでしょう。最終的にはAppleによる審査を経てApp Storeでの公開が可能になります。この審査は他のプラットフォームに比べて厳しく、単純で機能が少ないアプリはAppleによりリジェクトされる可能性が高いです。例えばアプリ開発の練習として簡単な電卓などを作っても、App Store上には類似のアプリが無数にあるため、公開できない可能性があるということになります。

2.1. 企画

アプリを通してどのようなユーザーにどのような体験を与えたいのか、ターゲットユーザーと実現したいことを明確にする必要があります。似たようなアプリがある場合は、それらの調査を行い、どのように差別化を図りたいのかを検討すると良いでしょう。また「App Store審査ガイドライン」に違反する内容のアプリはたとえ出来上がっていてもApp Storeに出すことができない可能性が高いため、企画を始める段階からある程度を考慮することを強くお勧めします。特にアプリ内課金を導入する際にはAppleの審査はよりいっそう厳しくなるため、審査ガイドラインに沿った形に企画を着地させる必要があります。

2.2. 要件定義/デザイン

おおまかな企画が定まったら、アプリをどのように構成するのかを考えるフェーズに入ります。ユーザーにアプリの中をどのように回遊してもらい、どのような体験を提供するのかを具体化させていきます。また提供するコンテンツやアクションの階層構造/論理構造をはっきりとさせておくと、要件やデザインに落とし込むときに混乱を防ぐことができるので、この段階で整理しておくといいでしょう。例えば電子書籍リーダーを作る場合は、本一覧がベースの階層となり、1つ深い階層にシリーズが存在します。さらにシリーズには複数の本が紐づくといった具合です。

おおまかにやりたいことが見えてきたら、プロトタイプを作成してみましょう。紙ベースで画面を描いたり、矢印で動きを表現したりといった簡単なもので構いません。またAdobe Experience Design(XD)などを使うとより高度なプロトタイピングが行えます。実装コードを書かずにおおまかな動きを見ることができるため、複数のチームメンバ間でイメージを共有するにはうってつけのツールだといえます。iOSアプリの細かなデザインについての話は3章に記します。

2.3. 設計/実装

要件がある程度定まったら、アプリの技術的な設計フェーズに入ります。また特に要件のなかで実現が難しい点があれば、本当に実現可能なのか検証してみる必要があります。具体的な話は4章以降に記していきます。

2.4. ベータテストと品質保証

開発中はCrashlytics BetaやDeployGate、小規模であれば自前でのAd-Hoc配信などを通して開発チーム内でドッグフーディングを行うことにより、アプリの不具合検出や改善などを行います。また、ある程度の状態まで達したら開発に携わっていない第三者にも利用してもらい、フィードバックをもらえるようにしておくと、開発チームでは気づけない問題が発見できるでしょう。

いよいよリリースしても問題ないという段階が近づいてきたら、アプリの動作確認項目一覧表などを作り第三者にチェックをお願いすると、より安定したアプリをストアに出すことができると思います。これは一般的に品質保証(QA)のステップとよばれることが多いです。

2.5. 審査提出とリジェクト対応

大きなアプリとなると一発で審査をパスするのは難しく、Appleから何らかの指摘を受けてリジェクトされると思っておいたほうがよいでしょう。あらかじめリジェクトされることを想定して、ある程度アプリが出来上がってきたら、とりあえず審査に出してみるのも戦略のひとつです。これによりリジェクト対応のための仕様変更が生じる点を早めに知ることができます。

2.6. リリース

審査に通過したら晴れてアプリをApp Storeにリリースすることができます。審査提出時にはリリースタイミングのオプションがあり、そこで指定されたとおりにリリースが行われます。オプションは以下の通りです。

  • 手動でリリース: 審査通過後、リリースボタンを押したタイミングでリリースされる
  • 自動でリリース: 審査通過後、自動でリリースされる
  • 指定時刻以降に自動でリリース: 審査通過後、指定の時刻を過ぎたタイミングでリリースされる

なお、オプションはiTunes Connectというアプリの管理に使われているサービスの仕様変更によって変わる可能性があります。

3. iOSアプリのデザイン

iOSアプリのUI/UXに関してはAppleが公式に「iOSヒューマンインターフェースガイドライン」を制定しています。ガイドラインに沿わないデザインや実装を行うと一部は審査でリジェクトされる可能性があるため、開発を始める前にざっくりと目を通しておくとよいでしょう。ここではアプリ全体のデザインに影響してくるポイントを数点、記述します。

3.1. なるべく標準UIに沿ったデザインにする

特段デザインにこだわりがなければ、iOSのメールやSafari、設定画面などの標準的なアプリに沿った形でUIコンポーネントを利用し、画面を構成していくのがよいでしょう。UIコンポーネントを過剰にカスタムして使うと、場合によってはユーザーがどのように利用すればよいのか迷ってしまう可能性があります。また、iOSバージョン間で見た目や振る舞いを統一するのが難しくなり、最悪の場合は特定バージョンにおいて期待した動作を提供できなかったり、クラッシュを引き起こしたりする原因にもなります。

3.2 アプリ内の画面遷移

アプリを作る際に1画面だけで構成することは非常に稀で、ほとんどの場合には画面を遷移させる必要が出てくるでしょう。iOSの画面遷移には、主に次の2つのパターンが存在します。

  • プッシュ遷移
  • モーダル遷移

プッシュ遷移とはiOSの設定画面などで見られる右方向に階層構造を掘るように遷移するタイプのものを指します。この遷移は、スワイプで戻ることができ、コンテンツ階層間の移動をスムーズに行うのに適しています。この階層構造は、提供するコンテンツの階層構造と揃えてあげるのが一般的で、ユーザーにも理解しやすい形になるでしょう。たとえば音楽プレイヤーであるiTunesアプリは、ライブラリ→プレイリスト一覧→プレイリスト→楽曲というコンテンツ階層構造になっています。当たり前のことではありますが、きちんと分類して構成されているアプリは意外に多くありません。アプリデザインの構成を考える際に同時に提供するコンテンツ階層構造を整理することは、きっとデザインをする上でも役に立つことでしょう。

一方、モーダル遷移は、ビューが現れている間はその要素内でしか操作ができないようなものを指します。例えば、iOSのSafariのブックマーク一覧はこのタイプの遷移をします。また注意喚起のダイアログなどもモーダル遷移にあたります。何かオプションを指定したり選択したりする際に使われる傾向にあります。しかし、モーダルを閉じるには基本的にはタップをする必要があるため、ユーザーに煩わしさを感じさせてしまう可能性が高まります。最近は、モーダルビューを前の画面の上に浮いた状態で表示し、モーダル画面自体をスワイプすることで閉じる実装も目立つようになってきました。これにより閉じるためにタップをしなければならない問題が解消され、モーダル遷移に対するストレスを緩和させることができるため、可能であればそういった実装も考えてみると良いかもしれません。

3.3. デバイスの大型化とデザイン

iPhone 6 PLUSの登場時には、そのデバイスの大きさに随分と驚いた方も多いのではないでしょうか。実際iPhone 5のデバイスサイズは4インチであったのに対して、iPhone 7 PLUSでは5.5インチになっています。解像度も高くなり表示領域が増え、デザイン表現の幅が広がったのは間違いありません。

しかし、デバイスが大型化する一方で、人間の手の大きさは変わっていない点には注意する必要があります。右手でデバイスを操作する場合、左上や左下に配置したボタンなどには指が届きにくく、アプリのスムーズな操作の妨げになります。以前はモーダル画面の閉じるボタンを左上に配置するケースが目立っていたのですが、近年は右上や右下などに配置されているのをよく見ます。また、先述したとおり、モーダル画面自体を上下にスワイプすると閉じることができるように構成されているものもよく見ます。本質的には触り心地が良い形に画面を構成していければ、きっと良いアプリになるのではないかと考えています。

4. アプリをどのように構成すれば良いのか

初めてアプリ開発をする際に何に気をつければよいのか、とても不安になる気持ちは非常にわかります。筆者も初めてアプリを構成する際に何かアプリ開発特有の構成・設計を取る必要があるのではないかと思い調査をしました。結局のところネイティブアプリは、裏で処理をしつつも、ユーザーの入力を常に待ち受けつづける必要があるため、UIスレッドをブロックしないように注意するという点に注意していれば、一般的なプログラミングとほとんどかわらないと思います。したがって基本的なプログラミングができる方は何も心配せず、以前から実践していた技法を使いアプリを構成することができるでしょう。

iOSアプリ開発が本当に初めてである場合は、まずラベル(UILabel)、ボタン(UIButton)、テキストフィールド(UITextField)、画像(UIImage)などの基本的なコンポーネントの使い方を覚えると良いでしょう。続いて複雑なビューを構成する基本的な要素であるスタック(UIStackView)、テーブル(UITableView)、コレクション(UICollectionView)、スクロール(UIScrollView)、タブ(UITabBar)の使い方を学ぶと、自分の思い描いたビューを実現するための下地が整うのではないでしょうか。

4.1. 複雑な設計を採用する前に考えたいこと

近年、iOSアプリ開発をする上でどのような設計手法を取るかというような話題をよくみかけます。「iOSクリーンアーキテクチャ」や「ヘキサゴナルアーキテクチャ」など熱心に議論が行われています。これらの議論や記事ではアプリの規模感についての前提が共有されていなケースが多く、場合によっては過剰な構成となり、コードの可読性や開発のスピードを下げてしまうこともあるでしょう。開発メンバー間で考え方も一致させていく必要があり、本当に必要なものが何なのかを見極めることが非常に重要です。

iOSアプリのコードベースは往々にしてそれほど大規模なものにはならず、だいたい1万〜2万行程度で構成されることが多いと思います。アプリ全体のアーキテクチャパターンを考えることは確かに大切なことですが、私自身はSOLID原則やDRY原則、YAGNI原則などのシンプルで基本的なプログラミング原則を意識してコーディングしていくように心がけています。アーキテクチャのたくさんの決まりごとを意識しつづけるのは難しいことです。少数のシンプルで明確な決まりごとを意識していると実は自ずと、本に書かれているようなアーキテクチャになっていることは多々ありますし、そもそも複雑なアーキテクチャの根底思想にはシンプルな原理原則があることが多いと思います。

4.2. ライブラリの選定

アプリのすべてのコードを自前で書くことは稀で、多くの場合オープンソースライブラリの助けを借りることになると思います。ライブラリをうまく使いこなせば大幅に開発期間を短縮することができ、場合によっては多くの人に使われたり、メンテナンスされているため、一人で書いたものに比べ品質の高いコードを利用することができるなどというメリットもあるでしょう。

ただし、Swiftのライブラリについては、今後予想される言語自体のアップデートに継続的に対応させる必要があります。過去に大きな変更が幾度も入ったため、GitHubでStarがたくさんついていて、多くの開発者が利用しているライブラリでも、最新の言語バージョンにアップデート対応がされず、放置されていることは珍しくありません。利用する前に、メンテナンスが継続して行われているかをGitHubのPulseなどで確認しておくことをおすすめします。また、メンテナンスが止まってしまった場合、公開リポジトリからフォークして、自分でメンテナンスしていく覚悟が必要です。

これはSwiftのライブラリに限ったことではないですが、基本的にはコードの8割程度をざっくりと斜め読みし、コードの設計・品質・メンテナビリティ・適切なテストが存在するかなどを確認してから依存を決めると失敗がないと思います。また利用した各ライブラリのライセンスを遵守し、必要であれば必ずライセンス表記をしましょう。

4.3. ライブラリへの依存

ライブラリを導入すると一口に言ってもいろいろなやり方があります。たとえば秘匿情報などを管理できるキーチェーンにアクセスするライブラリを使うことを想定してみましょう。何も考えずにViewControllerの必要な箇所でライブラリをimportして依存コードをばらまいていくというやり方は、最初の実装者にとっては一番手が抜けて楽かもしれません。しかしこれには大きな問題があります。ものにもよるとは思いますが、おそらくライブラリを利用している周辺のコードは似たような実装が繰り返し登場しているのではないでしょうか?またライブラリのインターフェースが変更されたり、利用するライブラリを差し替えたりする場合、あちこちに散らばったコードに手を加える必要がでてきます。

したがって、個人的にはライブラリを利用する際にはなるべく依存コードを記述する範囲を狭くするように意識することが多いです。大半の場合はひとつのクラスの中に閉じ込めることができるはずで、その上でプロトコルを切り、実装クラスを差し替えられるような構造にするのが好みです。こうすることによってライブラリを差し替えたり、自前の実装に切り替えたりするなどの対応も容易になります。またテストの書きやすさにも繋がる場合もあると思います。

5. アプリと非同期処理

ユーザーインターフェースの存在するアプリは常にユーザーからの入力を受け付ける状態を保たなければならないという制約があります。したがって、何か重たい処理をするときは別のスレッドに仕事を任せる必要があります。この重い処理にはどんなものがあるでしょうか。例えばサーバーにデータを取得する際はリクエストを送ってからレスポンスが帰ってくるまで時間がかかります。この間ユーザーの入力を一切受け付けないアプリは控えめにいって最悪でしょう。また画像の変換や複雑な計算などはユーザーからのアプリへの入力をブロックしてしまいます。

これを避けるためには、重たい処理はユーザーからの入力を受け付ける担当とは別のものに任せればよいでしょう。ユーザーからの入力を受け付けている窓口はメインスレッドとよばれています。対してその裏で処理を行なっているものをバックグラウンドスレッドとよんでいます。また、あるタスクの実行を止めずに別の処理を行うことを非同期処理と言います。iOSアプリ開発において非同期処理はスレッドを利用して実現されていますが、Swift, Objective-Cからは開発者が直接スレッドを触ることなく非同期処理を取り扱える仕組みが用意されています。それがGrand Central Dispatch(GCD)とオペレーションキューになります。それぞれどのようなものかざっくりと特徴をみていきます。また、Appleが公式で提供している「並列プログラミングガイド」および「スレッドプログラミングガイド」を参照するとコードレベルの技術詳細に迫ることができると思いますので、ご覧ください。

5.1. Grand Central Dispatch(GCD)

GCDを利用する場合もオペレーションキューを使う場合も、基本的にはキューにジョブを積むというのが基本的な実装内容になると思います。ではこの2つの何が違うのかというと、用意されているキューの種類とジョブをクロージャで渡すのか、オブジェクトで渡すのかという点になります。

GCDには、キューイングされた処理を逐次実行していく直列ディスパッチキュー(Serial Dispatch Queue)と並列に実行していくのが並列ディスパッチキュー(Concurrent Dispatch Queue)が用意されています。さらに特別なキューとしてメインスレッドで行いたいタスクをキューイングするためのメインディスパッチキューというものが用意されています。メインスレッドはひとつしかなく、並列にできないので当たり前ではあるのですが、これは構造的には直列ディスパッチキューになります。

さて、実際のアプリの中でこれらがどのように利用されるかを少し想像してみましょう。例えばボタンを押したイベントを皮切りにサーバーにHTTP通信を走らせ、その結果をテキストボックスに表示するケースを考えてみましょう。最初にメインスレッドがボタンの押下イベントを受け付け、イベントハンドラを呼び出します。続いて、イベントハンドラは並列ディスパッチキューにクロージャをわたして、あとの処理をバックグラウンドスレッドにお任せします。このように、裏側で行わせたい仕事をキューに積んで放置することにより、ユーザーからの入力を受け付けられる体制に即座に戻ります。一方、バックグラウンドスレッドではどのようなことが行われているでしょうか。並列ディスパッチキューに渡されたクロージャの中身をみてみましょう。まずHTTPリクエストをサーバーに送るでしょう。そしてレスポンスが帰ってきたら、そのデータをよしなに加工して、テキストボックスに反映させる必要があります。このときに注意が必要で、基本的にUIコンポーネントを更新する際はメインスレッドでやる必要があります。したがって、加工し終わったデータの準備ができたら、今度はメインスレッドに処理を行わせるための直列ディスパッチキュー(DispatchQueue.main)にクロージャでお仕事を渡します。お仕事内容は単純にデータをテキストボックスに反映させるだけです。

5.2. オレペーションキュー

オペレーションキューを用いる非同期処理では、タスクを表現したデータ構造であるOperationを作り、キューに渡していくという流れになります。したがってあらかじめタスクを仕込んでおいて一気に並列/直列で実行するなどということが可能です。実際のところGCDのラッパーでしかないため動作原理はほぼほぼ同じになります。しかし、クロージャではなくタスクというオブジェクトを引き回せることでより柔軟で複雑なプログラミングが可能になると思います。

5.3. スレッドセーフな実装

複数のスレッド間で共有されるオブジェクトは不正な状態になる可能性をはらんでいます。不変なオブジェクトであれば問題はないですが、状態を持つオブジェクトには不正な状態になることを防ぐための実装を施してあげる必要があります。一般にマルチスレッド間でのオブジェクト共有に対して安全であることをスレッドセーフな実装とよんでいます。スレッドセーフな実装を実現させるためのツールにはアトミック操作とメモリバリア、ロック、条件変数などがあります。それぞれ特徴が異なっており、用途に適したものを利用する必要があります。詳細についてはAppleが公式で提供している「スレッドプログラミングガイド」を読むと良いと思います。

6. アプリ内通信のこれから

多くのアプリではウェブAPIを利用したり、画像/音声/動画リソースをインターネット上から取得します。これからSwift/Objective-Cで開発をはじめようという方はどのようにしてHTTPリクエストを走らせるのかという点が気になるのではないでしょうか。

ネットで検索をするとAFNetworkingやAlamofireといったライブラリの名前がヒットすると思います。しかし個人的には標準で提供されているURLSessionで十分足りると考えています。複雑なPOSTリクエストの組み立てなどには一部ライブラリの助けがあると楽をすることができるかもしれませんが、それを除けばライブラリに実装されている機能を利用する機会はそれほど多くないでしょう。通信ライブラリに限らない話ですが、本当にそのライブラリを導入する必要があるのか、よく検討してみてください。

6.1. App Transport Security

App Transport Security(ATS)とはiOS9.0以降で導入されたサーバークライアント間でのセキュアな通信を保証するための仕組みです。Appleが推奨するTLSバージョンと暗号スイート、サーバー証明書とそのハッシュアルゴリズム、サーバー証明書の署名キーを満たしていない場合に接続エラーとなります。

2017年4月現在ではATSに対応することは必須ではなく、HTTP通信やAppleの推奨条件を満たさないHTTPS通信を行いたい場合は、Info.plistに設定を追加することでATSによる接続エラーを回避することができます。しかしながら、AppleはATSに正当な理由なく対応していないアプリをリジェクトするとの予告を出しており、今後アプリ開発をしていく上ではこれに対応することはほぼ間違いなく必須条件となるでしょう。

少なくとも自前で立てているサーバーと通信を行う場合は、Appleが定めた推奨条件に対応させましょう。ただし自分の管理外サーバーとの通信を行う場合は、ATSに対応しない正当な理由として認められるようです。

6.2. APIクライアントは人間の書くものではない

大半のアプリではREST APIを叩き、そのレスポンスをもとにビューを更新するなどの処理が入るのではないでしょうか。こんなときにはAPIクライアントの実装が必要になるでしょう。

残念ながらSwiftでAPIクライアントを書く作業はSwiftyではありません。URLSessionを用いてレスポンスを取得し、正常なリソースが得られたらJSONなりXMLなりをパースしてJSONObjectを手に入れます。続いてJSONObjectの各キーから値を取り出してSwiftで定義したエンティティの構造体にマッピングします。JavaやC#などを使うとシリアライズやデシリアライズの工程はだいたい手で書く必要はなく、十分に実績のあるライブラリが自動的にやってくれるため、とてもSwiftyなのですが、Swiftには現在そのような機能を実現するライブラリは存在しないようにみえます。またあらかじめスキーマが決まっているエンティティの構造体を書くのも非常に面倒臭い作業で自動化したい機運が高まります。

APIクライアントのレイヤーを自動で解決するための方法はいくつかあります。ひとつ目はSwaggerというREST API作成のためのフレームワークを利用する手法です。仕様を表現したYAMLファイルから自動でAPIクライアントのコードを生成できるのが特徴です。

またREST APIからは外れますが、Protocol Buffersを使うことによりデシリアライズやエンティティの作成を自動化できます。こちらはサーバー側から送出されるレスポンスもProtocol Buffersに対応させなければならないため、自前のサーバーを利用したアプリ作成のときに使える手段となります。サーバーとクライアント間の通信も含めて、すべて自動でコード生成したい場合はRPCフレームワークのgRPCの利用を検討してみてください。

7. ユーザーに笑顔を届けるまでがiOS開発

Appleによる過酷なダンジョンを切り抜けついに審査を切り抜けたみなさんは、ついにリリースボタンを押すことになるでしょう。いままで開発をすすめてきたメンバーと一緒にリリースボタンを押すとウェイ感がでてとてもエモいので是非おためしください。

7.1. AppStoreのねぼすけ

さて、時間はお昼の12時、無事リリースボタンを押した我々はAppStoreに飛び、アプリをダウンロードしてみようと試みます。しかしながら、アプリは見当たりません。Appleの実装はとてもlazy(怠惰)なのでリリースボタンを押してから反映までに30〜60分程度要すると思っていただいてよいでしょう。もし決まった時間にプレスリリースやSNSなどでリリース告知をする際には、あらかじめこっそりとアプリをリリースして、AppStoreに反映させておくのが良いと思います。

そんなこんなでアプリは13時にはストアに反映されていたとしましょう。ところがtwitterでエゴサするとダウンロードがうまくできないとの酷評が。リリースと同時につけられる1ツ星評価。実際のところ何が原因か分かっていないのですが、お昼の時間帯などはAppStoreからのダウンロードがうまくいかないときがあるようで、個人的にはリリースはアプリのユーザーがアクティブでなくなってくる時間帯にするようにしています。個人的にはAppStoreのアプリ配信サーバーを増強してほしいという気持ちをここに掲載させていただきます。

7.2. 俺たちの闘いはこれからだ!

アプリをリリースして、開発を終わらせるぞ!そう思っていた時期が私にもありました。しかしアプリ開発はリリースしてからが本番です。まずは多くのユーザーに使ってもらうためにきっと様々な仕掛けが必要でしょう。また発生させてしまった不具合の対応や、アプリをさらに快適に利用できるような新機能の提供などやることはたくさんあるはずです。そう、俺たちの闘いはこれからだ!

System.Net.Httpのリクエストやレスポンスをロギングする

SwiftのURLSession使って自前でHttpClient書いてたときは、リクエストパラメタとかいろいろをデバッグ時にログ出力してくれる便利なやつを自作していたんですが、.NETのHttpClientまあそのまま使うので、ロギングどうしようと思ってたらちゃんと用意してくれている。とても良い。

これを使ってリクエストを送ると例えば以下のようなログ出力が得られる

便利

仕事の基礎英語を見ながら気になったフレーズをメモ (1)

  • No. The director says that the impact of this change will be minimal since he only needs to make some revisions to the narration.
  • minumal: 多少の影響
  • minuscule: ほぼ影響ない
  • A company is going to merge with B company.
  • We are here at A company and just found out that there will be a merger with B Company soon.
    • 伝えたい内容は後半の there will be 句なので自制の一致が破られる
  • We have ordered some work from them, but we have not signed any contract or paid anything. There will be no legl repercussions if we cancel the work, right?
  • repercussions: 波紋・余波(語源 – cuss: 叩く)
  • This has bad repercussions.: これは(あとに)響く。
  • With all due respect: 恐縮ですが
  • it turned out => 隠された状態がターンして中身が見えるので「明らかになる」という意味を持つ
  • would you be open to -ing: 〜ということにしてもよいですか?
  • it doesn’t match the product: 製品にあっていない(あっていないが、お前が悪いという印象を与えない)
  • We have an interview request that would be great PR => will be だと確信をもって「良いPRになる」 とつたえることいになる
    • We have <******> request という表現も良いな〜
  • We can’t give you too much more information at this stage
    • at this stage => 現時点では
  • Trust me, it will be a helpful, cutting-edge product.
    • cutting-edge product => 最先端の

異世界に転生して2ヶ月以内に漫画を書かないと死ぬことになった人間の物語

このポエムは絵を全く描いたことがない人間が、コミックマーケット92で4コマ本を出すまでの流れを淡々と描いたものです。

===

2017年6月のある日の朝、目覚めると、足元には Microsoft 社製新型デバイス「Surface Pro 5」が転がっていた。朦朧とした意識の中デバイスを箱から取り出し、電源を入れると突然穏やかでないメッセージが現れた。

「2ヶ月以内に漫画を描いて入稿しなければお前は死ぬ」

漫画を書くと言ってもどうすればよいのだろうか。美術の時間はだいたい岡本太郎のモノマネと称してむちゃくちゃな線や色を塗って素晴らしいとか自画自賛していたので、まともな絵がかけるわけない。あ、ちなみに岡本太郎さんの本結構面白いのでおすすめです。高校時代に3冊ほど読んでゲラゲラ笑ってたので中二病真っ盛りの方には刺さる本ではないかと思います。

さて、幸いにして、テキスト物の構成・レイアウトは前々からやっていたので、本を作るプロセスはだいたいわかっている。問題は絵が描けないという点だ。これを解決しなければどうにも本にならない。

そこで我々は、漫画を描く方法を探しに、異国の地 Google へと足を運んだ。現地住民への聞き込み調査の結果「Clip Studio」というソフトウェアが良いということがわかった。さっそく、いくつかのリンクを踏んでポチポチとボタンを押していくと購入が完了し、ソフトウェアのダウンロードが始まった。

インストールをすませソフトを起動するとよくわからない設定画面がでてきた。解像度、キャンバスサイズ…よくわからないし、非常に面倒臭い。とりあえず漫画の殿堂・芳文社の「まんがタイムきららの投稿・持ち込み募集のページ」を見てみることにした。URLがcontributionとなっているあたり、GitHubのオープンソース開発と似ていて親近感を強く感じる。なるほどなるほど?

とのこと(600dpi、えっマジ…なんで…?というあたりの理由はまだよく理解していない)。さっそく同様の設定を行い、とりあえずキャラクターを書き始める。線がまっすぐ引けない。描いた本人もなんのキャラクターを描いたのか認識できない。私は「ご注文はうさぎですか?」という作品が少し好きなので、正直言ってこんなイラストを本にまとめているのを見かけたらちょっとムッとしてしまう。キャラクターに対する愛も何もないひどい線画だった。

2ヶ月で形になる自信が全くなかったので、同僚のリゼさんに絵の書き方を教えてほしいと頼み込んだ。するとリゼさんは2冊の本を貸してくれた。「ヒロマサのお絵かき講座(顔の描き方編・体の描き方編)」だ。なるほどなるほど。とりあえずやってみよう。

という感じで、イラストの練習をする日々が始まった。

はじめのいっぽ

とりあえず好きなキャラクターの好きな構図を線が汚くなってもよいので、きれいなバランスになるようにひたすら書き進めていった。同じ絵を繰り返し描いていくと下手なりにこなれてくるのだが、線をきれいに描きたいという意識のあまり、異常に拡大した状態で書き進めていってしまい、結果全体のバランスが悪化するという現象が発生した。

また、拡大しているので、線が細すぎることに気づけず、仮で印刷してみると線がかすれてしまうということも起きた。テキストもの作るときに基礎レイアウトができたらひとまずコンビニのプリンタで印刷してみる個人的な習慣があるのですが、これのおかげで線が異常に細くて、印刷時に乗らないことに気づけてよかった。

絵が描けない人間が4コマを描くのは愚かな選択である

4コマ漫画はその名前のとおり、すでにコマが定められていて、あとは絵を描くのみなのだが、実は普通の漫画のほうが楽な側面もあることにだんだん気付きはじめてしまった。というのも4コマ漫画は1ページに柱2本分割り付けるとすれば、8コマ存在することになる。ということは、よほどのことがない限り1ページに8つ以上のキャラクターを描かなければならないのである。

また、4コマ漫画はキャラクターどうしのやりとりを描いたストーリーになることが多く、目線のコントロールやキャラクターどうしの位置関係をきっちりと描かないと意味が通じない内容となってしまう。

普段何気なく読んでいる漫画の殿堂・芳文社のドキドキビジュアル全開マガジン「まんがタイムきららMAX」の尊さを、自分が絵を描くことにより感じることになるなんて思わなかった。はじめて本を描く方は4コマを描くという愚かな選択を取る前にどうか、この事実に気づいてほしい。

レイアウトとイラスト制作の違い

イラストレーターでの図版の作成とイラストの大きな違いにも気づいた。基本的にイラストレーターでの制作物は理詰めで、いくつかのレイアウトルールにしたがって版面を構成していったり、曲率を計算したりすることによって、必ず図形が再現できるような進め方をしていくことが個人的には多い。

一方、イラストについては服のこの部分に線がなぜこういう角度で入っているとシワっぽく見えるのか、体のパーツの配置がなぜこうなっているのかといったある種のルール的なものを適用することによりバランスを整えていくことができる部分があると感じた一方で、実際に線を引くのは自分の手の感覚を鍛えていくしかなく、伝統芸能に近い要素が非常にあると感じた。なんどもなんども線を引き直しても、自分の頭の中で描いているような線にならない。部分的に満足のいく線になっても、全体のバランス感がおかしいなど、いくらやっても自分自身が許容できるレベルに達しない状態が続きながらも、どんどん入稿日はせまってくるのです。

なんとなく分かっていたけど、やっぱり2ヶ月で絵をなんとかするのは、あまりにもハードルが高すぎると感じたし、巷にあふれているように見えるイラスト・漫画に対して非常に強い敬意を感じるようになった。絵を見かけると、この人はこの絵を完成させるまでにどれくらいの時間と労力と気持ちを注ぎ込んだのか、少しは理解できるようになった気がして、その尊さを感じるようになった。

描けなかったカラーイラスト

この本の真の目的は、「ご注文はうさぎですか?」単行本の装丁と揃えてあげることでした。したがって、冊子の表紙は厚めのマットな用紙に対して、ブラウンのシックな雰囲気のもの。中表紙に関してはカラーで、できればイラスト。そして、ブックカバーには、SEとしてかわいらしく働くラビットハウス三姉妹の様子を描きたかった。時間も技術もなかったので、目標は達成できませんでした。

コミックマーケット92当日

まわりに有名サークルの素晴らしい本がたくさんならぶなか、アルザスの木組みの街を紹介した「木組みの街の歩き方」という謎の本と、今回のふざけた「ご注文はSEですか?」という漫画を頒布する謎の浮わついたサークル「きらきらアラモード」がブースを出しました。こんな本です。

意外にみなさん手にとっていただいて、本当に自分が一番驚いているのですが、目標としていた部数を午前中に突破して、閉会直前に持ち込み分全て完売という、大変ありがたい結果となりました。イラストの技術はないのですが、作品に対する愛を強く込めた本だったので、受け取ってもらえて嬉しかったです。

特にこの本をあらかじめチェックしていて、中身をチェックすらせず買っていってくれた方も多数いて、こちらから思わず「中身見なくて大丈夫ですか?」とか聞いちゃったりしてました。あと本の中身のネタについて共感してくださるような感想をいただけたのも嬉しかったです。

また昨年、冬の本は、ごちうさ島ではなく、アニメ(その他)ジャンルの聖地巡礼島に出していて、かつ開会から1時間半で完売してしまったため、わざわざ反対のホールから足を運んでくださった方にお渡しすることができませんでした。夏に改めてブースにきていただき「前回買えなかったので増刷していただいて嬉しい」との旨の言葉を4〜5人の方にかけてもらえたのも非常に良かった。

あとは「木組みの街の歩き方」の装丁について、特に「変形A5版」である旨にぱっと見で気づいて指摘してくださった方がいてこれは本当に嬉しかった。地球の歩き方シリーズのパロディ本だったのですが、これは標準規格のサイズではなく、縦A5版をカットして細長くしたサイズだったのです。こうした変形裁断に対して無線綴じでそれなりに手頃な価格で仕上げてくれる印刷会社さんはほとんどなくて結構苦労しました。最終的には、会社の先輩に教えていただいたイニュニックさんという印刷会社さんが本当に素晴らしいクオリティで仕上げてくださり本当にありがとうございますという感謝の気持ちでいっぱいになっています。

また、ブースにはおなまえは伏せますが、神絵師の方々がわざわざ足を運んでくださり、インターネットでいつも観測している、あのアイコンの方だ!みたいな方もたくさんいらしていただき、本当にありがたい限りの夏コミでした。

唐突な宣伝

冬コミで出したごちうさ舞台探訪本については増刷分、在庫わずかですが COMIC ZIN さんで委託通販を行なっています。
また、夏コミ新刊「ご注文はSEですか?」については今後、どこかしらのショップに委託をする予定ですので、ぜひよろしくお願いします。

http://shop.comiczin.jp/products/detail.php?product_id=30771

結論

もう二度と絵は書きません。

以下、弊サークルの打ち上げの様子です。

フルール・ド・ラパン社に入社しました

本日から新卒で入社して以来、およそ3年半働いていたラビットハウス社に所属したまま、フルール・ド・ラパン社でも働くことになりました。

3年と少し前の春から住み込みバイトしているラビットハウス社はとてもいい会社で、かわいい妹のJavaちゃんや、同僚のSwiftちゃんと楽しく働いています。これからもそちらで働きつつ、この度フルール・ド・ラパン社でも働ける機会を得ることができました。

せっかくいただいたチャンスなので、ラビットハウス社とは違う、フルール・ド・ラパン社のかわいい制服や、豊富なフレーバーティーを楽しみつつ、新たなチャレンジをしていきたいと思っています。一緒に働く皆さん、ぜひよろしくお願いします。

退職エントリではないので、Amazonの干し芋のリストは貼りませんが、随時献金は募集していますのでtwitterのDMで現金を振り込みたい旨、ご連絡ください。追って銀行口座をご連絡いたします。

あとフルール・ド・ラパン社に興味のあるエンジニアのみなさんも、是非お声がけください。一緒に働きましょう。

最後に告知系を2つ

C92

2日目-東ネ23a: サークル「きらきらアラモード」より、ラビットハウス三姉妹がシステム開発を受託するお仕事日常系漫画「ご注文はSEですか?」を頒布いたします。ぜひよろしくおねがいします。

漫画書けもしない状態から、血迷って Surface Pro 4 と CLIP STUDIO を買ってしまい、FC(青年)ジャンルでブースももらえてしまったので、ラビットハウスで働く同僚に絵の書き方を教えてもらいながら頑張って書きました。

絵、実際に書いてみて、twitterなどでながれている絵はどれくらいの労力が費やされたものなのか多少なりとも雰囲気はわかるようになり、その尊さを感じられるようになったのは、やってみてよかった点だとおもいました。

あと、普段みている漫画の各巻での作画の違いとか細かいところにちょっとずつ目に止まるようになってきて、そういう点も面白みがありました。拙い漫画ですが、是非よろしくお願いします。

iOSDC 2017

9/15〜17に早稲田大学で開催されるiOS関連技術のカンファレンス「iOSDC Japan 2017」にてRxSwiftのObservableについて30分の講演を行います。とてもヒマでしょうがない方は是非見にきてください。本当は1時間くらい喋りたかったんだけどそんな枠はなかった。最長の30分枠をもらえたので、ちゃんと準備して良い発表できるように頑張ります。

その他、随時どっかしらでふらふら発表していたりしますが、細かいことまとめるのめんどうなので、適当にcompassからの通知を拾っていただければ…。

最近死ぬほど忙しい(※ 趣味の予定を詰め込みすぎました)ので技術系の記事をまとめきれてないのですが、記事にするネタ(というか個人用のメモ)もたくさん溜まって来たので、ちゃんとここにまとめて置きたい。あとでやります。

現場からは以上です。