Morniak
Morniak

Reputation: 998

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)
})

Upvotes: 1

Views: 325

Answers (1)

Eluss
Eluss

Reputation: 522

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.

Upvotes: 2

Related Questions