0:06 This episode is a bit different because it's a Q&A episode where we
answer questions that have been sent in to us. We'd like to know if people like
these Q&A episodes, so if you have feedback, please send us an email.
Storing Authentication Information
0:48 Let's start with the first question: Where do you store
authentication information when making a request? This is a question about the
Networking episode, where we
presented a networking layer with a Resource struct. In many cases, we have
to use an authentication token for almost every request, as most endpoints are
authenticated. Therefore, it would make sense to put the token in the
1:50 Then we'd modify the request in the load method to include the
token as a header field.
If it's important for your business logic to make a clear separation between
authenticated and non-authenticated requests, then you could put the token in
the Resource instead.
2:16 The next question: Where would you add HTTP headers — specifically,
headers such as Content-Type, which are also connected to how you parse the
resource? A header like Content-Type would be a perfect candidate to put into
the Resource struct, as it's specific to the endpoint. We could, for example,
add a dictionary called headers:
2:55 Having a headers dictionary is more generic, so it's also a bit
more flexible. We could modify our initializer for JSON resources to
automatically set the Content-Type or the Accept-Type. Likewise, if we want
to accept XML, we would need a different parsing function, and we can support
this by adding another initializer to Resource so that the parsing function
and Content-Type automatically match up.
3:28 We could even combine the two questions: in our load method in
the WebService, we could add both headers that are Resource specific and
headers that are set for all resources.
4:14 At first, we thought it'd be easy by playing around with protocols
a bit, but when we actually tried figuring it out, it wasn't so easy. Our
conclusion was that it's possible, but none of our solutions felt as nice as the
generic table view controller for a single cell type. For example, one simple
solution had a big drawback: we needed to move a force-cast from our table view
controller (the library) to the configure callback (the client of the library).
Currently, within tableView(cellForRowAt:), we cast our cell to the right type
so the configure callback gets called with the right cell type.
5:23 No matter how we solve this problem, we always end up with a
compromise. We haven't found a nice solution, so if anyone discovers something,
let us know.
Adding UITextView Support to ContentElement
5:39 Another question: In the Stack Views with
Enums episode, if
you want to add support for a text view, how do you deal with all the callbacks?
A text view has multiple callbacks. If we only had a single callback, we could
use something similar to the .button case, but what about when there are
6:18 First, the ContentElement approach is something we built for
convenience, so it might not be the best tool for this problem.
6:26 Second, we could also add a custom case to the enum. This way,
we can use any view within the stack view and we'd pass in a fully configured
UIView subclass. This allows us to have more complicated views that we use
together with the convenience cases:
By the way, we could also take this approach in other situations where the
number of callbacks gets out of hand — for example, in a view controller such as
the one described in our Connecting View
Custom UIStoryboardSegue Subclasses
8:50 The next question: Is the App class in the Connecting View
episode such a good idea? It will get complicated as we add more features. An
alternative approach might be creating subclasses of UIStoryboardSegue, just
like in Andy Matuschak's talk, Refactor the Mega
Rather than having all the logic in an App class, he moved a lot of logic to
segues. That way, it wasn't in the view controller.
9:30 There are two parts to this question. Firstly, we'll have to decide
if we want to use storyboards at all. In our case, we decided not to use
storyboards, and then we ended up with an App class that could become very
big. That's definitely a problem, but it should be easy to split it up into
10:00 The second part is that we've never tried having a storyboard with
custom segue subclasses. However, it seems like a sensible approach when using
storyboards. There's no one right way. Our solution was definitely more
experimental and strange, but it worked well for our use case.
Storyboards, Nibs, or Code?
10:26 There's a related question that we get a lot: Should I use
storyboards, or nibs, or just code? There's no way we can answer this. We've
used all these approaches in past projects, and all of them worked well. Just
choose whatever fits you and your project. With all three approaches, you'll
have to be careful to keep your code maintainable by continually refactoring
11:08 There are also questions about testing: What should I test? How
much should I test? What's the best way to do this? Again, there's no right
answer. We've used different approaches ourselves. Once, for a Rails client
project, we used BDD and this worked really well. Once we handed over the
project, the next person could just start working without us having to spend a
lot of time transferring the code base.
11:59 We also have some episodes coming up where we develop things in a
TDD way because it's a perfect fit. In those particular instances, this made
development much faster and easier. There are other parts of the same app that
we only tested manually. In a lot of projects, we only tested a specific
critical part or almost nothing. It depends on your project. Again, there's no
one right way to test. It depends on who you're working with, what your project
does, how important it is, and so on.
12:45 It's important that you figure out for yourself what helps you and
what doesn't help you, along with when testing helps you. It's not so important
what we do or how we come to our decisions, because everyone needs to figure it
out for themselves personally. Different people have different capabilities and
different ways of working.
13:13 When you think about testing, it's good to keep in mind the ways
in which it can help you. For example, testing can help you write the code
correctly as a verification, but it can also help you design your code. More
specifically, it can help you define the API of your code. Finally, tests can
serve as documentation. This is also useful when working with multiple people.