wootan's diary

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

iPhoneXに対応しました!

ReluxをiPhoneXに対応しました!
発売前に対応は完了していたのですが...時間がとれず...(反省)

そしてAppタブの「iPhoneXにおすすめ」に掲載してただきました🎉

f:id:wootan1102:20171116124523p:plain:w320


iPhoneX対応についてはいくつか記事があがっていますが、同じようにReluxでやったことについて書きたいと思います。載せているスクリーンショットはクリックで拡大することができます。拡大すると蟹が食べたくなるかも...

f:id:wootan1102:20171116124313p:plain:w320

f:id:wootan1102:20171116124318p:plain:w150 f:id:wootan1102:20171116124323p:plain:w150

f:id:wootan1102:20171116124328p:plain:w150 f:id:wootan1102:20171116124333p:plain:w150

f:id:wootan1102:20171116124337p:plain:w150 f:id:wootan1102:20171116124345p:plain:w150


iPhoneX対応

開発環境

  • Xcode9以降
  • iOS SDK 11以降

セーフエリア

セーフエリアとは

アプリのコンテンツやUIが正しく表示され、操作しやすいように安全な領域(セーフエリア)が新たに設けられています。セーフエリアはAutoLayoutに対応していれば簡単に対応することができます!

参考URL
Update Apps for iPhone X - iOS - Apple Developer

画面上部の扱い


f:id:wootan1102:20171116170723p:plain:w320

セーフエリアに基づいてステータスバーに自動的にスペースが挿入されます。
ステータスバーの高さを20pxとして扱っているアプリは、レイアウト崩れなどが発生する可能性があります。

丸みを帯びたディスプレイになったのでコンテンツやUIをコーナーに配置してはいけません。また、センサーハウジング(切り欠き部分)にもかぶらないように配置する必要があります。


画面下部の扱い


f:id:wootan1102:20171116170753p:plain:w320

ホームインジケータに干渉しないようにする必要があります。
特に画面下部に固定するようなUIは特に注意です。


Storyboardでセーフエリアを有効にする

User Safe Area Layout Guides にチェックをいれることで有効になります。
有効にするとUILayoutGuideが追加されます。

f:id:wootan1102:20171116172209p:plain:w320

ソースコード上からセーフエリアを取得する

safeAreaInsetsを使用します。
UIView の layoutSubviews もしくは UIViewController の viewWillLayoutSubviews で正しい値が取得できます。

参考記事
qiita.com


Swiftの場合

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    if #available(iOS 11.0, *) {
        let safeAreaInsets: UIEdgeInsets = view.safeAreaInsets
    }
}

Objective-Cの場合

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];    
    if (@available(iOS 11.0, *)) {
        UIEdgeInsets safeAreaInsets = self.view.safeAreaInsets;
    }
}

スクリーンエッジジェスチャー

iPhoneXではスクリーンエッジジェスチャーで様々なことができます。

  • ホームスクリーンに戻る
  • アプリスイッチャー
  • 通知センター
  • コントロールセンター

この操作と干渉しないようにする必要があります。
干渉してしまう場合はエッジプロテクトを使用します。
エッジプロテクトを使用すると
1回目にアプリ固有のジェスチャーが呼び出され、
2回目にシステムジェスチャーが呼び出されます。

Swiftの場合

override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge {
    return .bottom
}

Objective-Cの場合

- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
    return UIRectEdgeBottom;
}

Reluxではセレクションズ(テーマ別まとめ)、人気宿ランキングでエッジプロテクトを使用しています。

f:id:wootan1102:20171116124318p:plain:w320


Reluxで対応した内容は以上になります。
iPhoneXの画面いっぱに表示される写真が綺麗なので
ぜひダウンロードして触ってみてください🙏

Relux(リラックス)

Relux(リラックス)

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

iOS11の Password AutoFill に対応してみた

iOS11がリリースされましたね!
アプリの審査がかなりギリギリでしたが、対応したものをリリースすることができました 笑
今回はPassword AutoFillについて書きたいと思います。

Password AutoFillとは?

Password AutoFillはiOS11のあたらしい機能で、
iCloud Keychainに保存されたアカウント/パスワードをアプリ上で自動入力することができます。

保存されたアカウント/パスワードはiOSの設定画面から閲覧、編集することができます。
また、新しく追加することも可能です。
設定 > アカウントとパスワード > AppとWebサイトのパスワード

Password AutoFillが有効な条件

  • Webとアプリにログイン機能がある。
  • ユーザがiCloudキーチェーンを有効にしている。
  • ユーザがSafariを使用している。

Safari以外のブラウザをつかっていたり、サードパーティのパスワードマネージャを使っている場合は使えません...

対応方法 アプリ編

1. TextFieldのContentTypeにUsernameとPasswordを設定する

Swift

if #available(iOS 11.0, *) {
    usernameTextField.textContentType =  UITextContentType.username
    passwordTextField.textContentType = UITextContentType.password
}

Objective-C

if (@available(iOS 11.0, *)) {
    [usernameTextField setContentType:UITextContentTypeUsername];
    [passwordTextField setContentType:UITextContentTypePassword];
}

※StoryboardからContentTypeを設定することもできます。

2. Associated Domainsを有効化する

https://developer.apple.com/account/ios/identifier/bundle

f:id:wootan1102:20170921010410p:plain

※Universal Linksなどに対応していれば対応済のはずです。

3. Associated Domainsを設定する

Xcode > Project > Capabilities > Associated Domains
f:id:wootan1102:20170921010550p:plain

「webcredentials:ドメイン名」を追加

対応方法 サーバ編

apple-app-site-associationファイルを設置する

  • 設置場所はドメインのルート配下
  • httpsでアクセスできるように設定(httpの場合は署名が必要?)
  • jsonファイルだが拡張子はつけない

apple-app-site-association

{
  "webcredentials": {
    "apps": ["TeamID.BundleIdentifier"]
  }
}

※Universal Linksなどに対応していればファイルは設置済のはずです。

対応は以上になります。
Universal Linksなどに対応していれば、アプリもサーバサイドもほとんど工数はかかりません。

実機での動作

TextContentTypeが設定されているTextFieldにフォーカスがあたると鍵アイコンが表示されます。
このアイコンをタップすることでTextFieldにアカウント/パスワードを自動入力することができます。

iOS11の Password AutoFill は工数をあまりかけずに対応することができます!
ちょっとしたことですが、メールアドレスやパスワードを入力しなくても済むようになるので
ユーザの離脱率の改善にもなりそうです。ログイン機能がある場合はぜひ実装してみてください。

Firebase Performance Monitoring を導入してみた

前回の記事から少し間があいてしまいましたが
Firebase Performance Monitoringを導入しました!
β版ですが十分つかえるレベルだと思います。

developers-jp.googleblog.com

Firebase Performance Monitoring とは?

アプリの起動時間、ネットワークリクエストなどのパフォーマンス情報を自動的に測定し、Firebaseコンソール上で確認することができるようになります。
アプリのパフォーマンスで問題がある部分を把握するのに役立つサービスです。

導入方法

Firebaseを導入済であればかなり簡単に導入することができます。

0. 前提条件

  • Xcode8.2.1以降
  • iOS8以上をターゲットとするXcodeプロジェクト
  • CocoaPods 1.0.0以降

1. Podfileの編集

pod 'Firebase/Performance'

2. インストー

pod update

3. コードの変更

// Objective-C
@import <Firebase.h>

[FIRApp configure];

ハマったところ

インストール時にこのようなエラーがでて焦りました。

[!] Unable to satisfy the following requirements:

- `Firebase/Performance` required by `Podfile`

Specs satisfying the `Firebase/Performance` dependency were found, but they required a higher minimum deployment target.

すぐに気づいたのですが update せずに install しており
Firebase/Coreが古いバージョンでロックされていました。

Firebase Remote Configをつかって有効/無効を切替え

公式サイトにもやり方が掲載されています。
Peformance Monitoring はβ版なので切替えられるようにしておいたほうが良さそうです。
Disable the Firebase Performance Monitoring SDK  |  Firebase

1. コードの変更

公式とは違うのですがこのように設定しました。

if (self.remoteConfig[@"performance_enable"].numberValue.boolValue) {
   [FIRPerformance sharedInstance].instrumentationEnabled = YES;
   [FIRPerformance sharedInstance].dataCollectionEnabled = YES;
} else {
   [FIRPerformance sharedInstance].instrumentationEnabled = NO;
   [FIRPerformance sharedInstance].dataCollectionEnabled = NO;
}

2. Firebase Remote Configの設定

Firebaseコンソール上ではこのようになっています。
値を0に変更することで無効化できます。
また、この設定自体を誤って消してしまった場合にも無効になります。
f:id:wootan1102:20170630210112p:plain

確認可能な情報

ダッシュボードではこのように表示されます。

f:id:wootan1102:20170630210637p:plain


端末、国、OS毎の起動時間や
ネットワークリクエストごとの応答時間、成功率など
細かくデータを確認することができます。

アプリの起動時間、ネットワークリクエストの応答速度で
ユーザ体験が大きくかわってしまうので
Firebase Performance Monitoringで計測して、
問題がある部分を少しずつ改善していくのが良さそうです!

Firebaseのカスタムパラメータレポートをつかってみた

Google I/O 2017でFirebaseの新機能が発表されました!
Analyticsの強化やパフォーマンス測定ツールの提供など盛りだくさんです。
詳しくはこちらのブログを御覧ください。

developers-jp.googleblog.com


今回はカスタムパラメータレポートを試してみました。

カスタムパラメータレポート

これまでカスタムパラメータはFirebaseの画面上では確認できず、BigQueryと連携して分析する必要がありました。
これからは画面上で簡単に分析が可能になります。
カスタムパラメータのためにクエリを書かなくてよくなります。

設定方法

1. Analytics > イベントのイベント一覧を表示

f:id:wootan1102:20170531221517p:plain

2. カスタムパラメータを追加したいイベントのアイコンからパラメータレポートを編集



3. パラメータ一覧から分析したいデータを追加

f:id:wootan1102:20170531223047p:plain

4. タイプを設定して保存

これで設定は完了です!かなり簡単ですね!
これから追加するカスタムパラメータをあらかじめ追加しておくこともできます。

データの閲覧

イベント一覧からカスタムパラメータを設定したイベントを選択すると詳細画面に遷移します。
この画面でカスタムパラメータの内容を確認することができます。

f:id:wootan1102:20170531224702p:plain
こちらはRelux開発版の検索キーワード一覧です。
(動作確認に北海道で検索している人が多いようです!)

数値は伏せていますがイベント発火件数とユーザ数を確認することができます。
通常のイベントと同様にフィルタをかけることができるので
ユーザプロパティやユーザリストで絞り込んでデータをみることもできます。

※データが多い場合はこのようなエラーが発生することがありますが
 待機してしばらく待つと問題なく表示されます。

f:id:wootan1102:20170531224612p:plain

あまりにも時間がかかる場合は期間をフィルタすると良さそうです。

制限

カスタムパラメータレポートは設定してから蓄積されるようになっています。
他のデータと同様に反映されるまでに最大24時間かかることがあります。
過去分について分析する場合やすぐにデータが見たい場合は
BigQueryを使用して分析する必要があります。

また、カスタムパラメータレポートを設定できる数は
テキストは10個まで、数値は40個まで設定することができます。

参考URL

support.google.com


複雑な分析はBigQueryを使う必要がありますが、
簡単なデータならエンジニア以外でも確認できるようになるので凄く便利ですね!
よくみるデータはここで確認できるようにしておくと良さそうです!

FirebaseのStreamViewとDebugViewをつかってみた

ReluxではFirebaseを既に導入しているので実際にさわってみました。
間違いなく神機能なのでぜひ使ってみてください!

【参考記事】
developers-jp.googleblog.com


DebugView

DebugViewはFirebaseで取得可能なイベントをリアルタイムに閲覧することができます。
不具合の調査や新しいイベント、プロパティの確認などにも使えそうです。
これまではBigQueryを利用するか、イベントが反映されるまで数時間待つ必要がありましたが
これからはDebugViewを利用することで簡単にイベントを確認することができます。

使い方

f:id:wootan1102:20170314192223p:plain

EditScheme -> Run -> Arguments Passed On Launch に -FIRDebugEnabled を追加して有効にするだけで利用可能になります。
Debugを無効にしたい場合は -FIRDebugDisabled を有効にするだけです。

実際の画面

f:id:wootan1102:20170314192818p:plain

実際の画面ではイベント、ユーザプロパティ、エラーをリアルタイムに確認することができます。
問題ある部分はハイライトされるのでしっかりイベントを設定しておけば、デバッグ時のエラー調査なども捗りそうです。

Stream View

StreamViewは直近30分以内にFirebaseAnalyticsに届いたイベントを可視化したものです。
イベントが送信されていればすぐに確認することができます。DebugViewのような設定は必要ありません。

実際の画面

f:id:wootan1102:20170314194005p:plain

地図上にこのように表示されます。
正確な位置まではわかりませんが、どの都市からアクセスがあるかを確認することができます。

他にもイベント一覧や
f:id:wootan1102:20170314195159p:plain

ユーザプロパティ一覧
f:id:wootan1102:20170314194720p:plain

地域など この画面で様々なデータを閲覧することができます。
f:id:wootan1102:20170314194904p:plain

フィルタをかけることもできるので特定の地域・イベント・プロパティで絞って
データをウォッチすることも可能です。

ユーザスナップショット

画面右下にあるユーザスナップショットをクリックすると
ランダムに選択されたユーザのイベントストリーミングを閲覧することができます。
ユーザスナップショットは地域、アプリバージョンでのみ絞り込むことできます。

f:id:wootan1102:20170314200114p:plain


新しい施策に対してユーザがどういう行動をとっているかすぐに確認することができるのでRemoteConfigとの相性も良さそうですね。
細かいデータの確認はBigQueryが必要ですが
StreamViewでいろいろできそうなので有効活用していきたいと思います。

まだ Firebaseを導入していない場合は
こちらからデモプロジェクトを確認してみてください!本当にこれは凄い奴です!!
support.google.com

Google Data StudioをつかってFacebookページのいいね数を表示してみた

Relux Facebookページの「いいね!」の数を
社内の一番目立つところに置いてあるディスプレイに表示しました。
いいね数はリアルタイムに更新されるので
出社時と退社時で数値が増えているのが嬉しいです。

f:id:wootan1102:20170226175105j:plain

簡単にできるのでやり方をご紹介したいと思います。
サーバなどを用意する必要はありません!

つかったもの

f:id:wootan1102:20170226181635p:plain

手順

1. Google Spread Sheetを新規に作成

このシートはGoogle Data Studioのデータソースとして使用します。

2. Google Apps ScriptでFacebook GraphAPIを使用していいね数を取得

function myFunction() {
  var response = UrlFetchApp.fetch('https://graph.facebook.com/?id=rlx.jp&access_token=アクセストークン’);  
  var result = JSON.parse(response.getContentText());
  var range = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange(1,1);
  range.setValue(result.likes);
}

Facebook Graph APIで取得した「いいね」の数をA1セルにセットしています。
プロジェクトのトリガーでmyFunction を定期的に実行するように設定します。

f:id:wootan1102:20170226182817p:plain

3. Google Data Studio で新しいレポートを作成

データソースに先程作成したGoogle Spread Sheetを指定します。

データの表示はスコアカードを使用しています。
データソースにはGoogleAnalyticsを指定することもできるので
PV数なども簡単にダッシュボードに表示することができます。

4. Google Chrome Extension の作成

Google Data Studioのデータは自動的に更新されず、
画面に表示される更新ボタンを押す必要があります。

ブラウザをリフレッシュするプラグインでは値が更新されなかったので

更新ボタンを一定間隔で押すだけのChrome拡張機能をつくりました。

manifest.json

{
  "content_scripts" : [
    {
      "matches" : [
        "https:\/\/datastudio.google.com\/*"
      ],
      "js" : [
        "content_scripts.js"
      ]
    }
  ],
  "manifest_version" : 2,
  "name" : "Google Data Studio Auto Refresh",
  "version" : "0.1"
}

content_scripts.js

function action() {
    var elements = document.getElementsByClassName("control-icon icon ng-scope");
    elements[0].click();
}

setInterval("action()", 60000);

これをChromeで読み込んで完成です。

f:id:wootan1102:20170226182832p:plain


社内でも好評です!工数をあまりかけずに簡単にできるので試してみてはいかがでしょうか?

Xcodeのビルド時間を短縮する

Xcodeのビルド時間が気になってきたので
調査してすぐにできそうなものを試してみました。

Xcodeが使用するコア数を設定

Macのコア数を確認

以下のコマンドを実行

$system_profiler SPHardwareDataType
Model Name: MacBook Pro
      Model Identifier: MacBookPro12,1
      Processor Name: Intel Core i5
      Processor Speed: 2.7 GHz
      Number of Processors: 1
      Total Number of Cores: 2
      L2 Cache (per Core): 256 KB
      L3 Cache: 3 MB
      Memory: 16 GB…

Total Number of Coresがコア数なのでこの場合のコア数は2です。

Xcodeの設定を変更

上記コマンドで調べたコア数を設定します。
これよりも大きな値を設定しても意味はなく、パフォーマンスが悪化することがあります。

以下のコマンドを実行

$defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 2

Debug Information Formatを変更

SchemeがDebugのときのみ
DWARF with dSYM FileからDWARFに設定を変更します。
dSYMファイルはクラッシュログを調査するのに必要なもので開発時は必要ないです。

CocoaPodsのコンパイルをスキップ

※効果はありますが戻し忘れに注意です。

Product -> Scheme -> Edit SchemeからBuildを選択し
Find Implicit Dependenciesのチェックをはずします。

f:id:wootan1102:20170112175515p:plain

Podfileを変更してもビルドは走らないので注意しましょう。

CocoaPodsではなくCarthageを使用

Carthageはライブラリを事前にビルドし、フレームワークを作成するのでビルド時間を短縮することができます。
対応していないライブラリ以外はCarthageを使用するのが良さそうです。
試せていませんがSwiftPackageManagerでも効果があるようです。

github.com
github.com


ビルド時間を確認するには?

以下のコマンドを実行

$defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES

Xcode上ではこのようにビルド時間が表示されます。

f:id:wootan1102:20170112174619p:plain

最後に

設定を少し変更するだけでもビルド時間が改善されました。
Swiftはコードレベルでも改善できることがあるので
パフォーマンスを意識してコードを書くように心がけたいと思います。