wootan's diary

iOSアプリ開発を中心としたエンジニアブログ

Relux施設詳細画面のリニューアル

iPhone7でSuicaが使えるのが想像以上に快適
今まで気づかなかったのですがSuicaの支払いに対応しているお店って結構あるんですね!
財布を忘れてもiPhoneがあればなんとかなりそうです。
www.jreast.co.jp


Reluxアプリの施設詳細画面(旅館やホテルの情報を表示するページ)のリニューアルをおこないました。今回はリニューアル時に気をつけた点などを中心に紹介したいと思います。

施設詳細画面のリニューアル

タブ表示から1画面へ

以前は「施設紹介」「プラン」「アクセス」「レビュー」の4画面のタブで構成されていましたが、リニューアルで1つの画面に統合しています。
また、部屋タイプの一覧は画面遷移せずにみられるように改善しました。


片手で操作できるように工夫

画面を下にひっぱると写真が画面中央に表示され、片手でも無理なく操作できるようになっています。
画面左上の戻るボタンは×ボタンに変わり全画面表示が解除されるようにしています。もちろん上にスワイプしても解除されます。


項目のアイコン化

施設の情報はアイコンで見やすく整理
文字を少なくすることで情報が詰まりすぎないように工夫しています。


写真・地図のパララックス

施設写真と地図にはパララックスを取り入れ、奥行きと立体感を表現しています。
画面の構造がおかしくならないように注意しながら取り入れました。


コンシェルジュ導線の追加

部屋タイプの一覧のすぐ下にReluxコンシェルジュ(カスタマーサポート)の導線を配置することで旅行の予約や相談を気軽におこなっていただけるようになっています。


どこからでも部屋タイプ一覧にジャンプ

1つの長い画面になっているのでどこからでも部屋タイプ一覧にジャンプできるよう
画面下部にボタンを設置しています。このボタンは部屋タイプ一覧が画面上に表示されると非表示になります。


リニューアルの効果

  • 予約完了までの画面がひとつ減ることによりCVRが数%改善
  • アプリに関する良いレビューが増加
  • Reluxコンシェルジュへの旅行の相談が増加

数値の改善だけでなく社内外から「使いやすくなった」と評価してもらえました。

最後に

今回のリニューアルではアプリエンジニアもSketchを使用したり、
プロトタイプを作成するなど様々なチャレンジをしました。
何度も つくって、触って、壊して を繰り返し
試行錯誤しながら気持ち良い動きになるかを確かめました。
良かったらダウンロードして触ってみてください!

Relux(リラックス)

Relux(リラックス)

  • Loco Partners Co., Ltd.
  • 旅行
  • 無料



リニューアルプロジェクトのインタビューも
Wantedlyで紹介されているので興味あったらこちらも読んでみてください!

www.wantedly.com

Relux iOSアプリ開発にfastlaneを導入してAppStore申請を自動化

本エントリーはこちらの記事の続きになります。
凄く間が空いてしまいました...(反省)
wootan1102.hatenablog.com

前回は fastlane のテストアプリ配信についてを紹介しました。
今回は AppStore への申請について紹介したいと思います。

AppStore申請の自動化

AppStore申請作業

通常の手順は以下のようになります。
fastlaneでは全ての工程を自動化することができます。

  1. アプリをアーカイブ
  2. AppStore用のバイナリを生成
  3. iTunesConnectへバイナリをアップロード
  4. メタ情報(アプリ概要、アップデート情報)を更新
  5. スクリーンショットを更新

Fastfile

fastlane/Fastfileの自動生成されたappstoreレーンを使用します。
deploygateの配信よりも時間がかかりますが、
コマンドを実行するだけで良いので簡単です。

appstoreレーン
  • sigh プロビジョニングファイルの更新
  • gym アプリケーションのビルド
  • deliver AppStoreへのアップロード
lane :appstore do
   cert
   sigh(force: true)
   gym(scheme: "relux", configuration: "Release")
   deliver(force: true)
end

after_allでSlackに通知するようにしておけば
AppStoreへのアップロードが終わった時点でSlackに通知されます。

Tips

パスワードを変更した場合

パスワードの情報はKeychainに保存されています。
iTunesConnect上でパスワードを変更し fastlane を実行するとエラーになります。
その際に下記のようにコンソール上で新しいパスワードを入力できるようになっています。
新しいパスワードを入力すると自動的にKeychainに保存されます。

Starting login with user 'XXX@XXX.XXX'
-------------------------------------------------------------------------------------
The login information you enter will be stored in your Mac OS Keychain
You can also pass the password using the `FASTLANE_PASSWORD` env variable
More information about it on GitHub: https://github.com/fastlane/fastlane/tree/master/credentials_manager
-------------------------------------------------------------------------------------
Password (for XXX@XXX.XXX):


AppleIDを変更した場合

fastlane 配下にある2つのファイルを変更する必要があります。
team_idやapp_identifierなどもこのファイルで変更することができます。

project_dir/fastlane/Appfile

apple_id "XXX@XXX.XXX"

project_dir/fastlane/Deliverfile

username "XXX@XXX.XXX"


メタ情報の更新/スクリーンショットの更新をスキップする

Deliverfileに追記することでスキップさせることができる

project_dir/fastlane/Deliverfile

#メタ情報の更新をスキップ
skip_metadata true

#スクリーンショットの更新をスキップ
skip_screenshots true


※ 詳細な使い方などはドキュメントに書いてあるので一度読んでみるのがおすすめです。
github.com


AppStoreへの申請を自動化してよかったこと

Schemeの指定ミスを防ぐ

Releaseを選択していたつもりがDebugになっており
アップロードしなおすというミスが完全になくなりました。
頻繁に発生する問題ではありませんが自動化したことで
Schemeが正しいかを確認する必要がなくなりました。

工数大幅削減

AppStoreへの申請作業は月に数回しか行わないものですが
それなりに時間がかかるのでかなり負担になっていました。
作業自体は難しいものではありませんが工数が大幅に削減することができ、
誰でも簡単に申請作業ができる状態になりました。

Gitでの管理

メタ情報(アプリ概要、アップデート情報)やスクリーンショットをGit上で管理できるようになります。
Gitで管理することによりAppStore上の情報の更新に対してレビューを行えるようになりました。

セットアップも簡単でドキュメントもしっかりしているので
設定でつまづくことはないと思います。ぜひ試してみてください!

※チーム無いで証明書を共有して管理するツールもあります。こちらのやり方が推奨されているようです。
fastlane/match at master · fastlane/fastlane · GitHub

Relux iOSアプリ開発にfastlaneを導入してテストアプリ配信を自動化

ポケモンGOが盛り上がっていますね!
ようやく60種類あつめました。コンプリートにはまだまだかかりそうです...

本エントリでは fastlane の導入について書きたいと思います。
fastlaneを導入することでテストアプリの配信コスト、AppStoreの申請コストを
大幅に削減することができました。ぜひ参考にしてみてください。

fastlaneとは

XcodeiTunes Connect 上で行う
リリースフローの作業を自動化することができるツールです。

レールの概念

fastlaneにはレールという概念が存在します。
リリースフローの作業(テスト配信、AppStoreの申請など)を
それぞれをレーンとみなし、提供されているアクションを
組合せてレーンを作成します。
用意されているものだけでも十分ですが
プロダクトに合わせてカスタマイズすることも可能です。

導入方法

基本的にコンソールの指示に従っていくだけで初期設定が完了します。

#インストール
$ sudo gem install fastlane

#初期化
$ fastlane init

#画面の指示にしたがって値を入力していく
Your Apple ID (e.g. fastlane@krausefx.com): XXX@XXX.XXX
Starting login with user 'XXX@XXX.XXX'

-------------------------------------------------------------------------------------
The login information you enter will be stored in your Mac OS Keychain
You can also pass the password using the `FASTLANE_PASSWORD` env variable
More information about it on GitHub: https://github.com/fastlane/credentials_manager
-------------------------------------------------------------------------------------

Password (for XXX@XXX.XXX): *****

+----------------+-------------------------------------------+
|                      Detected Values                       |
+----------------+-------------------------------------------+
| Apple ID       | XXX@XXX.XXX                           |
| App Name       | relux                                     |
| App Identifier | XXX.XXX.relux                         |
| Workspace      | /Users/XXX/relux_ios/relux.xcworkspace    |
+----------------+-------------------------------------------+

Please confirm the above values (y/n)
y

Created new file './fastlane/Appfile'. Edit it to manage your preferred app metadata information.
Loading up 'deliver', this might take a few seconds
Login to iTunes Connect (XXX@XXX.XXX)
Login successful

+--------------------+-------------------------+
|            deliver 1.10.3 Summary            |
+--------------------+-------------------------+
| username           | XXX@XXX.XXX          |
| app_identifier     | XXX.XXX.relux        |
| metadata_path      | ./fastlane/metadata     |
| screenshots_path   | ./fastlane/screenshots  |
| skip_binary_upload | false                   |
| skip_screenshots   | false                   |
| skip_metadata      | false                   |
| force              | false                   |
| submit_for_review  | false                   |
| automatic_release  | false                   |
+--------------------+-------------------------+

Writing to 'fastlane/metadata/ja/description.txt'
Writing to 'fastlane/metadata/ja/keywords.txt'
Writing to 'fastlane/metadata/ja/release_notes.txt'
Writing to 'fastlane/metadata/ja/support_url.txt'
Writing to 'fastlane/metadata/ja/marketing_url.txt'
Writing to 'fastlane/metadata/ja/name.txt'
Writing to 'fastlane/metadata/ja/privacy_url.txt'
Writing to 'fastlane/metadata/copyright.txt'
Writing to 'fastlane/metadata/primary_category.txt'
Writing to 'fastlane/metadata/secondary_category.txt'
Writing to 'fastlane/metadata/primary_first_sub_category.txt'
Writing to 'fastlane/metadata/primary_second_sub_category.txt'
Writing to 'fastlane/metadata/secondary_first_sub_category.txt'
Writing to 'fastlane/metadata/secondary_second_sub_category.txt'
Successfully created new configuration files.
Downloading all existing screenshots...
Downloading existing screenshot '1_iphone4_1.4.0inc-01.jpg'
Downloading existing screenshot '2_iphone4_2.4.0inc-02.jpg'
Downloading existing screenshot '3_iphone4_3.4.0inc-03.jpg'
Downloading existing screenshot '4_iphone4_4.4.0inc-04.jpg'
Downloading existing screenshot '5_iphone4_5.4.0inc-05.jpg'
Downloading existing screenshot '1_iphone35_1.3.5inc-01.jpg'
Downloading existing screenshot '2_iphone35_2.3.5inc-02.jpg'
Downloading existing screenshot '3_iphone35_3.3.5inc-03.jpg'
Downloading existing screenshot '4_iphone35_4.3.5inc-04.jpg'
Downloading existing screenshot '5_iphone35_5.3.5inc-05.jpg'
Downloading existing screenshot '1_iphone6_1.4.7inc-01.jpg'
Downloading existing screenshot '2_iphone6_2.4.7inc-02.jpg'
Downloading existing screenshot '3_iphone6_3.4.7inc-03.jpg'
Downloading existing screenshot '4_iphone6_4.4.7inc-04.jpg'
Downloading existing screenshot '5_iphone6_5.4.7inc-05.jpg'
Downloading existing screenshot '1_iphone6Plus_1.5.5inc-01.jpg'
Downloading existing screenshot '2_iphone6Plus_2.5.5inc-02.jpg'
Downloading existing screenshot '3_iphone6Plus_3.5.5inc-03.jpg'
Downloading existing screenshot '4_iphone6Plus_4.5.5inc-04.jpg'
Downloading existing screenshot '5_iphone6Plus_5.5.5inc-05.jpg'
Successfully downloaded all existing screenshots
Successfully created new Deliverfile at path 'fastlane/Deliverfile'
'snapshot' not enabled.
'cocoapods' enabled.
'carthage' not enabled.
Created new file './fastlane/Fastfile'. Edit it to manage your own deployment lanes.
fastlane will send the number of errors for each action to
https://github.com/fastlane/enhancer to detect integration issues
No sensitive/private information will be uploaded
You can disable this by adding `opt_out_usage` to your Fastfile
Successfully finished setting up fastlane

テストアプリ配信の自動化

弊社ではdeploygateを利用しており手順は以下のようになります。
fastlaneでは全ての工程を自動化することができます。

テストアプリ配信フロー

f:id:wootan1102:20160729195028p:plain

1. pod install の実行
2. アプリケーションのビルド
3. プロビジョニングファイルの更新
4. ipaファイルの生成
5. deploygateへのアップロード

Fastfile

fastlane/Fastfileに実行させたいアクションを書いてきます。
initした状態で一通りのものは揃っているので
どういう書き方をすれば良いか迷うことはないと思います。

事前処理

レーンを実行する前の事前処理を書いておくことができます。

  • 実行後にSlackに通知できるようにWebhookURLを設定
  • cocoapods pod installの実行
before_all do
   ENV["SLACK_URL"]="XXXXX"
   cocoapods
end
deploygateレーン

deploygate配信用のレーンを新しく用意しています。
アップロードする際のメッセージは最後のコミットメッセージを設定しています。

  • sigh プロビジョニングファイルの更新
  • gym アプリケーションのビルド
  • deploygate deploygateへのアップロード
lane :dg do
   sigh(adhoc: true)
   gym(scheme: "relux", configuration: "Debug")
   message = "relux for iOS\nCommit message: #{last_git_commit[:message]}"
   deploygate(user: "XXXXX", api_token: "XXXXX", message: message)
end
事後処理

レーン実行した後の処理を書くことができます。
ここでは レーンが成功したことをSlackに通知するようにしています。

after_all do
   slack(message: "Successfully fastlane.")
end
Slack上ではこのように表示されます。

f:id:wootan1102:20160729194950p:plain

レーンの実行

今回紹介したdeploygateはこのように実行します。

$ fastlane dg

とても簡単です。導入前は手動でアップロードしていたのですが
コマンド1つでアップロードできるようになりかなり楽になりました。
deploygateには必ず最新版のテストアプリがあるという状態を保つことができています。

AppStoreへの申請についても自動化することができるので次回紹介したいと思います。

relux iOSアプリに Material Design 風のフォームを導入

relux iOSアプリにマテリアルデザイン風のフォームを導入しました。

マテリアルデザインのライブラリはMaterialKitが有名ですが
見た目がイメージしていたものと異なるのでスクラッチ開発しました。
実際のアプリケーションのスクリーンショットと交えながら紹介していきます。

マテリアルデザインとは

Googleが発表したデザインガイドラインです。
詳しくはこちらを参照
Introduction - Material design - Material design guidelines

導入したきっかけ

  • iOS標準のUIパーツはシンプルだがプロダクトとマッチしなかった
  • フォーカスがあたっているフォームがわかりにくかった
  • Androidのフォームが格好よくて羨ましかった

気をつけたこと

  • 操作感を大事にする
  • Androidっぽくなりすぎないようにする
  • 余計なインタラクションはつけない(リップルエフェクトは無し)
  • 余計な影をつけない(あくまでもフラット)

入力フォーム

画面表示

入力フォームはホワイトスペースを広くとることでスッキリさせています。
また、エラーメッセージが表示されても綺麗にみえるように調整しています。

フォームレイアウト

どのフォームも基本的に以下の要素で構成されています。

  1. タイトル
  2. 必須項目マーク
  3. テキストフィールド
  4. 下線
  5. アイコン
  6. エラーラベル

f:id:wootan1102:20160621001759p:plain

エラーの表示、非表示でレイアウトの高さがかわらないようになっています。
Androidのサポートライブラリでは高さが動的にかわるようになっていますが
レイアウトがガタガタかわると美しくないのであえて固定しました。

フォームの共通処理

必須項目制御
BOOLで必須項目を設定できるようにしています。
必須項目にするとフォーカスがはずれた際に
自動的に空か判定してエラーメッセージを表示するようにしています。


キーボード制御
AccessoryViewが自動で挿入されるようにしています。

「決定する」を押すとキーボードが閉じます。
キーボードのNext(Enter)を押すと次のフォームにフォーカスするようになっています。
次のフォームが存在しなければキーボードを閉じます。

次のフォームにフォーカスがあたると
自動的にスクロールされるようになっています。

f:id:wootan1102:20160629164350g:plain

ここの使用感はかなりこだわっってつくっているので
実際のアプリをダウンロードして触ってみてください!

Relux(リラックス)

Relux(リラックス)

  • Loco Partners Co., Ltd.
  • 旅行
  • 無料


フォームの状態

フォームの状態は以下の3種類です。
disabledは用意していません。
シンプルなデザインなので迷わないよう
disabledにするのではなく表示しないというルールにしています。

フォーカスがあたっていない状態

フォーカスがあたっている状態


フォーカスがあたると下線の色を変更し
フォームの位置を計算してスクロールします。

エラーが表示されている状態


エラーメッセージが設定されると下線の色を変更し
エラーメッセージラベルを表示します。

フォームの種類

フォームの種類によって入力方法を切替えています。
ラジオボタン以外は使いまわせるように汎用的な設計になっています。

テキストフィールド


テキストビュー


セレクトボックス


日付ピッカー


ラジオボタン・スイッチ

フォームの入力検知

NSNotificationCenterのaddObserveを使用しています。
クレジットカード入力欄などの一部のフォームは入力内容をもとに制御を行っています。
下記は入力された数字をみてスペースをいれています。

AmericanExpressの場合(番号はダミー)

VISAの場合(番号はダミー)

細かいですが実際のカードと同じように表示されるので
入力ミスなどを減らすことができました。
※クレジットカードのスキャン機能は検討中です。

最後に

いかがでしたか?
iOSのフラットデザインとAndroidのマテリアルデザインの
良い部分を組み合わせることができたのではないかなと思います。
さらに良いユーザ体験を提供できるよう改善を行っていきます!

おまけ

今まで知らなかったのですがこちらのライブラリも良さそうですね。
github.com

potatotips # 30 (iOS/Android開発Tips共有会)に参加しました!

potatotipsにiOSブログまとめ枠で参加しました!
potatotips.connpass.com

会場は株式会社VOYAGE GROUPさんです。

  • 会議室は無料で貸出
  • 勉強会をやるとピザの差入れあり

らしいのでいつか使ってみたいと思います。

iOS Tipsまとめ

iOSに関連する発表のメモになります。
間違いなどがあれば指摘お願いします。

Proactive Suggestions 発表:nk5さん

※資料挿入予定

  • NSUserActivityにmapItemが新しく追加

QuickType for TextFieldが便利そうでした。
このあたりはあまり触れていないので実際に動かして色々試したいです。
(うさぎの汁なし担々麺 美味しそう...)

Siri Kit 発表:Motoki Naritaさん

speakerdeck.com

  • Intents Framework と Intents UI Framework を使って実装する
  • AppIndentVocabulary.plistにワードを登録するとSiriが解釈できるようになる
  • UnitTestを書くことができる

Siri Kitを使ったアプリが楽しみですね。
UnitTestを書けるのが意外でした。
喋って動作確認はかなり恥ずかしいのでこれはありがたいです。

パスワードレスのアプリをつくる 発表:hayashi311さん

speakerdeck.com

  • fidoという生体認証の話
  • 公開鍵暗号を使ったチャレンジレスポンス方式の認証
  1. サービス登録時に生体認証を使う
  2. 生体認証で署名鍵、検証鍵を生成
  3. 署名鍵を端末で保存
  4. 検証鍵をサーバで保存

噛み砕いて説明していただいたのでとてもわかりやすかったです。
これが標準になれば幸せになれそうな予感がしました。
バイス間連携もできるそうです。

Xcode Extensions 発表:y_kohさん

speakerdeck.com

  • Xcode Source Editor Extensionsの話
  • 開いているファイルを処理することができる
  • パレットを表示したりエディタの表示を変えることはできない

まだまだ できることは少なそうですが今後に期待したいですね。

さらに便利になったR.swiftの実力を見るがいい 発表:takasekさん

qiita.com

  • Nibの指定などを安全に書くことができる
  • NSLocalized Stringsにも対応
  • Colorsにも対応

NSLocalized Stringsや画像などはプラグインで入力しているので、タイポ困ったことはありませんがリソースが削除された際にビルドエラーになるのは良いですね。

RIP Xcode Plugin 発表:dealforestさん

speakerdeck.com

  • Xcode8からcode signされるようになりプラグインがロードされない
  • code sign を消したXcodeなら動く
  • Swiftのプラグインがうまく動かない?

Xcodeプラグインは本当に悲しいです...
しばらくは code sign を消したXcodeでがんばって
Xcode Editor Extensionsを見守るしかないんですね...

Server side swift framework Slimnerの紹介 発表:noppoManさん

speakerdeck.com

github.com

  • Revel(GO)の2倍
  • node.jsの5倍

面白そうなのでちょっと触ってみたいと思いました。
サーバサイドもクライアントもSwiftでできたら幸せ

最後に

WWDCの直後だったので関連技術の発表が多かったです。
自分が触れていない部分について聞くことができて勉強になりました。
WWDC関連の勉強会にはいくつか参加する予定なのでさらに理解を深めたいと思います。

アプリUIUX事例研究 # 2 TodoMovies

アプリUIUX事例研究

"イケてるアプリ"の"イケてるUIUX"を研究する。
話題のアプリや気になったアプリを触って
良いと思ったものを紹介していきたいと思います。
第2回目は「TodoMovies」を紹介します。

Discover画面


大きめの写真の上に文字が乗せられています。
パララックス(視差効果)で奥行きがでています。
使われているアプリが増えてきましたね!

My Lists


To Watch と Watched で色がわかれています。
そのほかに自分で定義したリストもつくれるようです。


先に進んだ画面でも同じ色が使われています。


エンジニアはこの色が好きな人も多いかも?

Details


ポスター画像の下部を三角形でマスクして文字を載せています。
これはiPhone6スクリーンショットなのですが
1画面に収まるように設計されているのが良いですね。
予告動画の再生とシェア導線がきちんと表示されています。


下までスクロールすると監督とキャストが顔丸で表示されます。

Search


検索画面はこのようになっています。
Watchedにある Star Wars は緑のマークがついています。
これはかなりわかりやすいですね。


左からスワイプすると + が表示されます。
青なので To Watch に追加されるのがわかりますね。


さらにスワイプすると チェック が表示されます。
緑なので Watched に追加されるのがわかりますね。

Settings


設定画面でパララックスをオン・オフ切替えできるようになっています。
パララックスは苦手な人もいるのでこの設定はありがたいですね。


以上になります。
使われている色に一貫性があり、わかりやすくなっていました。
スワイプ操作も慣れるとかなり使いやすいです。

TodoMovies 4

TodoMovies 4

  • Taphive GmbH
  • Entertainment
  • Free