Search code examples
iosswiftswiftuitimercombine

How can I pass two args from timer.publish properties to any method Swift/Combine


I have timer method where it get called whenever new instance is created. I want every ticker should be stored in dictionary with respect to each instance like [test1: 1, test2: 1] , [test1: 2, test2: 2] ......So on. Tried below option but not able to send any values. Currently with .scan I am able to send only integer

var subscriptions = Set()
var dict = NSMutableDictionary()

func multiplecall(name: String) {
Timer.publish(every: 1, on: .main, in: .common)
.autoconnect()
.scan(1) { value, _ in value + 1 }
.sink(receiveValue: fetchValues)
.store(in: &subscriptions)
}

func fetchValues(ticker: Int){
print(ticker)

}



**Expecting something like this**
    func fetchValues(testName: String, ticker: Int){
    dict[testName] = ticker
    }

multiplecall(name: "test1")
multiplecall(name: "test2")

Solution

  • You don't need to do anything super special here. Instead of passing fetchValues to sink, pass a closure:

    .sink(receiveValue: { value in
        fetchValues(testName: name, ticker: value)
    })
    

    or simply:

    .sink { value in
        fetchValues(testName: name, ticker: value)
    }
    

    Here is a complete code that prints the dictionary after publishing the first 5 values:

    var subscriptions = Set<AnyCancellable>()
    var dict = [String: Int]()
    
    func multiplecall(name: String) {
    Timer.publish(every: 1, on: .main, in: .common)
        .autoconnect()
        .scan(1) { value, _ in value + 1 }
        .prefix(5)
        .sink { _ in
            print(dict)
        } receiveValue: { value in
            fetchValues(testName: name, ticker: value)
        }
        .store(in: &subscriptions)
    }
    
    func fetchValues(testName: String, ticker: Int){
        dict[testName] = ticker
    }
    
    multiplecall(name: "test1")
    multiplecall(name: "test2")
    

    Output:

    ["test1": 6, "test2": 5]
    ["test1": 6, "test2": 6]
    

    Note that the first line is produced from the first publisher completing. At this point test2 has not completed yet. That's why it's "test2": 5.