TrueTimeは、SwiftとAndroid用のNTPライブラリです
Instacartのshoppersから聞いた共通の苦情は、彼らが通路にいる際、ネットワークの接続が弱いという状況が頻繁に起きているということです。
私たちは、アプリを使ってshoppersに力を与え、注文をすばやく満たすために必要なすべてのツールを提供しようとします。 スポットネットワーク(Spotty network)接続は大きな問題です。
この一連のブログ記事では、shopper向けのアプリをオフラインで動かすことで、わが社のアイデアや学習の一部を分かち合い、shopper向けのアプリをAPIのファーストクラスのパートナーにしていきたいと考えています。これからご紹介します:
Part 1: Introducing TrueTime (TrueTimeの紹介)
Part 2: Batch Processing Requests (バッチ処理要求)
Part 3: Tighter Instrumentation (より厳しい計装)
では、クライアントアプリケーションとサーバーとの間の不自然なネットワーク接続の問題をどのように解決するのでしょうか?シンプル!信じられないほど簡単な目的で、ロジックをクライアントに移します。私たちは、その目標を達成するための最初のソリューションの1つを共有したいと考えています。
TrueTimeを紹介
このデバイスは現在、信頼できる情報源と考えられています。 これには、リクエストとともに送信される時間も含まれます。実際の処理が数分前に行われた可能性があるため、サーバーがAPIリクエストを受信した時刻を信頼できなくなります。 現在の時刻が必要な場合は、デバイスに尋ねてそれを信頼する必要があります。
あなたのデバイスの日付と時刻を変更しましょう。 今度は、新しいDate()またはNSDate()を初期化してみてください。 そうすると日時の変化を反映します。 ユーザーのタイムゾーンや時計の調整に影響されない時間を得る簡単な方法はないですが、iOSとAndroidのどちらもこの機能を提供していないことに驚くかもしれません。
ユーザーはさまざまな理由でこれを行うためです。たとえば、異なるタイムゾーンにいるか、時計を5分早く設定して時間を守るかなどです。 合理的な精度を達成するためにNTPを使用している多くの電話機にもかかわらず、電話機はまだ数分間ドリフトしているという事実もあります。
わずか1時間でお客様への配送を可能にするInstacartでは、毎分が重要です。 顧客が注文する時間、shoppersが注文を開始する時刻、配送ドライバがそれを受け取る準備が整ったとき、保証された高精度で追跡する必要があります。 私たちは共通の基準時間を必要とします。 デバイスのカスタマイズや変更に影響されません。私たちは今日、AndroidとiOSの両方でTrueTimeを公開しています。
TrueTimeはどのように時間を計算しますか?
私たちは、NTPサーバーのプールに対してネットワーク(SNTP)リクエストを作成し、アプリケーションとのセッションの開始時に一度だけ実際の時刻を決定します。 次に、デバイスの稼働時間とネットワーク要求からの応答との間にデルタを設定します。 その後、毎回、そのオフセットが要求され、修正されたDateオブジェクトが返されます。
使用法
私たちはAPIをできる限りシンプルに保つように努めました。
Android
// at an opportune time (e.g. app start):
TrueTime.build().initialize();
// or the Rx version
TrueTimeRx.build().initializeRx(“time.apple.com”)
.subscribeOn(Schedulers.io())
.subscribe(date -> {
Log.v(TAG, “TrueTime was initialized at: %s” + date);
}, throwable -> {
Log.e(TAG, “TrueTime init failed: “, throwable);
});
// you can now use this instead of your traditional new Date();
Date myDate = TrueTime.now();
iOS / Swift
// At an opportune time (e.g. app start):
let client = TrueTimeClient.sharedInstance
client.start()
// You can now use this instead of NSDate():
let now = client.referenceTime?.now()
Head over to the usage section to get more of the juicy details: Android, iOS.
もっと詳しく情報を知るため、次のセクションに進めていきましょう:Android、iOS。
プラットフォーム実装の詳細
Android
TrueTimeのバニラバージョンを追加すると、次のような基本的な公式が得られます。
compile‘com.github.instacart.truetime-android:library:<release-version>’
しかし、我々は基本的なTrueTimeライブラリにRxJavaの拡張機能も追加しました。 これを使用したい場合は、代わりにこのインポートを使用してください:
compile ‘com.github.instacart.truetime-android:library-extension-rx:<release-version>’
Jitpackとgradleを使用した正確なインストールの詳細については、instructionsをご覧ください。
Rx拡張が許すいくつかの賢い技があります:
•複数のSNTPホストを利用してUDPリクエストを撃退することができます。
•これらのUDPリクエストは、パラレルで実行されます(3つの並列呼び出しの制
限があります)。
•SNTPリクエストの1つが失敗すると、失敗したリクエストを単独で何回(数回)も再試行します。
•いずれかのホストから返されるとすぐに、最初の応答を取り、他のすべてのリクエストを終了します。
iOS / Swift
Carthageを使ってTrueTimeを含めることができます:
github “instacart/TrueTime.swift”
現在、iOS 8以降、macOS 10.9、tvOS 9(Linuxのサポート予定もあります)に対応しています。 いくつかのメモ下記のようになります:
・NSDatesはUNIXのタイムスタンプにすぎないので、ReferenceTime.now()によって返された値を保持するか、あとで調整することなくディスクに保持すると安全です。
・Reachability eventsは、リクエストを一時停止/開始するために自動的に考慮されます。
・UDPリクエストはパラレルで実行され、デフォルトの制限は3並列呼び出しです。 もし1つ失敗した場合があったら、デフォルトで最大5回まで再試行できます(します)。
私たちはInstacart❤️ open source。 TrueTimeを改善できると思うなら、私たちはあなたのPRをGitHub:Android, iOSに載せたいと思っています。
ああ! この種のソリューションに興味があるなら、是非一度私たちに相談してください! 私たちは、こうした問題を解決できるmobile engineersを探しています。
同様の課題を抱えていたLyftの友人に感謝します、最近、iOS向けの同様のクールなソリューションを思いつきました。彼らの解決策もチェックしてください!
タイトル:Offline First: Introducing TrueTime for Swift and Android
作者:Kaushik Gopal
原文URL:https://tech.instacart.com/offline-first-introducing-truetime-for-swift-and-android-15e5d968df96