0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Swift] [Combine] measureInterval(using:)を使って出力の間隔を取得する

Posted at

measureInterval(using:)

Combine には measureInterval(using:) という Publisher の出力の間隔を取得することができる関数が用意されているのでそれを紹介してみたいと思います。

サンプルコード

挙動はサンプルコードを見ていただくのが早いと思います。

まずは以下のような一定間隔で出力してくれる Publisher を用意します。

import Combine
import Foundation

var cancellables = Set<AnyCancellable>()
let timerPublisher = Timer.publish(every: 2, on: .main, in: .default)
    .autoconnect()
    .share()

適当に subscribe すると以下のような出力になります。

timerPublisher
    .sink { output in
        print("timerPublisher: \(output)")
    }
    .store(in: &cancellables)

// timerPublisher: 2022-02-05 11:14:17 +0000
// timerPublisher: 2022-02-05 11:14:19 +0000
// timerPublisher: 2022-02-05 11:14:21 +0000

ここで、measureInterval(using:) を間に噛ませると以下のようになります。

timerPublisher
    .measureInterval(using: RunLoop.main)
    .sink { output in
        print("measureInterval: \(output)")
    }
    .store(in: &cancellables)

// measureInterval: Stride(magnitude: 2.0009289979934692)
// measureInterval: Stride(magnitude: 1.9993009567260742)
// measureInterval: Stride(magnitude: 1.9998070001602173)

measureInterval(using:) を間に噛ませることで、時刻 から 時間間隔 に変更されていることがわかります。

timerPublisher
    .measureInterval(using: RunLoop.main)
    .sink { output in
        print("measureInterval: \(output)")
    }
    .store(in: &cancellables)

// measureInterval: Stride(magnitude: 0.20106804370880127)
// measureInterval: Stride(magnitude: 0.1994309425354004)
// measureInterval: Stride(magnitude: 0.19979500770568848)

さらに collect() を間に噛ませて、ちょっとした関数を当ててあげるだけで、出力の間隔の平均を表すこともできます。

func averageInterval(strides: [RunLoop.SchedulerTimeType.Stride]) -> Double {
    let sum = strides.map { $0.timeInterval }.reduce(0, +)
    return Double(sum) / Double(intervalValues.count)
}

timerPublisher
    .measureInterval(using: RunLoop.main)
    .collect(10)
    .map { averageInterval(strides: $0) }
    .sink { output in
        print("output average interval(s): \(output)")
    }
    .store(in: &cancellables)

// output average interval(s): 2.0000609040260313

以上になります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?