Search code examples
swiftcombine

Add explicit type to flatmap


When uncommenting the code in the following code block I get the following error.

Cannot infer return type for closure with multiple statements; add explicit type to disambiguate

But I can't figure out the syntax for explicitly adding a type. How do I do it?

let path:String = path ?? Self.path
let publisher: AnyPublisher<[Self]?, Error> = NetworkableManager.getAll(path: path) 
    .flatMap {
//     if path == "menus" {
//        print("It's a menu")
//     }
       return StorableManager.shared.saveAll($0)
                
    }
    .merge(with: StorableManager.shared.fetchAll(predicate: filters))
    .eraseToAnyPublisher()


Solution

  • You didn't provide a whole lot of information about the classes involved so I mocked something up to create the playground example below.

    The bit that I have added is in the closure of the flatmap operator. Basically I told the compiler what type that closure will return using the fragment input -> Future<[String], Error>. To come up with that line I had to know the return type of StorageManager.shared.saveAll(items: input) so I used the value my mocked up sample returns.

    Your return value may be different.

    import Foundation
    import Combine
    
    class StorageManager {
        static let shared = StorageManager()
    
        init() {
        }
    
        func saveAll(items: [String]) -> Future<[String], Error> {
            Future<[String], Error> { fulfill in
                    fulfill(.success(items))
            }
        }
    }
    
    struct NetworkManager {
        static func getAll(path: String) -> Future<[String], Error> {
            Future<[String], Error> { fulfill in
                fulfill(.success(["Duck", "Cow", "Chicken"]))
            }
        }
    }
    
    let path : String = "some path"
    let publisher : AnyPublisher<[String], Error> =
        NetworkManager.getAll(path: path)
            .flatMap { input -> Future<[String], Error> in
    
                 if path == "menus" {
                    print("It's a menu")
                 }
    
                return StorageManager.shared.saveAll(items: input)
            }
            .eraseToAnyPublisher()