Home > Software engineering >  Swift Combine: combining two calls to create a new output
Swift Combine: combining two calls to create a new output

Time:12-09

Let's say there is a struct with such definition:

struct CustomData {
    let data1: Int
    let data2: String
}

There we have these two methods:

func getInt() -> AnyPublisher<Int, Error> {
    return Just(Int.random(in: 0...100))
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
}

func getString() -> AnyPublisher<String, Error> {
    return Just("\(Int.random(in: 200...400))")
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
}

Is it possible to use Combine to get the output of these functions and create an object of type CustomData in a chain of calls?

CodePudding user response:

You may want to look at the various combine and merge calls. For example, using combineLatest:

struct ContentView: View {
    
    @State var result: CustomData?
    @State var cancellable: AnyCancellable?
    
    var body: some View {
        VStack {
            if let result {
                Text("result: \(result.data1) \(result.data2)")
            }
        }
        .onAppear {
            cancellable =
                getInt()
                .combineLatest(getString())
                .tryMap {
                    CustomData(data1: $0, data2: $1)
                }
                .sink(receiveCompletion: { err in
                    //
                }, receiveValue: { customData in
                    self.result = customData
                })
        }
    }
    
    struct CustomData {
        let data1: Int
        let data2: String
    }
    
    func getInt() -> AnyPublisher<Int, Error> {
        return Just(Int.random(in: 0...100))
            .setFailureType(to: Error.self)
            .eraseToAnyPublisher()
    }

    func getString() -> AnyPublisher<String, Error> {
        return Just("\(Int.random(in: 200...400))")
            .setFailureType(to: Error.self)
            .eraseToAnyPublisher()
    }
}
  • Related