Relux Androidアプリ がベストアプリに選ばれました!
ベストアプリとは?
Google Play がこの 1 年を振り返って選んだ「2016年 ベストアプリ」をご紹介します。思わず家族や友人にすすめたくなるアプリ、画面にくぎ付けになってしまうアプリ、ランキングを賑わせたアプリ、洗練された美しいアプリなど、多彩なラインアップ。さらに12/8 (木) 受賞イベントにて、2016年 ベストアプリ並びに各カテゴリー大賞が発表されます。発表をお楽しみ!
2016年 ベストアプリ
Xcodeで覚えておくべきショートカット
本エントリーではXcodeでよく使う(使いそうな)ショートカットについてまとめました。
Breakpoint操作はいつもマウスでポチポチしてしまうので、しっかりショートカットを使うようにしたい...
コード操作
選択範囲のコメントアウト
Cmd + /
インデント操作 左にずらす
Cmd + [
インデント操作 右にずらす
Cmd + ]
カーソル位置を行の先頭に移動
Ctrl + A
カーソル位置を行の末尾に移動
Ctrl + E
カーソル位置から行の先頭まで選択
Cmd + Shift + ←
カーソル位置から行の末尾まで選択
Cmd + Shift + →
変数、メソッドにジャンプ
Cmd + Click
変数、メソッドのDescription表示
Opt + Click
Xcode操作
左ペイン表示/非表示切替え
Cmd + 0
右ペイン表示/非表示切替え
Cmd + Opt + 0
デバッグエリアの表示/非表示切替え
Cmd + Shift + Y
スタンダードエディタ切替え
Cmd + Return
アシスタントエディタ切替え
Cmd + Opt + Return
1つ前に選択していたファイルに戻る/進む
- 戻る Cmd + Ctrl + ←
- 進む Cmd + Ctrl + →
ヘッダーファイル / 実装ファイルの切替え
Cmd + Ctrl + ↑ または Cmd + Ctrl + ↓
検索
プロパティ・メソッド一覧表示
Ctrl + 6
ファイル内検索
Cmd + F
プロジェクト内検索
Cmd + Shift + F
- 選択時にEnter スタンダードエディタに反映
- 選択時にOption + Enter アシスタントエディタに反映
クイックオープン
Cmd + Shift + O
ビルド/デバッグ
Project Clean
Cmd + Shift + K
Build
Cmd + B
Run
Cmd + R
Stop
Cmd + .
Breakpoint操作
- Step Over F6
- Step In F7
- Step out F8
- Continue Cmd + Ctrl + Y
Breakpoint 追加削除
Cmd + \
これを覚えるだけでかなり効率よくなるので頑張って覚えましょう!
iMessageAppへの対応
PSStore10周年セールでブラッドボーンを購入しました。
今月末はFF15が発売になるので積まないように頑張ってクリアします!
www.jp.playstation.com
本エントリーではiMessageAppの対応について簡単にご紹介したいと思います。
ReluxではiMessageApp内で旅館・ホテルの検索を行い、シェアすることができます。
Storeでもフィーチャーされているのでぜひダウンロードして触ってみてください!
ターゲットの追加
既存のアプリにExtensionを追加する場合は
プロジェクトの + からターゲットを追加してください。
アイコンの設定
通常のアプリとは異なるサイズのアイコンが必要になります。
一番大きなサイズは 1024✕768なのでそこから縮小・トリミングして必要なサイズを作成しましょう。
レイアウト作成
MainInterface.storyboard
通常のアプリケーションのStorybaordと同様にレイアウトを組むことができます。
コントローラはUIViewControllerではなくMSMessagesAppViewControllerを継承したものになります。
後ほど説明がでてきますが2種類の画面モードが存在するのでしっかりAutoLayoutに対応する必要があります。
Viewのライフサイクル
MSMessagesAppViewControllerではメッセージ専用のメソッドが用意されています。
通常のアプリケーションをつくり慣れている方なら名前から挙動を予測することができます。
Extensionの状態
willBecomeActive(with: MSConversation)
- アクティブ状態に遷移する前に呼ばれる
didBecomeActive(with: MSConversation)
- アクティブ状態に遷移した後に呼ばれる
willResignActive(with: MSConversation)
- 非アクティブ状態に遷移する前に呼ばれる
didResignActive(with: MSConversation)
- 非アクティブ状態に遷移した後に呼ばれる
メッセージのイベント
選択されたメッセージの値をつかって処理をおこなう場合は
didSelect内でおこなう必要があります。willSelect内だとselectedMessageが更新されていません。
willSelect(MSMessage, conversation: MSConversation)
- メッセージオブジェクトを選択したあと、selectedMessageを更新する前に呼ばれる
didSelect(MSMessage, conversation: MSConversation)
- メッセージオブジェクトを選択したあと、selectedMessageを更新した後に呼ばれる
didReceive(MSMessage, conversation: MSConversation)
- 新しいメッセージを受け取ったときに呼ばれる
プレゼンテーションスタイル
iMessageExtensionは2種類の画面モードが存在します。
Compact
- コンパクト表示(ソフトウェアキーボードと同じサイズ)
- Expanded時に右のボタンタップで切り替る
いつでもユーザが切替えることができるので両方に対応する必要があります。
プログラム側からも画面モードをリクエストすることができます。
requestPresentationStyle(MSMessagesAppPresentationStyle)
で指定したPresentationStyleに切り替えることができます。
画面が切り替る際には下記のメソッドが呼ばれます。
willTransition(to: MSMessagesAppPresentationStyle)
- 画面モードが切り替る前に呼ばれる
didTransition(to: MSMessagesAppPresentationStyle)
- 画面モードが切り替った後に呼ばれる
これらの用意されたメソッドを使用して処理を行います。
ここで紹介した以外のものも存在するので詳しくはドキュメント参照。
https://developer.apple.com/reference/messages/msmessagesappviewcontroller
メッセージの送信
MSMessageTemplateLayoutを使用しメッセージを設定します。
(これ以外のやり方がわからなかったのでカスタムする方法とかあったら教えてください...)
MSMessage *message = [MSMessage new]; MSMessageTemplateLayout *layout = [MSMessageTemplateLayout new]; // ここでlayoutに値を設定 message.layout = layout; [self.activeConversation insertMessage:message completionHandler:nil];
Layoutに設定できる値については公式のこの画像がとてもわかりやすいです。
左上のアプリアイコンは自動的に挿入されます。
https://developer.apple.com/reference/messages/msmessagetemplatelayout
iMessageAppに対応する際のポイント・Tips
キーボードについて
ソフトウェアキーボードはCompactでは表示することができません。
UITextFieldなどでキーボードを表示する場合は気をつけましょう。
Expandedになる前にソフトウェアキーボードを表示しようとするとクラッシュします。
Podsを共有するには?
複数のターゲットでPodsを共有するには以下のように書きます。
def shared pod 'hoge' end target 'SampleApp' do pod 'foo' shared end target 'SampleAppExtension' do pod 'bar' shared end
Modelなどの共通クラスはどうするか?
Modelなどは本体アプリとExtensionでかわらないので共通のクラスを使うようにします。
EmbeddedFrameworkを作成する方法もありますが、一部のみであれば本体アプリのソースを参照する方法がおすすめです。
共有したいファイルを追加するとこのような画面が表示されます。
このときに「Copy items if needed.」のチェックをはずすと
ファイル自体はコピーされずに参照することができます。
本体アプリとKeychainStoreを共有するには?
Keychain Sharingを使用します。
Project > Capabilities > Keychain Sharing をONにし
Keychain Groupsを揃えるだけで共有することができます。
ローカルストレージやUserDefaultsを共有したい場合はApp Groupsを使用します。
Keychain Sharingと同様にProject > Capabilities > App Groups をONにすることで共有することができます。
本体アプリを起動するには?
AppExtensionにはUIApplicationが存在しません。
AppExtensionではNSExtensionContextを使用します。
open(URL, completionHandler: ((Bool) -> Void)? = nil)で
カスタムスキームを指定することで本体Appをひらくことができます。
Reluxではメッセージをタップすると
メッセージに設定されている施設の詳細ページに遷移するようになっています。
最後に
iMessageAppに対応することで
アプリ間を行き来することなく情報をシェアできるようになり、
iMesssage上でやりとりを完結することが出来るようになります。
より良いユーザ体験のためにもiMessageApp対応を検討してみてはいかがでしょうか?
Relux施設詳細画面のリニューアル
iPhone7でSuicaが使えるのが想像以上に快適
今まで気づかなかったのですがSuicaの支払いに対応しているお店って結構あるんですね!
財布を忘れてもiPhoneがあればなんとかなりそうです。
www.jreast.co.jp
Reluxアプリの施設詳細画面(旅館やホテルの情報を表示するページ)のリニューアルをおこないました。今回はリニューアル時に気をつけた点などを中心に紹介したいと思います。
施設詳細画面のリニューアル
タブ表示から1画面へ
以前は「施設紹介」「プラン」「アクセス」「レビュー」の4画面のタブで構成されていましたが、リニューアルで1つの画面に統合しています。
また、部屋タイプの一覧は画面遷移せずにみられるように改善しました。
片手で操作できるように工夫
画面を下にひっぱると写真が画面中央に表示され、片手でも無理なく操作できるようになっています。
画面左上の戻るボタンは×ボタンに変わり全画面表示が解除されるようにしています。もちろん上にスワイプしても解除されます。
リニューアルの効果
- 予約完了までの画面がひとつ減ることによりCVRが数%改善
- アプリに関する良いレビューが増加
- Reluxコンシェルジュへの旅行の相談が増加
数値の改善だけでなく社内外から「使いやすくなった」と評価してもらえました。
最後に
今回のリニューアルではアプリエンジニアもSketchを使用したり、
プロトタイプを作成するなど様々なチャレンジをしました。
何度も つくって、触って、壊して を繰り返し
試行錯誤しながら気持ち良い動きになるかを確かめました。
良かったらダウンロードして触ってみてください!
リニューアルプロジェクトのインタビューも
Wantedlyで紹介されているので興味あったらこちらも読んでみてください!
Relux iOSアプリ開発にfastlaneを導入してAppStore申請を自動化
本エントリーはこちらの記事の続きになります。
凄く間が空いてしまいました...(反省)
wootan1102.hatenablog.com
前回は fastlane のテストアプリ配信についてを紹介しました。
今回は AppStore への申請について紹介したいと思います。
AppStore申請の自動化
AppStore申請作業
通常の手順は以下のようになります。
fastlaneでは全ての工程を自動化することができます。
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にはレールという概念が存在します。
リリースフローの作業(テスト配信、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では全ての工程を自動化することができます。
テストアプリ配信フロー
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上ではこのように表示されます。
レーンの実行
今回紹介したdeploygateはこのように実行します。
$ fastlane dg
とても簡単です。導入前は手動でアップロードしていたのですが
コマンド1つでアップロードできるようになりかなり楽になりました。
deploygateには必ず最新版のテストアプリがあるという状態を保つことができています。
AppStoreへの申請についても自動化することができるので次回紹介したいと思います。