Wantedly Engineer Blog

Wantedly 開発チームブログ

Wantedly Engineer Blogは移転しました

エンジニアのshingtです。このblogを書くのは2年前にNeo4jの記事を書いて以来ですね。

さて、時期を少し逃してしまった感がありますが、3月にWantedlyのApple Watch用アプリをこっそりリリースしました。

このアプリには少し変わった機能として “Wantedly上に登録された企業が近くにある際に、その企業を通知・表示する” というものを入れています。(注: 通知候補は一部の企業様のみとなっております。)

設計としても多少変わったものになったため、簡単にですがここで紹介します(自分の備忘録も兼ねて)。なお、watchOS 2、iOS9上での開発です。

機能について

前述のように、このWatchアプリではユーザの近くにある企業を通知/表示することができます。 このフローは大きく分けて2つ存在しており、画面遷移は以下のようになっています。 通知もしくは起動時の画面から、最終的には同じ位置情報を表示する画面に行き着く、という構成です。

メッセージが確認できる画面等もありますが、機能としてはそれくらいで、watchOSのドキュメントやairbnbのblogなどで言われるように、本体アプリの“Lightweight Extension"となるような機能に留めつつ、watchらしい体験も組み込んだという形です。

位置情報取得周りのフロー

上の図の通り、このアプリでは位置情報をユーザが確認するフローが2つ存在しています。

  • フローA: 通知経由の場合
  • フローB: ユーザが自らアプリを起動した場合

フローA: 通知経由の場合

前提としてこのアプリの通知は頻繁に送る類のものではありません。 そのため、CLLocationManagerにおけるSignificant Location Changeが検出されたタイミングで、一定条件を満たしている場合のみ通知を送信する、という方針を選択しました。

シーケンス図として正確ではありませんが、大まかな流れは以下のようになります。

位置情報画面に移動してからは、watchOSのCLLocationManagerが持つrequestLocationを利用してiOS側に位置情報を問い合わせ、定期的に画面中の距離情報や地図をアップデートします。 (Apple WatchにはGPSが内蔵されていないため、iOS側に問い合わせない限り位置情報を得ることはできません。)

この際の位置情報取得はiOS側で引き続き行い、それをwatchOS側で渡す流れにすることも可能でした。 そうしなかったのは以下の理由からです。

  • requestLocationを利用すればそれ以降の位置情報に関するコードはwatchOS側で完結させることができる
  • 要件としてCLLocationManagerの精度としては最高のもの(kCLLocationAccuracyBestForNavigation)を利用する必要があり、例えばハンドリングのバグ起因でiOS側で位置情報の取得が誤って行われている(= iOSデバイスのバッテリーの消費が大きくなってしまう)という状況は絶対に避けたかった

あくまでwatchOSアプリはエクステンションと捉えており、iOSアプリ側に影響が出ることは基本的に無いように設計していました。もちろん、Apple Watchとのペアリングが行われていない端末であれば、そもそも位置情報の取得許可を得ることもありません。

フローB: ユーザが自らアプリを起動した場合

こちらはユーザが通常通りApple Watch上でアプリを起動したケースです。

先ほどよりやや複雑ですね。一度近くの企業情報を取得した後の挙動はプロセス1の場合と同様です。

当初はwatchOSがiOSに対してrequestLocationを発行し、その結果を受け取った後、再度近くの企業を取得するリクエストを発行するという方針で考えていました。 しかしこの場合、コードとしては単純に記述できるものの、watchOS <=> iOS間のやり取りが上記の図よりも余分に一度増えてしまいます。

そのためwatchOSからiOSへの問い合わせについて、図のようにWCSessionを利用して近くの企業自体をリクエストするようにし、現在地の取得はiOS上で行うようにしました。WCSessionはデバッグし辛かったりシミュレータ上で不安定だったりと少し扱い辛くもありましたが、実機上ではある程度安定していたように思います。

Local Notification / Remote Notificationの扱い

watchアプリについて、Xcode上でUIRemoteNotificationを簡単にデバッグすることができる仕組みが用意されていますが、UILocalNotificationについてはその限りではありません。

UIRemoteNotificationUILocalNotification用の共通のラッパーを用意し、基本的に必要な処理はそのラッパーオブジェクトを通して行い、UILocalNotificationであってもシミュレータ上で挙動確認ができるようにしていました。 こちらに関してはpotatotips #28で紹介しましたので、以下スライドを参照して頂ければと思います。

まとめ

WantedlyのApple Watch用アプリに関して、主に位置情報制御と通知周りに関して簡単に紹介しました。 Apple Watchと言えば先日、今年の6月以降にsubmitするアプリについてはwatchOS 2以降のSDKを利用しなければならないとのアナウンスがありました(参考: Upcoming Requirement for watchOS Apps)。

今年のWWDCで何かしらのアップデートもあるでしょうし、何だかんだでwatchOS <=> iOS間の通信の制御は楽でもないので、この辺りが実装しやすくなることを個人的には期待したいです。

ということで、Watchアプリも付属しているWantedlyのiOSアプリは以下からダウンロードできます。ぜひぜひお試し下さい。

Wantedly - 転職に使える会社訪問求人アプリ

We are hiring

WantedlyではwatchOS、iOSに限らず、多分野のエンジニアを募集しています。興味のある方はぜひ話を聞きに来て下さい。


Wantedly Engineer Blogは移転しました

このエントリーをはてなブックマークに追加