Help us understand the problem. What is going on with this article?

JINS MEMEのデータをxx秒おきにGoogle SpreadSheetに流す

More than 3 years have passed since last update.

What's JINS MEME

こちらをご参考ください。
http://qiita.com/mito_log/items/020a87996ed2b9d793e6

Motivation

JINS MEMEを使って何か作るにもデータの傾向を見たり分析してからでないとなぁ。ということでxx秒ごとにgoogle spread sheetに投げてデータを見てみます。今回も前回に引き続きRxSwiftで頑張っております。

github

https://github.com/mitolog/JINSMEMESampler

Spreadsheet

https://docs.google.com/spreadsheets/d/196kFM695twoL4b_a8dv-4AKrBZQW4jJk9MqcQyCgf4g/edit?usp=sharing

Screenshots

iPhone
MEME_spreadsheet_iphone.png

spreadsheet
MEME_spreadsheet_spreadsheet.png

How it works

ios側では、データを一旦配列に貯めておいて、一定時間毎にcsvでデータをpostで送信しています。

google spreadsheet側では、google app scriptのContent Serviceという機能を使い、簡単なRestfulAPI(POSTのみ)を用意しています。そこで、csvをパースして、シートに転記しています。

google apps scriptを使ったAPIについては、過去に書いた記事を見つつ作れるかと思います。注意すべきは、

  • スプレッドシート名を固有のものにすること
  • アプリの実行権限を得ること
  • ウェブアプリケーションとして導入のオプション

くらいかと思います。

Recap

Too much memory use while data retrieval and sending

今回もRxSwiftを使ってみたのですが、dispose関連のタイミングやら手法がまだカバーできていないせいか、データ取得時に大量にメモリを食ってしまっています。一応leaksでみてみるとリークは無いとの判定でしたが、工夫したいところです。

takeUntil

今回、スタート/ストップボタンを押すと、「データの取得開始、タイマーの起動」をしています。つまり、
スタート:subscribeの開始
ストップ: dispose
としたかったのですが、disposeをどうやるべきか...紆余曲折を経てtakeUntilを使う手法にたどり着きました。

takeuntil.png
画像: RxSwiftのPlaygroundより

一番上をrealtimeDataを取得するシーケンス(MEMELibAccess.sharedInstance.rx_realtimeDataReceived)、そのすぐ下を、データストップシーケンス(stopSequence)とすると、stopSequenceに何かしら次のアイテムをセットした時点で一番上のシーケンスは完了扱いとなり、disposeされます。

コード上でいくと、

MEMELibAccess.sharedInstance.rx_realtimeDataReceived
            .takeUntil(self.stopSequence)
            .subscribeNext { [unowned self] realtimeData in

というふうにせっとしておいて、その後に、stopSequence.on(.Next(true))とかしてあげればOKです。

詳しくは、GettingStartedのDisposingの箇所を見るといいかと思います。

bi-directional binding

RxSwiftで双方向データバインディングをみながらやってみました。

とても柔軟だなとおもったのは、例えばモデルがdoubleでビューがstringでもバインドできます。

view_to_model
self.intervalTextField.rx_text.subscribeNext { [unowned self] intervalStr in
    if intervalStr.utf16.count > 0 {
        self.vm.interval.value = atof(intervalStr)
    }
}.addDisposableTo(self.disposeBag)
model_to_view
self.vm.interval
    .subscribeOn(MainScheduler.sharedInstance)
    .map { interval in
        return String(interval)
    }
    .bindTo(self.intervalTextField.rx_text)
    .addDisposableTo(self.disposeBag)

mapを噛ませて、stringを返すようにすればバインドできました。

Scheduler

今回のように通信が絡んだりタイマーが絡むと、UIスレッドを意識しないといけません。RxSwiftでもスケジューラーという概念でスレッドを管理できるようになっているので、スケジューラーは要チェックです。

https://github.com/ReactiveX/RxSwift/blob/master/Documentation/Schedulers.md

1点気になったのが、ドキュメントでは、.subscribeOn(MainScheduler.sharedInstance)すればメインスレッドでsubscribeできるよみたいに書いてあったのですが、一部効かない場所があったので、dispatch_async(dispatch_get_main_queue()) {}で対応しました。

20Hz

いきなりJINS MEMEのことになりますが(ていうかほぼRxSwiftの勉強になっていますね...)、JINS MEMEのrealtimeモードでは、通信速度がBluetooth通信周期にのっとって約20Hzとなっています。
参照: https://developers.jins.com/ja/

ということは、1秒間に約20サンプルのデータがiPhoneには送られていることになり、10秒だと約200のサンプルになります。

google spreadsheetの最大セル数は、200万セルということなので、逆算すると、

2000000セル / 16(1行分のセル数) / 20サンプル = 6250秒(約104分)

は貯められることになりますが、用途としては、突発的な動作や短いスパンでの変化を分析したいときに使えるかなと思いました。

ということで、引き続きデータを見ながらどんなことができそうかを探っていきます。

mito_log
ベトナム・ハノイ拠点の個人デベロッパ。東南アジア向けに素敵なサービスと文化を作るべく模索中。ベトナムで1年半農業。newbie skateboarder、ハノイITもくもく会毎週土曜朝9時頃 → https://bit.ly/2Oe9Ehk
http://mitolab.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした