-
Notifications
You must be signed in to change notification settings - Fork 12
Debugging
This page will give you some tips for debugging the Diffuser and Fuser. We hope these tips prove useful, but please note that the most effective way to debug them - and to prevent bugs in the first place - is to understand how they work. Our Diffuser and Fuser overviews should give you this knowledge.
Diffusers are often made up of several higher-order functions. The most effective way to debug them is to just break things down.
Consider the following Diffuser:
let diffuser: Diffuser<Model> = .intoAll(
.map(\.title, .intoText(view.titleLabel)),
.map(\.subtitle, .intoText(view.subtitleLabel))
)Here we are decomposing the Model type. We map its title field into our view's titleLabel, and the its subtitle into our view's subtitleLabel.
Let's take this thing apart by expanding our functions:
let diffuser: Diffuser<Model> = .intoAll(
.map(
{ (model: Model) in model.title }, /* --> model.title is being passed into... */
/* ...--> */ .into { (title: String) in view.titleLabel.text = title }
),
.map(
{ model in model.subtitle },
.into { subtitle in view.subtitle.text = subtitle }
)
)By taking things apart, you also gain the ability to set break points which should give you a clearer picture of how data is flowing through the Diffuser.
You will most likely not need to break apart your entire Diffuser in this manner. It is likely that you know roughly where your error is. For example, maybe the view.titleLabel attribute is not being set properly. Start by expanding that into node, and then work your way backwards towards the root until you find the error.
Note: It is essential that the objects you send into your Diffuser are immutable.
The debugging story is very similar for the Fuser. The key to debugging it is to take it apart.
Consider the following Fuser:
let fuser: Fuser<CounterEvent> = .fromAll(
.extract(.incrementPressed, .fromEvents(view.incrementButton, for: .touchUpInside),
.extract(.decrementPressed, .fromEvents(view.decrementButton, for: .touchUpInside))
)Breaking this down gives us:
let fuser: Fuser<CounterEvent> = .fromAll(
.extract(
{ (_: UIButton) in
return .incrementPressed
}, /* <-- touch events are sent into this function... */
/* <-- from taps on view.incrementButton: */ .fromEvents(view.incrementButton, for: .touchUpInside),
.extract(
{ _ in .decrementPressed },
.fromEvents(view.decrementButton, for: .touchUpInside)
)
)Now we can set breakpoints in much the same way.
The type hints provided by the compiler are often not the most helpful. Taking things apart in the manner shown above is often a good way to verify your assumptions about the types involved. By breaking things down and removing things, you can isolate the actual problem at hand.