"If you are using code generation to solve a problem that might be better solved by making your code more generic, code generation will probably have a degradative effect on the health and maintainability of your codebase."
Basically, if you have to resort to code generation:
1) Abandon all hope, ye who enter here
2) The abstraction mechanisms available to you are deficient.
Ultimately it’s a cycle. Runtime abstractions tend to pile up until they hinder performance and debugging, and then code generation becomes interesting. Over time those patterns become incorporated into languages, at which point code generation seems pointless again (think Qt’s code generation tools in 1996 vs. C++14). And when the language has new interesting features, it seems to translate into people creating runtime abstractions, thus setting off another iteration of the cycle.
I think the kind of thing they're doing would be possible without code generation in a good dynamically typed language or a language with a feature like F#'s type providers, but maybe swift doesn't allow it.
The second use case (generating test mocks) is a pretty bad reason to use code generation IMHO. Instead they should be generating non-turing complete code representing the mock (JSON or something).
Code generation to avoid parametricity is (AFAICT) unequivocally a bad thing. Parametricity in code is almost always a good thing because it constrains what any implementation can do -- and thus gives you guarantees (subject to compiler correctness).
Code generation to avoid boilerplate in a sane way? IMO it's actually a pretty low-tech and simple way to avoid huge amounts of repetetive work, especially if you're targeting multiple platforms in different languages. Obviously, there's LISP-like macros and maybe pseudo-dependent types in Haskell (Servant) which may buck the trend, but I, for one, actually appreciate the simplicity of a bit of actually generated "on disk" code when it's appropriate.
IME code generation really shines when you're approaching the business domain, i.e. closer to the "edges" of your program/service. This is where "generic" solutions tend to not work as well just by virtue of every business case being slightly different. For logic that works on top of core data structures like vector-of-X or vector-of-Y? Hell no! You're writing lots of code that 'talks to' vector-of-$ all the time and you'd be crazy to want to have to duplicate all of that.
 Servant actually seems to be a sort of "define the types" and generate code for all the platforms, so that may actually be an example of my "sane" way. Whatever. LISP-like macros obviously kind of avoid the point entirely because they're never "materialized" as source. Just wanted to bring them up because they tend to be brought up in these discussions, regardless.
I use R.Swift in every project for a while already. My template Podfile has it as well as a linter.
The mock generation tools look neat. Swift is a complicated language to write tests in as it stands now and using Objective-C limits the things you can do in swift.