Skip to content

Latest commit

 

History

History
90 lines (68 loc) · 4.42 KB

patterns.adoc

File metadata and controls

90 lines (68 loc) · 4.42 KB

Patterns and Recipes

Included are a series of patterns and examples of Publishers, Subscribers, and pipelines. These examples are meant to illustrate how to use the Combine framework to accomplish various tasks.

Error Handling

Previous examples above expect that the subscriber would handle the error conditions, if they occurred. However, you are not always able to control what the subscriber requires - as might be the case if you are using SwiftUI. In these cases, you need to build your pipeline so that the output types match the subscriber types. This implies that you are handling any errors within the pipeline.

For example, if you are working with SwiftUI and the you want to use assign to set the isEnabled property on a button, the subscriber will have a few requirements:

  1. the subscriber should match the type output of <Bool, Never>

  2. the subscriber should be called on the main thread

With a publisher that can throw an error (such as URLSession.dataTaskPublisher), you need to construct a pipeline to convert the output type, but also handle the error within the pipeline to match a failure type of <Never>.

How you handle the errors within a pipeline is dependent on how the pipeline is defined. If the pipeline is set up to return a single result and terminate, a good example is Using catch to handle errors in a one-shot pipeline. If the pipeline is set up to continually update, the error handling needs to be a little more complex. In this case, look at the example Using flatMap with catch to handle errors.

UIKit or AppKit Integration

SwiftUI Integration

Testing and Debugging

The Publisher/Subscriber interface in Combine is beautifully suited to be an easily testable interface.

With the composability of Combine, you can use this to your advantage, creating APIs that present, or consume, code that conforms to Publisher.

With the publisher protocol as the key interface, you can replace either side to validate your code in isolation.

For example, if your code was focused on providing its data from external web services through Combine, you might make the interface to this conform to AnyPublisher<Data, Error>. You could then use that interface to test either side of that pipeline independently.

  • You can mock data responses that emulate the underlying API calls and possible responses, including various error conditions. This might include returning data from a publisher created with Just or Fail, or something more complex using Future. None of these options require you to make actual network interface calls.

  • Likewise you can isolate the testing of making the publisher do the API calls and verify the various success and failure conditions expected.