0
0

[Swift]Combine .sink, .store, .assign

Last updated at Posted at 2024-01-17

目次

1.SwiftCombineとは
2.sink
3.store
4.assign
5.おわりに

1. SwiftCombineとは

我からApple様が提供する純正フレームワークで、データバインディング機能を実現します。
サードパーティのRxSwiftのApple純正版とも言えるでしょう。

2. sink

info RxSwiftでいうところのsubscribeとも言えます。

  • 前提条件: subscriptionはAnyCanellabel型であること
  • receiveCompletion: 実行状態を受け取る(成功失敗の受け取り)
  • receiveValue: 実行の戻り値を受け取る
combineViewController
import UIKit
import Combine

let subject = PassthoughSubject<String, Never>() //<受信する型、返信する型>

class ViewController: UIViewContoroller {
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let cancellable = subject
        .sink(receiveConpletion: { completion in
            print("値の受け取りが完了しました:\(completion)")
            }, receiveValue: { value in
                print("受け取った値は:\(value)")
            })

        // イベントの送信
        subject.send("1")
        subject.send("1")
        subject.send("1")
        subject.send("1")
        subject.send("1")
        subject.send(completion: .finished) //イベントの終了
    }
}

実行結果

受け取った値は:1
受け取った値は:2
受け取った値は:3
受け取った値は:4
受け取った値は:5
値の受け取りが完了しました: finished

3. store

複数のSubscriptionをまとめて保持することもできます。

Set<AnyCancellable>()を使用することによってまとめることができます。
具体的には、.store(in: &(Set先のsubscription))を使用します。

StoreViewController
import UIKit
import Combine

// イベントの送受信を仲介
// イベントは「文字列を渡して表示させる」というもの
public let subject = PassthroughSubject<String, Never>()   // <受信する型, 返信する型>

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // イベントの送信
        let receiver = Receiver()
        subject.send("1")
        subject.send("2")
        subject.send("3")
        subject.send("4")
        subject.send("5")
        subject.send(completion: .finished)   // イベント終了を送信

    }
}

class Receiver {

    var subscriptions = Set<AnyCancellable>()
    
    init() {
        // ひとつ目の受け取り
        subject.sink{ value in
            print("First Subscription:\(value)")
        }
        .store(in: &subscriptions)

        // ふたつ目の受け取り
        subject.sink{ value in
            print("Second Subscription:\(value)")
        }
        .store(in: &subscriptions)
    }
}

実行結果

First Subscription:1
Second Subscription:1
First Subscription:2
Second Subscription:2
First Subscription:3
Second Subscription:3
First Subscription:4
Second Subscription:4
First Subscription:5
Second Subscription:5

4. assign

クラス変数への代入を行います

.assign(to: \.(代入先の変数名), on: (代入先のクラス名)を使いクラス変数に代入できます。

assignViewController
public let subject = PassthroughSubject<String, Never>()   // <受信する型, 返信する型>

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // イベントの送信
        let receiver = Receiver()
        subject.send("1")
        subject.send("2")
        subject.send("3")
        subject.send("4")
        subject.send("5")
    }

}

class Receiver {
 var subscriptions = Set<AnyCancellable>()

     init() {
         subject
             .assign(to: \.value, on: SomeObject())
             .store(in: &subscriptions)
     }
}

class SomeObject {
    var value: String = "" {
        didSet {
            print("didSet Value: \(value)")
        }
    }
}

実行結果

disSet Value: 1
disSet Value: 2
disSet Value: 3
disSet Value: 4
disSet Value: 5

5. おわりに

RxSwift->Combineに書き換えていく途中ですが、純正って響きが良いですよね〜
本記事を読んでいただきありがとうございました!

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