Is there a way to simplify Swift combine types?
You would just call eraseToAnyPublisher()
on the result.
Combine uncollect operator?
You can use flatMap
together with a new publisher
[1,2,3,4,5,6].publisher
.collect()
.flatMap { $0.publisher }
.sink { print($0) }
1
2
3
4
5
6
How Can I Flatten An AnyPublisherAnyPublisher?
This line .map { (arg) -> AnyPublisher<[T], LoadingError> in
needs to be a flatMap
.
Using Just with flatMap produce Failure mismatch. Combine
There is special operator setFailureType(to:)
. You can override failure type to whatever error type you need.
func request(request: URLRequest) -> AnyPublisher<Data, Error> {
return Just(request)
.setFailureType(to: Error.self)
.flatMap { request in
RequestManager.request(request) // returns AnyPublisher<Data, Error>
}
.eraseToAnyPublisher()
}
https://developer.apple.com/documentation/combine/just/3343941-setfailuretype
Mapping Swift Combine Future to another Future
You can't use dribs and drabs and bits and pieces from the Combine framework like that. You have to make a pipeline — a publisher, some operators, and a subscriber (which you store so that the pipeline will have a chance to run).
Publisher
|
V
Operator
|
V
Operator
|
V
Subscriber (and store it)
So, here, getItem
is a function that produces your Publisher, a Future. So you can say
getItem (...)
.map {...}
( maybe other operators )
.sink {...} (or .assign(...))
.store (...)
Now the future (and the whole pipeline) will run asynchronously and the result will pop out the end of the pipeline and you can do something with it.
Now, of course you can put the Future and the Map together and then stop, vending them so someone else can attach other operators and a subscriber to them. You have now assembled the start of a pipeline and no more. But then its type is not going to be Future; it will be an AnyPublisher<NSImage,Error>
. And there's nothing wrong with that!
Swift Combine transform an array of publishers
The general approach is to flatMap
the array into a Sequence
publisher of individual values, then do any async operations on each value (another flatMap
), then collect
the results:
HKHealthStore()
.workouts(HKObjectQueryNoLimit)
.flatMap { workouts in workouts.publisher }
.flatMap { workout in
workoutDetails(workout)
}
.collect()
.sink(
receiveCompletion: { ... },
receiveValue: { arrayOfWorkoutDetails in
// arrayOfWorkoutDetails is of type [WorkoutDetails]
})
.store(in: &bag)
Using flatMap in RestManager with generic function not working
There are several major flows in your implementation.
Firstly, you shouldn't be using Result
as the Output
type of the Publisher
and Never
as its Failure
type. You should be using T
as the Output
and ErrorType
as Failure
.
Second, you need tryMap
and mapError
, not flatMap
.
Lastly, you are handling the result of dataTaskPublisher
completely wrong. When dataTaskPublisher
fails, it emits an error, so you need to handle that in mapError
. When it succeeds, it emits its result as data
, so you need to be decoding that, not response
.
func fetchData<T: Decodable>(url: URL) -> AnyPublisher<T, ErrorType> {
URLSession
.shared
.dataTaskPublisher(for: url)
.tryMap { data, _ in
return try JSONDecoder().decode(T.self, from: data)
}
.mapError { error -> ErrorType in
switch error {
case let urlError as URLError:
switch urlError.code {
case .notConnectedToInternet, .networkConnectionLost, .timedOut:
return .noInternetConnection
case .cannotDecodeRawData, .cannotDecodeContentData:
return .empty
default:
return .general
}
default:
return .general
}
}
.eraseToAnyPublisher()
}
Related Topics
Auth.Auth().Currentuser.Reload() Doesn't Refresh Currentuser.Isemailverified
What Does the Underscore in a Function Declaration Do
Getch() Equivalent in Swift: Read a Single Character from Stdin Without a Newline
Using Tvposterimage in Tvuikit for Tvos 12
How to Set Cadisplaylink in Swift with Weak Reference Between Target and Cadisplaylink Instance
Swift Spritekit 3D Touch and Touches Moved
Codable Decode Property with Multiple Object Types Based on Another Value
Update Firebase Multi-Location with Error: Path Is an Ancestor of Path. Swift
"Unexpectedly Found Nil While Unwrapping an Optional Value" When Retriveing Pffile from Parse.Com
Swift Function Compiler Error 'Missing Return'
Aws - Unauthenticated Access Is Not Supported for This Identity Pool in Swift
Swift Cannot Output When Using Nstimer
Swift: Ambiguous Reference to Member 'Map'
How to Decrease a Value Using Fieldvalue in Firestore (Swift)
How to Convert Unix Timestamp into Swift Nsdate Object
How to Get All Characters of the Font with Ctfontcopycharacterset() in Swift
How to Ensure Make Sure I'm Not Accessing Data Until It's Loaded In