Extending Combine in Swift.

Tram Ho

  • Combine allows us to set up asynchronous processes as separate threads in which each thread has different operation . Individual processing streams can be observed , transforned , conbined in a variety of ways and can all be processed with high degree of safety and checked in compile time .
  • strong type validation is very useful when we are working on extending func in Combine because we can make changes depending on the out put we need.

1 / Inserting default arguments:

  • Although Combine has provided us with a lot of operation transform , sometimes we still need to customize the API to be used most conveniently during development. A typical example is when we work more with protocol Publisher with type Output and Failure then we need to know exactly what kind of type that publisher requirements:
  • The operation decode is used to transform the Data value emit when the publisher uses Decodeable . This operation however requires us to always pass the type we need to decode . We need to make a small customization here so we can automatically add us the values ​​needed for the decode work like:

  • One point to note is to change the .init() to the JSONDecoder instance used throughout the app. For example, when working with the web API where we download json from snake_case , we want to replace the snakeCaseConverting instance as the arguments decoder :

  • With the above change in the 2 extension we can now use .decode() to decode JSON every time the compiler allows to suggest the desired output type :

  • Operation decode is really useful when we can fully customize and specify the type we want for the output :

2 / Data validation:

  • Next we will find out what we can do to extend the dedicated API for data validation . If we want each of the loaded NetworkResponse instance contain at least 1 Item . We can add API using tryMap operator to handle error if any:

  • We can also add the above code on a validate operator for the workflows previously in Combine and can handle the error classification for empty array items as follows:

  • Another method to validate data in swift is to unwrapping optionals via the Combine operator compactMap so that you can ignore nil values ​​instead of throwing an error when processing doesn’t need to return a result. But if we want to show the error in the cases we can customize it like so:

  • The use of the unwrap operator is that when we are loading another collection of Item from recentItems and we only need the first element then we do the following:

3 / Result conversions:

  • The most common way to handle output from Combine is to use a sink operator with 2 closure , one for handling each output value and the other for completion event .
  • However, when it comes to successful processing of the output and completion separately, it sometimes brings with us certain inconveniences. In this case emit a single Result value is a great way for us to proceed with custom operator :

  • The new operator convertToResult takes advantage of its advantage when using the build viewmodel for SwiftUI view. We will now use pre-loaded item in the ItemListViewModel to use for the new operator to be able to switch to Result for each loading operation :

  • Continuing to dig deeper we will update the view model using the LoadableObject protocol and the LoadingState enum. We start to add custom operators to emit LoadingState value instead of using the Result :

  • The above change makes it easy to load and assign state to the viewmodel as follows:

4 / Type-erased constant publishers:

  • Sometimes we want to create a publisher that emit only one value or error using Just or Fail . However, when using these publisher , they also have to implement attached operators such as setFailureType and eraseToAnyPublisher :

  • Next let’s extend AnyPublisher with two static methods, one for type-erased Just creation and one for Fail publisher:

  • Now we can use Swift “dot syntax” to create constant publisher with one line of code like this:

Share the news now

Source : Viblo