ZOZOテクノロジーズのサマーインターンシップを公開!〜選考から実施内容まで〜

f:id:vasilyjp:20191003115750j:plain

こんにちは、ZOZOTOWN iOSチームの荒井です。今回は9月に実施したZOZOテクノロジーズのサマーインターンシップについて紹介したいと思います。インターンシップを開催予定の方、ZOZOテクノロジーズのインターンシップに興味がある方の参考になれば幸いです。

続きを読む

知ったらアプリ開発も楽になる! iOSDC Japan 2019で得たiOS開発の課題と向き合い方

こんにちは!
ZOZOTOWNやWEARのiOSアプリ開発をしている元と小野寺です。
先日、9/5から9/7まで3日間iOSDC Japan 2019が開催されました。今回ZOZOテクノロジーズでは12名のメンバーで参加し、弊社はスポンサーとして協賛しました。
この記事ではiOSDC Japan 2019にて発表されたセッションの一部を紹介すると共に、現場の盛り上がりの様子もお伝えします。

セッション

ライブラリのインポートとリンクの仕組み完全解説

最初に紹介するセッションは弊社の技術顧問をされている岸川さんのセッションです。

iOSDC Japan

内容はライブラリを使うときに遭遇するimportエラーやlinkエラーに対してシステマチックに解決するために必要な知識についてです。 ライブラリやフレームワークのimportエラーやlinkエラーを解決するとき、このセッションの内容は非常に役に立ちます。
応用編ではこのセッションで紹介された知識を活用できる方法がいくつか紹介されました。 その中でアプリの起動時間短縮に有効な方法があり、効果があるならZOZOTOWNアプリにも導入しようと思ったので実際検証してみました。着目したのはスライドの以下の部分です。

ダイナミックフレームワークが増えてくると起動時間に影響を与える(dyld2の場合) そのため各フレームワークをスタティックリンクにして1つの大きなダイナミックフレームワークにする

この方法はWWDC 2016のセッション「Optimizing App Startup Time」にてアップルが紹介した方法でもあります。

具体的にはダイナミックフレームワークはアプリ起動時にコストの高いリンク処理が発生するので各フレームワークをスタティックフレームワークとしてビルドし、その全てを1つのダイナミックフレームワークにまとめることでリンク処理のコストを抑える方法です。 dyld2に関しては現状サードパーティのフレームワークで使われてるので効果ありだと思いました。 実際に1つのダイナミックフレームワークにまとめてから今回のセッションで学んだ具体的な設定方法を使い、サンプルアプリで検証した結果を共有します。

■ 検証内容
「複数のダイナミックフレームワークをそれぞれスタティックリンクにしてから1つのダイナミックフレームワークにまとめる」ことで起動時間が短くなるかを確認
■ 検証対象アプリ
テンプレのプロジェクトを生成してからフレームワークを11個追加したアプリ(フレームワークの選定基準はありません)
■ importしたフレームワーク
AFNetworking, Alamofire, CocoaLumberjack, CocoaLumberjackSwift, RxBlocking, RxCocoa, RxRelay, RxSwift, SDWebImage, SDWebImageMapKit, SnapKit
■ 端末
iPhone 6s、iOS 12.3.1
■ 結果
赤い枠の中にある「Total pre-main time」が総計時間、「dylib loading time」がダイナミックフレームワークのロード時間です。両方とも短縮されているのでちゃんと起動時間が短縮されたのを確認できました。もし運用しているアプリの起動時間が長いのであれば試してみるといいかもしれません。

個人開発のアプリが輝くために
- アプリのDL数をあげる必殺技 -

弊社ZOZOテクノロジーズからLightning Talkで名取が登壇しました。

iOSDC Japan

発表内容は、自身が作成した個人開発のアプリ「大人のなぞなぞ〜脳トレIQ謎解きアプリ〜」を約100万ダウンロードまで成長させた戦略についての解説です。
これからアプリを実際に公開してみようと考えている方、既に公開している方どちら側であっても参考になる発表内容でした。

個人で開発したアプリでは、プロモーションにお金をかけることは、難しいですよね。
そんな個人開発のアプリを約100万ダウンロードされるまでに成長させた際に行った戦略の紹介です。発表の中で、ASO対策としてキーワード検索で上位に表示させる為の工夫が紹介されました。
ASO対策としては、次のようなポイントに気をつけると良いようです。

  • タイトルには、何のアプリなのかを表す為のキーワードを取り入れること
  • サブタイトルには、どんなアプリなのかを伝えるワードを取り入れること
  • キーワードには、ひらがなやカタカナ、漢字などを含める

セッション内では、カメラアプリを例にしてわかり易く説明されていました。
他にもアプリの評価を上げるために、高評価をしてくれそうなユーザーにレビューを依頼する取り組みについて紹介がありました。
高評価が期待できるユーザーの例として、次のような具体例が紹介されました。

  • アプリを10回以上訪問してくれたユーザー
  • あるコンバージョンを達成したユーザー
  • 一定期間、毎日アプリを起動したユーザー

実際に100万近くダウンロードされたアプリでの取り組みということもあり、とても説得力がありました。
今後アプリを公開する際により多くのユーザーに使ってもらう為には、どんな事に気をつけたら良いかの指標となる内容でした。
タイトルの記載内容やレビューへ促す条件を、紹介された内容や他のアプリとの比較をしてみることで、自身のアプリでの対策を見返す良い機会にもなりそうです。

FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた

テスト方針を決めるときは状況や環境を考慮する必要があるため、決まった対応パターンが存在しません。だからこそ他社の対応事例は「過去の対応方針を振り返るとき」や「これから決めるとき」参考になります。 このセッションではまさにそのテスト方針を決めるとき、何を考慮し、どう対応したかが事例として紹介されました。

「普段、テスト方針を決めるために自分がやっていることに問題はないか」、「他の人はどう決めてるか」はとても気になってたので自分の過去を振り返りながら、そして同じ状況なら自分はどうやるかを考えながら興味津々に発表内容を聞きました。
セッションで紹介された「再現可能なテストはないが安全に修正したい。だけどミスは許されない」状況で自分なら何を考慮するかを考えたときに思い浮かんだのは以下です。

  • 自動テストがあるか
  • サービス視点でテスト対象の重要度
  • 開発スケジュール的に使えるリソースはどれほどあるか(工数)
  • テストコードを書きやすい設計になっているか
  • テストしたいのは何か(ロジックか、表示か、挙動か)
  • 実装コスト
  • 実行コスト
  • テストの生存期間やメンテナンスコスト

セッションでも上記は考慮対象だったので大きくはズレてないと思い、少し安心しましたがUIテストを積極的に検討してる部分は印象的でした。今までUIテストは「手間がかかる」、「メンテコストがかかる」と単純に思い込んでいたのでもう一度UIテストに関して振り返ってみようと思います。他にはサービスの中の重要な価値について「認識を共有する」という項目も印象に残りました。確かにここをはっきりしておかないと暗黙的な基準で判断してしまうこともあるかもしれません。
このセッションはテストに関する自分のやり方を振り返るきっかけになったと思います。他社の事例を知ることは滅多にないのでテストに興味がある方は是非このセッションの資料を見ることをオススメします。

多言語対応と戦う 2019年版

こちらのセッションでは、多言語化が未対応のアプリでの対応の始め方から紹介されていました。
現在私が対応しているWEARアプリでは日本語や英語、繁体字、簡体字といった多言語の対応を行っていることもあり、このセッションを聞いてみることにしました。
WEARアプリでは文言もユーザーに伝わりやすいように、見やすいようにとデザイナーが試行錯誤して決めています。 実装の節目で私たちはデザインチェックを行うのですが、4つの言語の確認となりますとシステムの言語を都度切り替えて確認しなければならないという手間がありました。
そういった背景から私は、このセッションの中で紹介されたうちの1つ「アプリで言語を切り替えられるようにしよう」に興味を持ちました。
アプリの言語切り替えは、iOS 13以降からiOSの標準機能として盛り込まれる機能のようです。

Language selection per app

Use third‑party apps in a different language from your system language.

www.apple.com

こちらのセッションでは、これをiOS 12以前のバージョンで実現する方法が紹介されていました。

アプリ内で使用されている言語は、どこから取得されるのか?

UserDefault.standard.array(forKey: "AppleLanguages")にて[String]で定義されています。
ここで定義されている言語は、設定>一般>言語と地域の中で追加されてる言語です。 アプリ内では、UserDefault.standard.array(forKey: "AppleLanguages")から取得された配列の先頭の言語が使用されます。

どうやってアプリ内で言語を切り替えるのか?

例えば現在表示されている言語が、日本語の状態から英語に変える場合を考えます。
UserDefault.standard.array(forKey: "AppleLanguages")で取得される配列の順序を変更することで切り替えが可能なようです。
今回の場合、["ja-JP", "en"]を["en", "ja-JP"]と変更することで切り替えられます。
この他にも、設定アプリで追加されていない言語を追加する方法や、リセット方法なども含めてデモンストレーションを交えながら詳細に説明していただきました。

次に興味を持ったのは、「翻訳SaaSの導入で翻訳者にプルリクを出してもらおう」です。
この項目では、エンジニアでない方も翻訳変更に対するプルリクが発行できるような仕組みについて紹介されました。
ここではCrowdinというSaaSを例に説明されました。CrowdinとGitHubの連携時に、管理したいLocalizable.stringファイルを連携すると翻訳リストを管理するUI上で翻訳の変更が可能になります。
変更することで、プルリクが発行されるという仕組みになっているようです。
WEARアプリでは、英語と中国語の翻訳をそれぞれ別の方が担当して対応しています。私たちは、翻訳が必要な文言のやり取りをConfluenceやSlackを使ってやり取りして対応してきました。
現状の運用方法ですと翻訳依頼の取りこぼしや反映漏れなどが稀に発生していたこともあり、改善策を考えていました。そんな中で、今回のような具体的な運用例をあげての紹介はとても参考になるお話でした。
その他にも、翻訳ネームスペースを使った翻訳文言の管理方法や文字装飾のローカライズの方法などが紹介されていて、今後迷った時に参考になる発表内容でした。

会場の様子

思いやりが詰まったセッション会場

選出された登壇者によるセッションは、いくつかのテーマを同時進行でそれぞれの講義室で行われます。
セッション会場は、写真のように席がぎゅうぎゅうになることもあり、セッションに対する参加者の注目度の高さが伺えます。

iOSDC Japan

弊社の名取や技術顧問の岸川さんのセッションの際も、席は参加者で埋め尽くされてました。
運営の方々の1人でも多く参加者がセッションを聞けるようにという想いから「機械的席詰め」というシステムが度々施行されました。
これは、三人掛けの席で右側が空いていたら機械的に右に詰めるシステムという仕組みのものです。
会場の思いやりによって生まれた、この理想的なゾーンディフェンスのように美しいシステムに、私は感動を覚えました。
セッションは今後プロダクトに関わっていく上でどれも興味深く、勉強になりました。 各登壇者が発表の中にデモンストレーションを組み込んでいたり、笑いどころを入れるなどの工夫も見られ楽しく発表を聞くことができました。

活気にあふれたブース会場

iOSDC Japan 2019ではトークセッションの他にも、様々な企業が軒を連ねるブース会場があります。
セッションの合間や、お昼休憩などセッションのない時間帯は特に参加者の方々で会場はとても活気付いていました。

iOSDC Japan

この会場ではイベントのスポンサーとして協賛している企業がブースを出展して、参加者とのコミュニケーションを図っていました。
私たちZOZOテクノロジーズのブースを少し覗いてみましょう。

iOSDC Japan

今回ZOZOテクノロジーズでは、以下のテーマでアンケートを用意しました。

  • アプリのサポートiOS
  • アプリのSwift率
  • アプリの対応デバイス
  • アプリのレイアウト実装の割合

iOSDC Japan

参加者の方々のアンケートへの協力もあって、たくさんの方々と交流することができました。
実際にアプリを開発しているエンジニアや広報担当が参加者の皆さんの質問に答えるといった、お話もさせていただきました。参加者の皆さんと接する機会をいただけたことで、私たちもとても楽しい時間が過ごせました。
アンケート結果は、Twitterの公式アカウント上でハッシュタグ#iosdc #zozotechにて載せております。是非ご覧になってください。

1日目

2日目

食事は行列の先に

iOSDC Japan

午前中のセッションが終わると参加者の行列が。その先には、参加者分のお弁当とお茶の用意がありました。

iOSDC Japan

私が食べたのは、野菜を豚肉でぐるりと巻いた豚肉巻きとシャケの切り身に明太子のソースが絡み合ったおかずのお弁当。
副菜には、ゴーヤやゆで卵といった色とりどりの食材を使ったサラダが添えられており、セッションの合間の休憩時間を彩ってくれました。

After iOSDC Japan 2019について

9/24(火)弊社オフィスにてSansan様、JapanTaxi様、弊社ZOZOテクノロジーズの3社による合同イベント「After iOSDC Japan 2019」が行われます。 iOSDC Japan 2019を振り返りたい方や感じたことを共有したい方は是非お越しください! zozotech-inc.connpass.com

最後に

ZOZOテクノロジーズは、ファッションを技術の力で変えていくというミッション達成のため一緒に働く仲間を募集しています。気になる方は是非応募してください!
https://tech.zozo.com/recruit/mid-career/detail50/tech.zozo.com

WWDC19参加レポート - UI Design Labのフィードバック公開とAltConf登壇の様子をお伝えします!

f:id:vasilyjp:20190607165403j:plain

こんにちは!  開発部の名取と西山です。
今年のWWDCはSwiftUIをはじめ、Apple Developerの未来を変えそうなおもしろい発表が目白押しでした。

現地時間の2019/6/3-7にアメリカのカリフォルニア州サンノゼ、マッケンリーコンベンションセンターにて行われたWWDC19にZOZOテクノロジーズからは8名が参加してきました。
ZOZOテクノロジーズでは海外カンファレンスへの参加が推奨・サポートされており、多くのエンジニアが様々な海外カンファレンスへ参加しています。

本記事では、WWDC開催期間中の現地の様子とLabsでのフィードバック、AltConf登壇の様子などをお伝えします。

また、この期間は会場周辺でもいくつかのカンファレンスが開催されており弊社からは@banjunAltConfに登壇してきたのでその様子などもお伝えいたします!

WWDC?

WWDC(Worldwide Developer Conference)は、Appleが年に1回開催している開発者向けのカンファレンスです。 iOSやwatchOS、macOSの新バージョンなどをはじめ、開発環境周りの新機能などが発表されます。

多くの注目を集めるのは初日のキーノートですが、これは新OSや新機能の概要で、キーノート終了後に行われるPlatforms State of the Unionからがエンジニア向けのセッションとなります。

f:id:vasilyjp:20190607165548p:plain

WWDC期間中の雰囲気

キーノート前日

WWDC期間中は大変盛り上がり、まるでお祭りのようです。
私は今年初めて参加しましたが会場の雰囲気、スタッフ・参加者のテンションの高さなど日本ではなかなか味わえない空気感にただただ圧倒され、とても刺激を受けてきました。

私たちは土曜日の夕方に日本を出発し日曜日の昼頃サンノゼ空港到着、前日チェックインしてきました。チェックイン時は多くのスタッフにハイタッチで歓迎されます。

f:id:vasilyjp:20190607165638p:plain

ちなみに、今年のノベルティはジャケット(MA-1)とピンバッジでした。

f:id:vasilyjp:20190607165725p:plain

キーノート当日

初日のキーノートはみんな前方の良席で見ようと早朝から多くの人が並びます。
私は朝の4:00過ぎから並びましたがすでに100人以上の人が列に並んでいました。下の写真は早朝の3:00ですがすでに並んでいる人がいます。昨年はこの時間にはもっと多くの人が並んでいたようです。

f:id:vasilyjp:20190608093415p:plain

キーノートの開始時間は10:00ですが、スタッフが早朝から盛り上げてくれるため楽しみながら並んで待つことができます。

f:id:vasilyjp:20190608093244p:plain

キーノートの会場は超満員です。 ティムクックが登場すると会場は拍手喝采、大歓声に包まれます。

f:id:vasilyjp:20190607170230p:plain

会場で初めて見るキーノートはこれまでライブ配信で見てきたものとはまるっきり別物でした。

ライブ配信では決して味わうことのできない現場の興奮と熱狂、聴いてる人を惹きつける洗練されたプレゼンテーション、あの会場のワクワク感は開発者でなくとも一度体験するべきだと感じました。

今年のWWDCは、SwiftUI、iPadOS、ダークモードなど開発者にとって魅力的な発表が盛りだくさんでした。
Labsで聞いてきた話などブログでお伝えしたい内容もたくさんあるのですが、NDAの都合上ブログでの技術的な話は割愛させていただきます。

2日目以降

2日目からは技術的なセッションが始まります。それと同時にLabsもオープンします。
Labsではセッションの内容や気になったトピック、日頃の疑問などをAppleのエンジニア・デザイナーに直接相談できます。

f:id:vasilyjp:20190607170244p:plain

Appleのエンジニアやデザイナーと直接話をする機会はそう滅多にないため人気のLabsには長い行列ができます。

私はInterface Builder and Auto Layout Labに行ってAutoLayoutを用いたレイアウトの更新処理に関する質問をいくつかしてきました。
他にもApp Store Labでサービスを海外展開する上で注意すべきことや効果的な対応など日本ではなかなか手に入りにくい情報を得ることができました!

Labsの中でも、予約制で抽選に当選した人が参加できるUI Design Labは毎年大好評です。
今年からは、drop in(立ち寄り)形式での相談も1回10分まで受け付けていました。
私は最終日にようやく当選してAppleのデザイナーとディスカッションをしてきました。Appleのデザイナー2人から30分かけてアプリのフィードバックを貰えたのはとても貴重でした。

f:id:vasilyjp:20190608093511p:plain

このUI Design Labでは自分のアプリをAppleのデザイナーに触ってもらい、現状の優れている点や改善点がなどを細かくフィードバックしてもらえます。

UI Design Labは毎朝7:00〜7:30の間にWebから予約し、当選した人のみが参加できる特別なLabsです。
(世界最高峰のUI/UXデザインチームの方に開発中のアプリのフィードバックをもらうだけでWWDCのチケットの金額以上の価値があると思いました)

弊社のアプリ(ZOZOTOWN/WEAR)もたくさんのフィードバックもらってきたので、今回はその一部を公開します!

UI Design Lab × WEAR

モーダルを直感的に閉じられない

f:id:vasilyjp:20190607180949g:plain:w250

コーディネートを「セーブ」する際に表示されるモーダルが直感的に閉じられないという指摘です。

ユーザーが閉じる動作として「ゆっくり、大きくスライドさせる」「はやく、小さくスライドさせる」と例をあげられました。

WEARの場合「はやく、小さくスライドさせる」動作で閉じることができないので、こちらの対応をする必要があります。

投稿画像の明るさ調整

f:id:vasilyjp:20190607171232p:plain:w250

投稿画像の明るさを調整できる画面に関してです。 スライダーでの調整は、ユーザーにとって簡単では無いので、必要ないなら無くした方がいいとのことです。

明るさ調整を入れたい場合は、標準の「写真」アプリのようにビジュアルで結果がわかるような選択肢にした方がいいとアドバイスをいただきました。

f:id:vasilyjp:20190607171503p:plain:w250

ビジュアルの方は操作が少なく直感的なので、検討する余地があります。

タグ付けするフローの画面遷移が多い

もう1つ投稿フローから。

WEARにはクローゼット機能があり、アイテムをストックすることができます。 ストックから登録する際はワンタップでタグ付けすることができますが、直接アイテム情報を入力する場合は、 「カテゴリ」「カラー」「ブランド」が必須項目になるため、各項目を選ぶ度に画面遷移してしまいます。

f:id:vasilyjp:20190607171620j:plain:w500

ユーザーを迷わせないように、一画面で完結するようにした方がいいとアドバイスをいただきました。

ランキングのフィルターが簡単ではない

f:id:vasilyjp:20190607171645p:plain:w250 f:id:vasilyjp:20190607171725p:plain:w250

ランキング上部に「変更」ボタンがあり、こちらから性別の切り替えなどができます。 「変更」ボタンを選択し、性別を切り替えるのはユーザーにとって簡単ではないとのことです。

改善案としては、WEARの「見つける」画面上部にあるカテゴリ選択部分のようにした方が簡単になると提案を受けました。

f:id:vasilyjp:20190607171804p:plain:w250

いくつかフィードバックを紹介させていただきましたが、どれも根底にあるのは複雑性を排除し、直感的な操作を求めているように感じます。

UI Design Labのメリットととして、次のようなことがあると考えます。

  • なんとなくイケてないと思っている所をAppleのデザイン原則に基づき言語化してくれる
  • 限られた時間の中で指摘された所はユーザーインパクトが大きい
  • 良いと言われた所は自信につながる

Appleのデザイナーから「お墨付き」をもらえることにより、優先度をあげて対応しやすくなったり、良いと言われた所は自分たちの自信に繋がります。

驚いたことに、WEARに関しては特に質問を用意せずざっくりアプリを見てもらいましたが、限られた時間の中で的確で多くのフィードバックをいただけました。 そのプロフェッショナルな仕事ぶりに感動しました。

まだUI Design Labに行ったことがない方は、是非、次回以降のWWDCに参加し足を運んでみてはいかがでしょうか。

希望すれば通訳をつけていただけるので言語に不安がある場合も安心です!

AltConfに登壇!

WWDC開催期間中は、AltConfやtry! SwiftなどWWDC会場の周辺施設で他のカンファレンスも開催されます。

今年のAltConf 2019に弊社から@banjunがスピーカーとして登壇したのでその様子を簡単にお伝えします。

f:id:vasilyjp:20190607171838p:plain

AltConfの会場はWWDCに隣接するSan Jose Marriott Hotelの2階フロアです。

f:id:vasilyjp:20190608093955p:plain

スピーカールームは2つ用意されており、それぞれの部屋で同時進行します。
参加者はあらかじめスケジュールを確認し、聞きたい話を聞きにいく感じです。 この辺りの形式は日本で行われるカンファレンスと同様でスピーカートークはテンポよく行われます。

@banjunは「Auto Layout with an extended Visual Format Language」というタイトルで発表を行いました。

出典 : https://speakerdeck.com

Auto Layoutの制約を書くVisual Format Languageの文法を拡張するカスタムパーサーを実装して、Safe Areaへの対応をわずかなコードの変更だけで実現する手法の話をしました。

発表前は少し緊張している様子でしたが、当日の発表は非常に洗練さており多くの注目を集めるおもしろいものでした!
登壇が決まってからは技術顧問の岸川さんにご協力いただいて練習した他、弊社のエンジニアでピアレビューも行いました。

f:id:vasilyjp:20190607171931p:plain

まとめ

今年、WWDC初参加でしたがとても刺激的で学びの連続でした。

キーノートをはじめとする各セッションは勿論、Appleのエンジニアやデザイナーとのディスカッション、他のWWDC参加者の開発に対する熱量の高さなど非常に学びの多いカンファレンスとなりました。

また、iOS 13に関連する話やLabsで聞いてきた話などを詳しく聞きたい方は、6/12にZOZOテクノロジーズ青山オフィスにて開催予定のMeetUpにて弊社社員がLTを行いますのでぜひご参加ください!

カンファレンスに関係する交通費・宿泊費・チケット代などは全て会社に負担してもらいました。
自分から希望すれば国内・海外問わずカンファレンスに参加する機会やサポートをいただけて本当に感謝です!
ZOZOテクノロジーズでは、最新技術に対する感度が高く、ユーザー目線でプロダクトの開発をしたい人を募集しています。 興味のある方はこちらからご応募ください!

www.wantedly.com

おまけ

せっかくなので最後にサンノゼの街並みをパシャり。

サンノゼは非常に日差しが強く暑い反面、空気がカラッとしていてとても心地よい気候です。
街の至る所にBIRDと呼ばれるレンタル電動スクーターが設置されており、アプリさえあれば誰でも利用できます。

f:id:vasilyjp:20190607172004p:plain

非常に長閑な街並みで東京よりも時間の流れが遅く感じます。

f:id:vasilyjp:20190607172013p:plain

街を歩いてるとリスを見かけたりもします。

f:id:vasilyjp:20190607172021p:plain

サンノゼの街中には路面電車が走っておりローカルな街並みの雰囲気がでています。

f:id:vasilyjp:20190607172054p:plain

WWDC期間中は街並みがWWDC一色になります。
現地スタッフが至る所に立っていて積極的に話かけてくれます。

f:id:vasilyjp:20190607172102p:plain

ZOZOテクノロジーズの取り組みを大公開!try! Swift 2019 Tokyo 参加レポート

こんにちは、ZOZOTOWN事業部にてiOSエンジニアをしている名取です。

2019/3/21-22にベルサール渋谷ファーストで行われたSwift言語の技術カンファレンスtry! Swift 2019 Tokyoに参加してきました。 ZOZOテクノロジーズからはほぼ全員のiOSエンジニアが参加したほか、プラチナスポンサーとして企業ブースの運営も行いました!

本イベントに向けてZOZOテクノロジーズとしてもメンバー1人1人がたくさんのtry!(挑戦)をしてきましたのでその様子と話題のファッションチェックアプリの評判や当日の興味深かったセッション内容などについてお伝えいたします。

try! Swiftについて

try! SwiftはSwift言語での開発における最新の応用事例について集まる国際コミュニティです。 try! Swift 2019 Tokyoは32カ国から900人の参加者が集まる大規模なカンファレンスとなりました。

発表内容はSwift言語やiOSアプリ開発を中心にmac OS、Server Side Swift、3Dレンダリングの話など多岐にわたりAppleのエンジニアも数名が登壇されました。

Appleにとってもtry! Swiftが重要なイベントであることが伺えます。

ZOZOテクノロジーズとしてのtry!

私たちはアプリ開発が大好きです!
Swiftでプロダクトコードを書くのが楽しく、日々の技術の進化にメンバーみんながワクワクしています。
そんな私たちだからこそ、try! Swift 2019 Tokyoに参加するにあたって2つのtry!をしました。

CfPを出す

私たちZOZOテクノロジーズでは業務の一環としてプロダクトチームを跨いでiOSエンジニアが集まり、CfPのアイデア出しや議論から始めました。 一度書いたことがある方なら分かると思いますがCfPには大変な労力と技術的な知識・経験が必要となります。社内のiOSエンジニアで何度も議論を重ね、お互いに意見し合いながら1人1人が納得のいくCfPをつくりあげ提出しました。 その結果、ZOZOテクノロジーズからはMichael Petrieが見事スピーカーに選ばれ発表を行いました!

Michael Petrieのスピーカー発表が決まってからも社内のiOSエンジニアで積極的にピアレビューを行い、活発に議論を重ねながら発表内容のブラッシュアップに貢献しました。
私はZOZOテクノロジーズに入社してまだ数ヶ月ほどしか経ちませんが、チームとしての協力体制がとても素晴らしくチーム開発が好きな人にはこれ以上ない環境だと感じています。

ファッションチェックアプリの作成

スポンサー企業として何ができるかを考えた時に、私たちらしさとは何かを考えました。私たちに共通しているのはアプリ開発が好きでファッション産業が好きということです。
そんな私たちだからこそアプリを開発して来場者に楽しんでもらうのが面白いのではないかと考え「ファッションチェックアプリ」の開発を行いました。
ファッションチェックアプリの詳細はこちら

ファッションチェックアプリは元々DroidKaigiの企業ブースのためにKotlinとFlutterで作られたものでしたが、try! Swift 2019 Tokyoのために弊社の2人のiOSエンジニア【伴(@banjun)と西山】が協力してiOS対応をしました。

try! Swiftは国際的なカンファレンスであることからローカライズも行いました。ローカライズはFlutter側で実装することで、ブースでデモをしているときもアプリ上ですぐに言語切り替えができるようになりました。このようにしてiOS対応コードを入れつつもFlutterの利点も活かしたアプリになっています。

try! Swift 2019 Tokyo当日の雰囲気

会場はとても広く、世界中のSwiftデベロッパー900人が一堂に会しました。
try! Swiftは国際的なカンファレンスということもあり開催場所が日本であるにも関わらず多くの海外デベロッパーが参加しました。

メインのセッション会場とは別にスポンサーブースも設けられました。
当日のZOZOテクノロジーズのブースはこんな感じです!

ブースではファッションチェックアプリの展示をはじめ、ZOZOテクノロジーズのiOSエンジニアが参加者の質問に答えたり技術的なこと会社のことなどについてお話をさせていただきました。

ファッションチェックアプリは非常に多くの方々に利用していただき、たくさんのシェアがあったのにはとても驚きました。 どうやって作っているのか、リリースの予定はあるのかなど多くのご意見をいただき参加者の方々との良い交流のきっかけにもなりました。 ブースの運営側としても非常に学びのあるとても楽しい時間となりました!

SESSIONS

全32セッションの中から特に気になったセッションについて個人の感想などを踏まえながらいくつかご紹介いたします。

Keypath入門

@Benedikt Terhechte

出典 : https://speakerdeck.com

key pathを使う最大のメリットはプロトコルだけでは実現できない型の抽象化を行うことだと思いました。 言い換えれば、リーダブルなコードの記述ができるとも言えるかと思います。

以下のような型の異なる複数の要素を持つstructがあったとします。

この時にSettingsEntryというkey pathを要素に持つstructを以下のように用意したとします。

すると、SettingsEntryという1つの型のみでsetttingの管理を行うことができるようになり抽象化できるというお話でした。

セッションの後半では岸川克己さんkey pathを使ったライブラリが紹介されており、key pathのユースケースは意外と多い印象を受けました。

プロダクトコードを書く上で汎用化/抽象化を行うことは私たち開発者が常に意識すべきことの1つです。 key pathはそのための1つの選択肢になると思い興味を持ちました。

PixarのようなグラフィックをSwiftで実現する

@Michael Petrie

出典 : https://speakerdeck.com

弊社ZOZOテクノロジーズのMichael Petrieの発表です。

Swift実装のレイトレーシングを使って3Dレンダリングされた1本のショートムービーからこのセッションは始まりました。

Swiftでレイトレーシングの実装ができること、それもMetalなどのフレームワークが使われていないことに驚いた方も多いのではないでしょうか。まさに自分もその一人です。
サンプルコードを眺めているとimportされているのはFoundationのみであることに気づきます。
私たちが普段アプリ開発をする際は多くのライブラリやフレームワークをプロジェクトに取り入れその恩恵にあずかっています。しかしながら、Swift言語を深く知ることでレイトレーシングというPixarで使われている技術が自前実装で実現可能ということを知りとても刺激を受けました。

私たちiOSエンジニアが当たり前のように使っているSwiftでこんなことができるのかと学習意欲を掻き立てる素晴らしい発表内容でした。

Michael Petrieの発表はTwitterで話題になっていたほか、公開されたサンプルコードは翌日のGitHubのトレンド入りするなど、5分という短い時間の中で大変注目を集めていました!

以下、発表を終えたMichael Petrieのコメントです。

Understanding a concept, and being able to articulate it in a way that is easy to understand are two entirely different things. Presenting at try! Swift was an opportunity to practice the latter, one for which I’m very grateful.

Presenting on stage has highlighted the importance of being able to clearly explain what I know and have learnt. Through whatever means available, I think this is something every programmer should aim to do.

ポートレートモードを自作しよう

@Rina Kotake

出典 : https://speakerdeck.com

Swiftを使って2次元画像の背景をぼかすという発想がそもそも自分の中になく、アウトプットとしてのクオリティも大変素晴らしかったことからとても興味深いセッションでした。

深度情報を持たない画像に対してセグメンテーションを行う場合は機械学習を利用するしかないと思っていましたが「GrabCut」という手法を用いることで綺麗に画像の前景抽出を行うことができることを初めて知りました。

2D画像は深度情報を持たないから背景をぼかすことはできないではなく、成し遂げたい課題に向かってtry!した発表内容は本イベントに相応しいものだと感じました。

魔法の法則

@Dave DeLong

Ex-Apple iOS EngineerのDave DeLongさんの発表です。
彼の好きなSF小説作家ブランドン・サンダースンさんが掲げる3つの法則を魔法の法則と題し、どうしたら素晴らしいユーザー体験が実現できるかを発表されました。

とても印象的な内容だったので以下に3つの魔法とその解釈を記載いたします。 この3つの魔法の法則に従って行動すれば自ずと素晴らしいものになるとまとめられました。

【1】作者が魔法で満足のいくように葛藤を解決する能力は、読者がその魔法をどれだけよく理解しているかに正比例します。

これを普段私たちが開発するサービスやプロダクトに置き換えて考えると次のように言えると思います。 ある問題を解決するために新しい機能や改善を行ったとき、ユーザーが真に幸せになるためにはユーザーがそのことを正しく理解できていないといけない。すなわち、私たち開発者はユーザーがどんなことを行いたいのか、どんな問題を抱えているのかを適切に理解・想定しその最適解をサービスに組み込んでいく必要がありそのガイドを示すべきだと。

【2】制限は権力より重要

Dave DeLongさんは「できないことはできることよりも面白いことが多い」と述べられていました。 アプリの開発をするにあたっては多くの制限に直面します。時間、人数、能力、、、 私たち開発者は多くの制限がある中でどんな未来を実現すべきかを考え、常に最良の選択をする必要があります。 ただこうした多くの制限の中でこそ創造性が発揮され、時には思いも寄らない素晴らしい未来が実現するんだと述べられていました。

【3】新しいものを追加する前に、すでに持っているものを拡張してください

何か全く新しいものを追加することだけがユーザーを喜ばせるわけではなく、ある1つの機能に関して常に奥行きを加えることで、確実にユーザーを喜ばせることができる。 つまり、一見単純に見えるものが実は非常に奥深く複雑性がありニュアンスの多いものだということを発見した時にとてもワクワクするのだとDave DeLongさんは述べられていました。

サービスの開発者なら誰しもがユーザーを魅了する素晴らしいものを作りたいという気持ちがあるかと思います。
どうしたらユーザー体験が向上するのか。どうしたらユーザーは満足するのか。
絶対的な答えがない中で私たち開発者は常に試行錯誤しベストを尽くしています。
本セッションではそのような開発者への行動指針が提示されたように感じ深く共感するものでした。

おわりに

try! Swift 2019 Tokyoに参加して改めてSwiftでできることが年々増えているように感じました。
セッションではServer Side Swiftの話を始め、ハードウェアハッキングやレイトレーシングの話などiOSアプリ開発の枠を超えた発表が多い印象を受けました。
また、OSSとしてコードを公開したりデモアプリを作ったりといった発表も多く発表から自身のアウトプットに持っていくスピーチはどれも洗練されたものでした。
たくさんの刺激や学びを得ると共に、来年こそはあの場所で発表したいと強く思いました!

www.wantedly.com

カスタムコンポーネントを使用したUI実装について

こんにちは。iOS担当の遠藤です。
最近、私達のチームではUI実装をカスタムコンポーネントを使用して行うようにしました。今回はそのメリットと実装方法について紹介したいと思います。

はじめに

今までのUI実装では、カスタムビューごとにInterface Builderでテキストの色や、サイズを設定していました。
しかしこのやり方には、以下の問題がありました。

  • 間違った色やサイズを設定してしまう恐れがある
  • xibを作成するたびに色やサイズなどを設定するのは面倒
  • UIを変更する際に、変更範囲が広くなってしまう

UI実装をする度にInterface Builderでテキストやボタンの色や数値を設定すると、間違った設定をしてしまう恐れがあります。そして、毎回この設定をInterface Builderで設定するのは面倒です。
また、変更箇所が多くなってしまうことも問題でした。 アプリを開発、運用する中で一番変化が多いのはUIです。テキストやボタンの色、テキストサイズやフォントなどを変更したいという要望は少なからずあると思います。
Xcode 9からはColor Literalが使用できるようになり、色の変更はとても簡単になりましたが、テキストサイズやフォントの変更は一括ではできません。
テキストサイズやフォントを変えるのに多くのxibを変更する必要が出てきます。すべてのxibを変更し、漏れがないかを確認するのは非常に大変です。

これらの問題を解決するために、カスタムコンポーネントを使用して実装することにしました。UIを実装する際の参考になれば幸いです。

カスタムコンポーネントとは?

プロダクトで使用するテキストやボタンのデザインを定義したクラスをここではカスタムコンポーネントと呼んでいます。

f:id:vasilyjp:20190313150519p:plain

UILabelやUIButtonを継承して実装し、xibでデザインを構成するのにこのコンポーネントを使用します。

f:id:vasilyjp:20190313151327p:plain

カスタムコンポーネントを使用すると
どう変わるか?

カスタムコンポーネントにデザインの定義をしているので、xibにカスタムコンポーネントを配置するだけでUI実装が済みます。 このことではじめに挙げた問題は以下のように解決されました。

😣 間違った色やサイズを設定してしまう恐れがある
✅ 毎回Interface Builderでデザインの設定を行わないのでデザインの設定ミスが無くなります。

😣 xibを作成する度に色やサイズなどを設定するのは面倒
✅ xibではカスタムコンポーネントを配置するだけなので、デザインの設定を行うのはカスタムコンポーネントを実装する際の一度だけになります。

😣 デザインを変更する際に、変更範囲が広くなってしまう
✅ カスタムコンポーネントのみを変更するだけで済みます。

はじめに挙げた問題が全て解決されました。カスタムコンポーネントを使用することでUIの実装が楽になり、変更にも強くなります。

実装について

カスタムコンポーネントの実装について説明します。

カスタムコンポーネントを実装する上での制約

カスタムコンポーネントを実装する上で、2つの条件と1つの要望がありました。

条件

1. カスタムコンポーネントを使用する際に、Interface Builderでデザインが確認できること

カスタムコンポーネントを使用することで、Interface Builderでデザインの確認ができなくなってしまうとあまり使い勝手はよくありません。
デザインを実装する上でも、運用をする上でもInterface Builderでデザインを確認できたほうがやりやすいです。

👍 👎
f:id:vasilyjp:20190313151722p:plain f:id:vasilyjp:20190313151736p:plain

2. 型を保つこと

コンポーネントをカスタマイズしたことで、UILabelUIButtonの型ではなくUIViewなど別の型になってしまうと扱いづらくなってしまいます。 特に困るのが、xibにカスタムコンポーネントを配置した際に型が保てないと、Attributes Inspectorで要素の設定ができなくなってしまうことです。

👍 👎
f:id:vasilyjp:20190313151808p:plain f:id:vasilyjp:20190313151840p:plain

要望

カスタムコンポーネント単体でのデザインを、Interface Builderで確認できること

Interface Builderでカスタムコンポーネント単体のデザインを確認できないことで大きな支障はありません。 しかし、Interface Builderでカスタムコンポーネントのデザインを確認できることは便利なので、できるようにしたいです。

カスタムコンポーネントの実装

上記で挙げた3つの課題を満たすようにカスタムコンポーネントを実装します。

Intarface Builderでデザインの表示

カスタムコンポーネントのデザインをInterface Builderで表示したいので、まず、カスタムコンポーネントのクラスに@IBDesignableを設定します。 @IBDesignableを書くことで、Interface Builderを表示するときにビルドがはしり、デザインが反映されるようになります。

@IBDesignableを書いただけでは、Interface Builderにデザインの反映はされないので、prepareForInterfaceBuilder()メソッドを書きます。 prepareForInterfaceBuilder()はInterface Builderでビルドされるときのみ呼ばれ、そのメソッドで書かれた内容がIntarface Builderに反映されます。 Interface Builderを表示するときにビルドされるのなら、その時呼ばれる初期化メソッドのinit(frame:)にデザインの設定処理を書けば済むように思われます。 しかし、init(frame:)にデザインの設定を書いてもInterface Builderには表示されません。 なぜなら、初期化が終わった後に、Interface Builderで設定されている値で上書きしてしまうからです。

// CustomButton.swift

@IBDesignable
class CustomButton: UIButton {

  override func prepareForInterfaceBuilder() {
      super.prepareForInterfaceBuilder()
  }
}

デザインの設定

次に、デザインの設定です。
デザインの設定はInterface Builderを使用せずに、コードで設定をします。

Interface Builderでデザインを設定したカスタムコンポーネントを使用するには、xibを読み込む必要があります。
カスタムビューを使用するときのように、UINibを使用してxibを読み込んだ実装をしてみました。

// CustomButton.swift

@IBDesignable
class CustomButton: UIButton {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        loadNib()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()

        loadNib()
    }

    func loadNib() {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        let button = nib.instantiate(withOwner: self, options: nil).first as! UIButton
        button.frame = bounds
        addSubview(button)
    }
}

しかし、この実装では意図したように表示されません。UIButtonの上にxibから生成したボタンを貼り付けているため、このように二重に表示されます。

f:id:vasilyjp:20190313152044p:plain

これを避けるにはUIButtonを継承せずに、UIViewで実装をすると解決します。
しかし意図したように表示できたとしても、型がUIViewになってしまうためこのやり方はできません。

なのでxibではなく、デザインの設定をコードで行います。

// CustomButton.swift

@IBDesignable
class CustomButton: UIButton {

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupAttributes()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setupAttributes()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()

        setupAttributes()
    }

    private func setupAttributes() {
        layer.cornerRadius = 4.0
        backgroundColor = UIColor(red: 0x33 / 0xFF, green: 0x33 / 0xFF, blue: 0x33 / 0xFF, alpha: 1.0)
        setTitleColor(.white, for: .normal)
        titleLabel?.font = UIFont.boldSystemFont(ofSize: 14.0)
    }
}

デザインを設定している実装がsetupAttributes()です。
このメソッドを、init(coder:)init(frame:),prepareForInterfaceBuilder()で呼び出します。

xibを読み込んで生成される場合はinit(coder:)が呼ばれ、コードから生成する場合はinit(frame:)が呼ばれるのでどちらにもsetupAttributes()を書いています。

Interface Builderでも表示するために、prepareForInterfaceBuilder()でも書いているのでInterface BuilderでビルドされるときはsetupAttributes()が2回呼ばれてしまいます。 2回呼ばれてしまいますが、Interface Builderでのビルド時のみということと、書かれる処理が色やサイズの設定で複数回呼ばれても結果が変わらないため、私達は問題にはならないという判断をしました。

カスタムコンポーネントのデザインをIntarface Builderで表示する

カスタムコンポーネントのデザインをコードで実装すると、デザイン通りに実装できているのかぱっと見てわからないです。 そして、カスタムコンポーネント単体をxibで確認できるようにしたいという要望がまだ解決できていません。
ですが、@IBDesignableprepareForInterfaceBuilder()を設定しているので、カスタムコンポーネント単体をInterface Builderで確認できるようにすることもできるはずです。 そこで私達は、CustomButton.xibというプレビュー用のxibを用意することで解決しました。 xibをAssistant Editorで表示しながらコードを書くことでカスタムコンポーネントのデザインを確認しながら実装できます。

f:id:vasilyjp:20190313152236g:plain


このプレビュー用のxibはアプリにバンドルする必要がないので、Target MemberShipのチェックを外しています。

f:id:vasilyjp:20190327182846p:plain

これで全ての条件、要望が解決されました。

あとはこのカスタムコンポーネントをxibに配置すると、Intarface Builderで色やフォントを設定しなくても実装できるようになります。

f:id:vasilyjp:20190313152339p:plain

まとめ

今回はカスタムコンポーネントを使用したUIの実装について紹介しました。

アプリ開発において、UIを実装することは多く、実装の度に何回も同じ設定をするのは面倒です。また、単純な作業なため気をつけていたとしてもミスが起きてしまいます。カスタムコンポーネントを使用することで、毎回の煩わしい作業とミスをなくすことができました。デザインを変更するときも、カスタムコンポーネントのみの対応で済みます。変更範囲が狭いので対応漏れの不安がなくなります。
変更に強くミスのないUI実装になるので、カスタムコンポーネントを導入することをおすすめします。ぜひ、試してみてください。

弊社ではUI実装の仕組み化にも積極的に取り組んでいます。少しでも興味がある方は、ぜひ一度オフィスにお越しください。 下記からのエントリーもお待ちしています。

www.wantedly.com

FlutterとFirebase ML Kitを使ってカンファレンス用デモアプリを作った話

DroidKaigiで展示したファッションチェックアプリについて

こんにちは。ZOZOテクノロジーズ開発部山田(@yshogo87)です。 DroidKaigi 2019ではプラチナスポンサーとして、ブースを出展させていただきました。

DroidKaigi 2019

f:id:vasilyjp:20190307173118j:plain

そのコンテンツとしてファッションチェックアプリを展示させていただきました。

f:id:vasilyjp:20190307173352j:plain

f:id:vasilyjp:20190307173443j:plain

今回はファッションチェックアプリがどのような仕組みになっているかを説明させていただきます。

続きを読む

iOSで構築しているCIのWorkflow紹介

こんにちは。iOS担当の荒井です。 今回はiOSチームで構築しているCI/CDのWorkflowについて紹介します。

CI/CD環境

はじめに、ZOZOテクノロジーズのiOSチームがどのようなCI/CD環境を整えているかを簡単に説明します。ZOZOテクノロジーズではZOZOTOWNやWEAR、プライベートブランドZOZOなど様々なサービスを運営しています。プロダクトによりCI/CD環境は違うのですが、多くのプロダクトでBitrise + DeployGateという構成をとっています。今回お話するWorkflowもBitriseを例に紹介していきます。

Bitrise

多くのCIサービスが存在していますが、以下の理由でBitriseを選定しています。

  • 導入時、利用目的に対して価格面が見合っていた
  • Xcodeバージョンアップへの対応速度
  • 日本市場に注力

日本市場に注力していくという話もあり、今後サポートに期待が持てます。 最近では日本語の記事も掲載されています。

DeployGate

TestFlightやFabricを使っている方も多いと思いますが、弊社のiOSチームはDeployGateを選択しています。元々CI/CDの環境が整っていないプロダクトが多かったため、環境構築を進めるにあたり、会社としてAndroidチームで運用実績があるDeployGateにしました。プロダクトをまたいでテストを行うチームが存在するため、ツールは統一しようといった理由があります。

Workflow

それではWorkflowの話に移ります。 WorkflowはStepと呼ばれる定義済みスクリプトをまとめたものです。例えば「Carthageコマンドを実行する」には「Carthage」というStepを設定します。BitriseではGUIで簡単にSetpを追加し目的に応じたWorkflowを組むことができます。今回は以下のようなフローを例に、自動化する際どのようなWorkflowを組んでいるかを紹介します。

  1. エンジニアがGitHubにコードをPush
  2. GitHubへのPushをWebhook
  3. Workflowの実行
  4. DeployGateへのアップロード
  5. Slackへ完了通知

よくある「エンジニアがコードを書いてGitHubにPushしたら、テストが実行され、アーカイブしてQAに配布する。終わったらSlackに通知する」というものです。実運用ではPushのたびに配布をしていたら頻度が高いため、PullRequestの生成タイミングなど、目的に応じてトリガーを設定しています。

上記のようなフローを構築する場合、Bitrise上で以下のようなWorkflowが考えられます。

  1. SSH keyの登録
  2. リポジトリのクローン
  3. ビルドキャッシュのダウンロード
  4. 証明書のインストール
  5. Carthageコマンドの実行
  6. キャッシュの更新
  7. スクリプトの実行
  8. テストの実行
  9. アーカイブ
  10. DeployGateへのアップロード
  11. Slack通知

しかし弊社ではこれらのStepのほとんどをfastlaneに任せています。

fastlane

fastlaneはアプリの様々な作業を簡単に解決してくれるツールです。冒頭のフローを実装するのに必要となる「ビルドに必要な証明書類の管理」「DeployGateへのアップロード」などはすべてfastlaneで行なっています。fastlaneを使用すると以下のようなWorkflowになります。

  1. SSH keyの登録
  2. リポジトリのクローン
  3. ビルドキャッシュのダウンロード
  4. Carthageコマンドの実行
  5. キャッシュの更新
  6. スクリプトの実行
  7. fastlaneの実行

fastlane以外のStepスクリプトを使用しない理由は、CIサービスの移行を容易にするためです。他のCIサービスに魅力的な機能が出たり、何かしらの理由でCIサービスを変更しなくてはいけない場合でもfastlaneに処理を寄せておけば移行がスムーズになります。Bitrise上ではCode Signingの設定もせず、出来ることは可能な限りfastlaneにしています。サンプルのフローを例にSlackへ通知するまでのfastlaneの実装を紹介します。

証明書のインストール

iOSに関わる証明書などのファイルは暗号化されGitHubで管理しています。fastlaneではアクションという形で様々な機能が提供されており、証明書の管理はfastlaneのmatchというアクションを使って実装しています。今回は詳しく触れませんが、証明書の管理はGitHubにしておくと何かと便利です。まだすべてのプロダクトで使用しているわけではないので現在対応を進めています。

テスト

テストにはscanというアクションを使用します。 fastlaneの処理はFastfileという設定ファイルに記述して実装していきます。

lane :test do
  scan(scheme: "SCHEME-NAME", clean: true, skip_slack: false)
end

FastfileはRubyで記述していくことになりますが、ドキュメントも充実しており、Rubyに馴染みのないiOSエンジニアでも記述に困らないと思います。Swiftでの記述もサポートがあるため、こちらを試しても良いかもしれません。

アーカイブ

アプリケーションのビルドサンプルです。ビルドにはgymというアクションを使用しています。

private_lane :build do
  match # 証明書のダウンロード
    gym(scheme: "SCHEME-NAME",
      configuration: "InHouse",
      clean: true,
      export_method: "enterprise"
    )
end

DeployGateへのアップロード

DeployGateへのアップロードもfastlaneです。私たちはDeployGateを使用していますが、TestflightやFabricなどのアクションも揃っています。

private_lane :deploy_gate do | options |
  target = options[:release] ? "release" : "development"
  deploygate(
    api_token: ENV["DEPLOYGATE_API_TOKEN"],
    user: "DEPLOYGATE-USER",
    ipa: "./#{target}.ipa",
    message: last_git_commit[:message]
  )
end

Slack通知

全員が業務でSlackを使用しているため、何かの処理が終わった場合にはSlackで通知するように組んでいます。プロダクトに影響しない処理はサービス間で同じ設定を使うこともあります。 手元のテストでSlack通知が行われないように、CI上のみで通知をすることが多いです。

before_all do
  ENV["SLACK_URL"] = "WEBHOOKURL"
end

after_all do | lane |
  if is_ci?
     slack(message: "Test Successfully")
  end
end

error do | lane, exception |
  if is_ci?
    slack(
      message: exception.message,
      success: false
    )
  end
end

Bitriseに設定するlane

Bitriseに設定するlaneを作成します。

lane :deliver_qa do
  build
  deploy_gate(release: false)
end

今回はビルドとデプロイのみにしていますが、 他にもビルドバージョンやGitタグなどもfastlaneで自動化できます。

fastlane運用をしてみての利点

すでにCircleCIからBitriseに移行したサービスがありますが、基本的にfastlaneで書いてあったため移行はとてもスムーズでした。CI上の細かな設定を確認せずとも、fastlaneの設定ファイルであるFastfileを確認すれば処理の流れが把握出来るのも利点だと思います。また、fastlaneによるコードでの記述を行なっていれば、プロダクトをまたいで設定ファイルを簡単に共有できるメリットもあります。CI上でGUIによるWorkflow構築は簡単ですが、コードで記述していくメリットも十分あるように感じています。

まとめ

今回はiOSチームで構築しているWorkflowについて紹介しました。CI/CD環境は随時改善を進めており、どのチームも自動化を目指しています。まだまだ改善の余地があり今後も注力していきたいと思います。CI/CDに興味があり、自動化が好きな方下記よりご応募お待ちしております。

www.wantedly.com

iOSアプリの多言語対応について

f:id:vasilyjp:20180927112725j:plain

こんにちは。新事業創造部の荒井です。 今回はiOSアプリの多言語対応について紹介します。

はじめに

私は今までいくつかのiOSアプリを運営してきましたが、どのアプリも日本語のみのサポートでした。現在関わっているWEARでは、すでに多言語対応が進められており、良い機会ですので個人的に知見がなかった多言語対応について調査をしました。今回は基本となる文字列の翻訳について触れていきたいと思います。

続きを読む

iOSアプリの継続課金コンテンツに無料トライアル機能を導入する方法

f:id:vasilyjp:20180927112702j:plain

こんにちは!
最近暑いのでビール最高と感じている新事業創造部バックエンドエンジニアのりほやんです。
今回はAppleが提供しているお試し価格の機能のひとつである無料トライアル機能を紹介します。

お試し価格とは

お試し価格とは自動更新の定期購読に対して割引価格を設定したり、定期購読の開始時に一定の無料トライアル期間を設けることができる機能です。
お試し価格には都度払い、前払い、無料トライアルの3種類があります。

お試し価格はユーザーにとって、有料会員の体験ができるとても便利な機能です。
しかし公式ドキュメント以外の資料が少なく実装に何点か困ったことがありました。
そこで今回はお試し価格の無料トライアル機能を導入する方法についてご紹介します。
この記事が無料トライアルを導入しようか悩んでいる方、実際に無料トライアルを導入する方のお役に立てば幸いです。

続きを読む

CarthageでビルドしたフレームワークをGitにコミットせずに良さげに扱う

f:id:vasilyjp:20180927112700j:plain

iOSチームの@hiragramです。

所属するプロジェクトでは依存管理にCarthageを使っていますが、Carthageの成果物である Carthage/ 以下をコミットするかどうかはよく議論になる話題かと思います。 私はコミットしない派なので、そのメリットを残しつつデメリットをなくすためにやってみたことを紹介します。

続きを読む

大規模リファクタリングで痛感したSwiftのOptionalとの正しい付き合い方

f:id:vasilyjp:20180927112657j:plain

iOSアプリチームの@hiragramです。

最近、ファーストリリース時からあった画面の大規模なリファクタリングを担当しました。 コードは遅かれ早かれ賞味期限が切れて少しずつ腐っていくものですが、その賞味期限を少しでも伸ばすために、普段コードを書く時にSwiftのOptionalについて意識していることを記事にします。

f:id:vasilyjp:20180202153329j:plain

「とりあえずOptional」をやめる

SwiftのOptionalは便利ですが、「Optionalを使えば、nilを安全に扱えて良い」と捉えてしまうと、気づくとモデルのプロパティがOptionalだらけになっていて使う側で毎回アンラップをしなくてはいけないような状況に必ずなります。

続きを読む

大事故防止!iOSの自動更新購読型と消耗型の課金を共存させるときのサーバーサイドTipsまとめ

f:id:vasilyjp:20180927090637j:plain

課金とPush通知攻略に邁進中のじょーです。 今回は、ひとつのアプリに自動更新購読型と消耗型を共存させたときのサーバーサイドで行うレシート検証のTipsを紹介します。

自動更新購読型課金のサーバーサイド実装について

自動更新購読型課金単体で実装する場合はこちらの記事が参考になります。 (昔書いた記事で古い情報がある場合があります) 下記の記事では月額課金と呼んでいますが、自動更新購読と同義です。

tech.vasily.jp

消耗型課金のサーバーサイド実装について

消耗型課金単体で実装する場合はこちらの記事が参考になります。 tech.vasily.jp

続きを読む
カテゴリー