I've been struggling to find an equivalent for reduce(into:_:) in Combine.
enum GenericError : Error {
case with(message: String)
}
class Constants {
fileprivate static let scheme = "sampleScheme"
fileprivate static let host = "com.sampleHost"
fileprivate static let authPath = "/auth"
static let authQuery = "key"
}
func parse(_ url: URL, queryPathsFilterByKey: [String]) throws -> [String: String] {
guard url.scheme == Constants.scheme,
url.host == Constants.host,
url.path == Constants.authPath,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = urlComponents.queryItems else {
throw GenericError.with(message: "Invalid deep link.")
}
// Create a [String:String] from [UrlQueryItems]
let query = queryItems.reduce(into: [:]) { result, item in
result[item.name] = item.value
}
let result = query.filter { queryPathsFilterByKey.contains($0.key) }
guard !result.isEmpty else {
throw GenericError.with(message: "Error parsing query Items (deep linking)")
}
return result
}
what operator replaces reduce(into:) in Combine?
Found a way to do this
func parse(_ url: URL, queryPaths: [String]) -> AnyPublisher<[String: String], GenericError> {
guard url.scheme == Constants.scheme,
url.host == Constants.host,
url.path == Constants.authPath,
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = urlComponents.queryItems else {
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Invalid deep link"))
.eraseToAnyPublisher()
}
return queryItems
.publisher
.reduce ([String:String]()) { dictionary, value in
var dict = dictionary
dict[value.name] = value.value
return dict
}
.filter { $0.allSatisfy { queryPaths.contains($0.key) } }
.flatMap { dictionary -> AnyPublisher<[String:String], GenericError> in
if(dictionary.isEmpty)
{
return Fail(outputType: [String:String].self, failure: GenericError.with(message: "Error parsing query Items (deep linking)"))
.eraseToAnyPublisher()
} else {
return Just(dictionary)
.setFailureType(to: GenericError.self)
.eraseToAnyPublisher()
}
}
.eraseToAnyPublisher()
}
Not sure if this is the best way but worked.