Search code examples
objective-cswiftreactive-cocoa

Transform an array of value with async function and Reactive-Cocoa


I have an array of String and I want to modify it by calling an asynchronous function on each value.

I tried something but it's just creating a RACSequence of RACSignal and not an array of modified String

func modifyValueAsynchronously(inputValue: String, completion: (String -> Void)) -> RACSignal  {
    return RACSignal.createSignal() { subscriber in
        doAServerCall(inputValue) { outputValue in
            subscriber.sendNext(outputValue)
        }
    }
}

let value: NSArray = ["a", "b"]

let result = value.rac_sequence.map({ value in
    return self.doRequest(value as! String)
})

Solution

  • As you said, you want to perform an asynchronous function on each of your string values in array. Because of the fact that you do it async, the final result will also arrive asynchronous. After getting RACSequence of RACSignal, you want to wait until each signal provides you with value and then gather it all into array.

    let transformation = { (input: String) -> RACSignal in
            return RACSignal.createSignal { subscriber in
                subscriber.sendNext(input + "a")
                return nil
            }
        }
    
        let array: NSArray = ["a", "b", "c", "d"]
    
        let sequence = array.rac_sequence.map({ (element) in
            return transformation(element as! String)
        })
        RACSignal.combineLatest(sequence).subscribeNext { (element) in
            let array = (element as! RACTuple).allObjects()
            print("Elements from array \(array) \n")
        }
    

    Lets take this example. Transformation closure will asynchronously add an 'a' letter to each string. After creating a sequence, I add combineLatest operator which will give me result as soon as each element from sequence provides me with it's result. As soon as I get all results, I get a RACTuple inside subscribeNext method and I can make an array out of it.