【Swift】TimerをCombineで実装する方法!publishメソッド

この記事からわかること

  • SwiftTimerCombine実装する方法
  • publishメソッド使い方
  • 任意秒数ごとに処理実行するには?
  • scheduledTimerとの違いメリット

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

公式リファレンス:Replacing Foundation Timers with Timer Publishers

環境

TimerをCombineで実装する方法

任意の秒数ごとに処理を実行する機能を実装するためにはTimerクラスのscheduledTimerメソッドを使用します。

let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in
    print("TIMER")
})

おすすめ記事:【Swift UIKit】ストップウォッチタイマーの実装方法!Timerクラスの使い方

これをCombineフレームワークのpublisherで実装することができるようになっています。publisherとして実装することでオペレーター(流れてきたPublisherに処理を施してPublisherを再生成)を活用できるようになりデータの操作がしやすくなります。

Timer.publishメソッド

公式リファレンス:Timer.publishメソッド

publisherにするにはTimerクラスのpublishメソッドを使用して実装します。

static func publish(
    every interval: TimeInterval,   //  時間間隔
    tolerance: TimeInterval? = nil, //  許容されるタイミングの差異
    on runLoop: RunLoop,            //  タイマーが実行される実行ループ
    in mode: RunLoop.Mode,          //  タイマーを実行する実行ループモード
    options: RunLoop.SchedulerOptions? = nil // タイマーに渡されるスケジューラ オプション
) -> Timer.TimerPublisher

引数にはループで実行したい秒数をTimeInterval(Double)型で渡します。作成されたパブリッシャーをアクティブにするにはautoconnectメソッドを実行します。これでイベントが流れ出すのでsinkメソッドで実行したい処理を定義していきます。

var timerPublisher: AnyCancellable?

timerPublisher = Timer.publish(every: 0.1, on: .current, in: .common)
    .autoconnect()
    .sink { _ in
        print("TIMER")
    }

スレッドを変更する

タイマーで実装した処理のスレッドを変更するにはreceiveメソッドの引数にDispatchQueueクラスを渡します。例えばプライベートキューのバックグラウンドスレッドで実行したい場合は以下のようになります。

timerPublisher = Timer.publish(every: 0.1, on: .current, in: .common)
    .autoconnect()
    .receive(on: DispatchQueue(label: "subthread", qos: .background))
    .sink { _ in
        print("TIMER")
    }

オペレーターを使用する

Combineで実装するメリットであるオペレーターを使用して実装する例を見てみます。mapを使用することで流れてくる値を操作して表示させています。。

var timerPublisher: AnyCancellable?
timerPublisher = Timer.publish(every: 0.1, on: .current, in: .common)
    .autoconnect()
    .map { _ in
        return Int.random(in: 1...100)
    }
    .map { value in
        return value * 2
    }
    .sink { value in
        print("今回の値は: \(value)")
    }

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index