既存開発と iPhoneX 対応を両立するために、あえてビルドを失敗させる

この記事は Tech KAYAC Advent Calendar 2017 の5日目の記事です。

毎回誰にも共感されない

techblog.kayac.com

techblog.kayac.com

な記事を書いております Lobi で iOS アプリを直している @Gemmbu です。

ところで iPhoneX が出てもう一ヶ月経ちますがどうでしょうか? iPhoneX 対応進んでいますか?というわけで Lobi iOS アプリをいち早く iPhoneX 対応させたテクニックのお話をします。

この記事の対象者

  • iPhoneX にまだ対応できていないそこのあなた
  • それだけじゃなく iPhoneX に対応できているそこのあなたも

iPhoneX 対応って上下画面するだけでしょ?

って iOS アプリ開発者じゃないならそう思うかもしれませんが、残念なことにそうではないのです。まず iPhoneX 対応アプリを出すには Xcode のメジャーバージョンを上げなければなりません。で、 Xcode のメジャーバージョンを上げるとはどういうことかというとアプリが使用するライブラリのバージョンが一斉に上がるということになります。つまり iPhoneX 対応するってことは iPhoneX 対応のコードを追加すると同時に、既存の iPhone 端末および過去の iOS で正しく動作することも確認する必要があります。サーバで例えるなら Ruby のバージョンを上げたり、 Ruby on Rails のバージョンを上げたりっていうのをドキュメントはあるけどぎりぎりまでコミュニティなしでやらなければいけない感じです。

なので、 iPhoneX 対応(というか Xcode メジャーバージョンを上げること)はスケジュールが読みづらい作業であり、その間他の開発に取りかかれなくなるリスクのある作業となっています。そのため多くの現場では新機能対応と iPhoneX 対応の板挟みになっていることだと思います。

開発と iPhoneX 対応を両立するために Lobi チームではどうしたか

  • 既存開発メンバと iPhoneX 対応メンバに分けた
  • 既存開発メンバ用のブランチと iPhoneX 対応メンバ用のブランチを分けた
  • iPhoneX 対応メンバ用のプランチに適当なタイミングで既存開発メンバ用のブランチを都度マージした
  • 既存開発メンバは Xcode8.3.3 ( iPhoneX 未対応の最終版)で開発した
  • iPhoneX 対応メンバは Xcode9.x (そのときどきの最新版)で開発した
  • 既存開発メンバの書いたコードは iPhoneX 対応メンバが全てレビューをした
  • 既存開発メンバの書いたコードで iPhoneX 対応が必要なコードは Xcode9.x 環境ではビルドを失敗させるような修正をレビューで行った

この中の取り組みで面白いのはXcode9.x 環境ではビルドを失敗させるような修正です。どのようにすればよいのでしょうか?

どのようにしてビルドを失敗させる?

以下のコードは iOS11 では UIViewController の topLayoutGuide/bottomLayoutGuide は deprecated なので iOS11 から使える新しいレイアウト管理のための safaArea に書き換える必要があります。

self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);
self.tableView.scrollIndicatorInsets = self.tableView.contentInset;

まずはビルドを失敗させるように仕込みましょう。そのために #error directive を使用してコンパイル時にエラー発生させ、ビルドを失敗させます

#error topLayoutGuide/bottomLayoutGuide is deprecated in iOS11
self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);
self.tableView.scrollIndicatorInsets = self.tableView.contentInset;

これで、ビルド時に topLayoutGuide/bottomLayoutGuide is deprecated in iOS11 とメッセージを出して失敗します。ただこの場合だと、 Xcode のバージョンに関係なくビルドが失敗しますので次に Xcode のバージョンチェックを挟みましょう。

まず XCODE_VERSION_MINOR という丁度良い環境変数が定義されているので、それを使います。そのため Preprocesser MacrosHOGEHOGE_XCODE_VERSION_MINOR=0x$(XCODE_VERSION_MINOR) を追加します*1

Preprocesser Macros に定義することでどこでも使用することができるようになりましたので HOGEHOGE_XCODE_VERSION_MINOR を使用して Xcode のバージョンを確認するようにコードを修正しましょう。

#if defined(HOGEHOGE_XCODE_VERSION_MINOR) && 0x0900 <= HOGEHOGE_XCODE_VERSION_MINOR
#error topLayoutGuide/bottomLayoutGuide is deprecated in iOS11. use safeArea in iOS11 if need and remove this condition.
#endif
self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);
self.tableView.scrollIndicatorInsets = self.tableView.contentInset;

このコードを Xcode9.x 環境でビルドすると topLayoutGuide/bottomLayoutGuide is deprecated in iOS11. use safeArea in iOS11 if need and remove this condition. とエラーメッセージを吐きビルドが失敗します。つまり既存開発メンバは Xcode8.3.3 で開発しているためビルドは通るのですが、そのブランチを iPhoneX 対応のブランチにマージした際にビルドが失敗するようになるのです!!ビルドが失敗するのであとは iPhoneX 対応メンバが責任を持って修正し対応すれば良いことになります。

FAQ

Q. ビルド失敗させなくてもマージの際に修正すればいいのでは?

A. マージの規模が小さければ大丈夫かもしれませんが、大きい場合にはミスが発生する可能性が高くなります。コードの大部分は iPhoneX 対応のための追加の処理が必要ないのです。その箇所を生成されたマージコミットから漏れなく探すのが難しく、タイミングによっては複数の巨大な修正を一度に取り込む必要がありコントロールし辛いものであるため、その箇所をビルド失敗させることで漏れなく対応しました。

Q. ビルド失敗が発生するけど、直し方はどうやるの?

A. iPhoneX 対応メンバがレビュー時に Xcode9.x ビルドを失敗させる修正をさせたのと同時に対応方法も #error directive のメッセージで伝えたり必要であればコードに修正方法をコメントすることにした。そのためそれに従えばだれでもビルド失敗は治せる状態にしていました。

Q. 別にビルド失敗させなくても特定の識別子(例えば #TODO など)使えばいいのでは?

A. #TODO だらけのプロジェクトあったりしますよね...

Q. そもそもある一箇所でバージョンチェックするような修正で iPhoneX 対応できなくないですか?

A. そのためにあらかじめ Xcode8.x であるべき状態に WWDC 2017 のビデオ見て変更点を予想して対応しておきました。そうすることで Xcode9.x 対応は最小限ですみました。

Q. この手法って CI 環境とかで Xcode のバージョン追従漏れに気づいたりもできる?

A. はい。 iPhoneX 対応だけでなく Xcode のバージョンチェックに使うこともできます。詳しくは http://blog.dealforest.net/2014/11/プロジェクト毎に-xcode-のバージョンを指定/ を確認してください。

カヤックではエンジニアを大募集しています

カヤックでは普通の iOS エンジニアだけでなく、 WWDC のビデオを見るだけで次の iPhone を予想しそれに対応できるようなエスパーなエンジニアを募集しております。

明日は

アドベントカレンダー6日目を担当してくださるのは、きみーさんです。マットでマックスな人です。

*1:ちょっとしたハックなのですが XCODE_VERSION_MINOR は Xcode のバージョンで Xcode9.1 を使用した場合は 0910 という値となっています。そのため HOGEHOGE_XCODE_VERSION_MINOR=$(XCODE_VERSION_MINOR) と 0x を付与しない場合は 0 から始まる数値のため 8 進数と解釈され 8 進数で 9 はダメよと怒られてしまいます。そのため 0x を付与して 16 進数として扱うようにしています。

Qiitaで1000いいねを稼ごうとした人の末路

エンジニアのアウトプットの向上目的とした、1000いいねチャレンジを行いました。 Qiitaで1000いいねを獲得するのはなかなか難しく、個人的に試行錯誤したので参考になればと思い書きます。 また、SNS広告の検証の結果としても、こちらにまとめます。

f:id:okamuro:20171130201724p:plain

1000チャレンジとは

iPhoneX欲しすぎた私は

-> Qiitaで1000いいね達成するまでiPhoneXが買えないチャレンジ

という宣言を会社全体でしたため、1000いいねチャレンジが生まれました。

f:id:okamuro:20171203135232p:plain

いいねを稼ぐためにやってみたこと

狭い範囲の技術で投稿してみる

serverless frameworkでサーバーを構築するという記事を書いてみました

平均いいね数: 14
流入: 2,300
いいね率: 2.3%

範囲が狭いためか訪れたユーザーのいいね率は高いですが、流入が少ないためあまりいいねを稼げませんでした。 非常にしょっぱい。

タイトルで釣ってみる

〇〇してないなんてもったいない!などのあおり文句をつけて流入を増やそうとしました

平均いいね数: 51
流入: 11,225
いいね率: 0.9%

やはり流入がおおく、普段使っているようなツールに絞ることでいいねが誘発できました。

アイドルで釣ってみる

吉岡里穂さんの画像を使わせて貰い、いいねを稼ぐ

平均いいね数: 3
流入: 1,100
いいね率: 0.2%

これは非常に申し訳ない事態だと思っております。流入も少なければいいねもない。ファンに怒られそうです。

流行にのっかってみる

平均いいね: 28
流入: 12,798
いいね率: 0.2%

流行しているワードを使用すれば、いいね率は少ないですが流入が多かったのでいいねが稼げました。

記事の広告を出してみる

それぞれの記事に1万円分の広告をつけまして、流入を増やそうとしました。

平均いいね: 11
流入: 5,753
いいね率: 0.2%

記事に広告をつけたとしても、クリックはそれぞれ20程度。流入してもいいねは押さずに帰っていくのがほとんど。 結果、無駄にお金を払ってこの広告作戦は終了しました。 非常にお財布にも痛い結果となりました。

翻訳してみる

私の先輩の記事なのですが、とってもいいねがあります。 これに乗っかって、翻訳記事を書いてみました。

平均いいね: 248
流入: 10578
いいね率: 2.3%

流入がめちゃくちゃ多いし、いいね率も高かったです。

ランキングつけてみる

平均いいね: 15
流入: 1446
いいね率: 1.0%

はてぶからの流入

3はてブを獲得すると新着エントリーに、もっといくとホットエントリーにのる。

  • はてブの新着やホットエントリーに乗るとはてなユーザーからも流入があります
    • ある程度いい記事を書いて、ホットエントリーに乗りさえすれば、ブーストしていいねが増えそうです

Qiitaパワーをつかう

100いいねごとにQiitaからの流入が上がる 

  • Qiitaでは記事のいいねが100、200、300...ごとに公式twitterで流されます。そのときにも流入が増えるのでいいねが稼げそうです

その他共通してやったこと

画像よりgifをつける

  • 画像より動いている方がわかりやすいし、記事の最初にどうなるのか?を明確にすることで離脱を防ぐことができるようです。

これらの経験から得られたいいね獲得の秘策

①いいねが欲しかったら流入を増やせ

  • いいねしてくれる人は、だいたい数パーセントのようです。流入さえ増えれば記事の内容は関係なくいいねがもらえそうな感じです。やはり、釣りタイトルなどがいいのかもしれません。笑

②毎日コツコツすると上がる

  • ウィークリーランキングに載るようになると、記事全体を見に来てくれる人が多くなります。1回でどかーんを狙ってもいいですが、毎日コツコツ書くといいねがたくさん増える傾向にありそうです。

③みんなをまきこめ!

  • 毎日、コツコツ書くのは結構しんどいもの。思うようにいいねがつかない時もありなえぽよになりがちです。しかし、みんなが見てくれていると今日もかかなきゃなーっと思うので、みなさんも1000いいねチャレンジする際は、会社のslackなどで宣言して見ましょう

まとめ

  • 流入を増やす努力をする
  • いいねが欲しくて課金をしても無駄
  • 見てる(応援してくれている)側は、数字が毎日見えるので面白いし協力してくれやすいのでおすすめ!

面白法人カヤックではなんかわからんけど楽しく働きたい!という人を募集しております!

明日12/5は、ストリートファイターがめちゃくちゃ強いで有名な、カメーさんです!