-
-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how to adopt SafeDI in UIKit / AppDelegate apps #146
Comments
Interesting. I haven't made an This is a bit tricky because the generated initializer in this case would need to be both an override and a convenience initializer, and we don't necessarily have enough information at the That said, I'm going to leave this open as a feature request. I can imagine adding a |
init()
on a root type
Another workaround I used: Then, I added another extension AppDelegate {
convenience init(_ a: AppDelegate) {
self.init(
viewControllerBuilder: a.viewControllerBuilder,
userRepository: a. userRepository,
network: a.network
)
}
} Finally, I used it inside AppDelegate to implement public convenience override init() {
self.init(.instantiate())
} So, if I had an option in safe-di-tool --generate-instantiate-function |
I think I prefer adding modifiers to the exiting |
Valid combinations of decorators we need to care about are: required convenience init() // when the superclass's `init()` is `required` override convenience init() // when the superclass defines an `init()` without the `required` decorator I think that's it. You can imagine updating our public macro Instantiable(
isRoot: Bool = false,
superclassHasNoParameterInit: Bool = false,
superclassHasRequiredNoParameterInit: Bool = false,
fulfillingAdditionalTypes additionalTypes: [Any.Type] = [],
conformsElsewhere: Bool = false
) And then we can make the macro enforce that you don't set both I don't love this API, but I'm struggling to come up with an alternative that is:
I am open to suggestions! |
It fixes the first problem, but I have no idea about the second one. Does it fix the "already overriden" problem in AppDelegate? |
Great point. I just played around a little and I think you're right that this still won't work for working with Objective-C objects. Here's the error I get when utilizing an @main
public class AppDelegate: UIResponder, UIApplicationDelegate {
public init(test: String) {}
}
extension AppDelegate {
public override convenience init() { // Error: Multiple definitions of symbol '$s14SampleProject11AppDelegateCACycfc'
self.init(test: "hi")
}
} And then here's an error I got playing with another Objective-C inherited type: public class SuperTest: NSObjectProtocol {
public init() {}
// stub NSObjectProtocol implementation here…
}
public final class Test: SuperTest {
public init(test: String) {}
}
extension Test {
public override convenience init() { // Error: Non-@objc initializer 'init()' declared in 'SuperTest' cannot be overridden from extension
self.init(test: "test")
}
} So, maybe this feature isn't worth adding? The additional complexity in I think this workaround merits documentation. I'm going to update the title of this issue to track that proposed resolution. |
init()
on a root type
I'll add a subheader under the Migrating to SafeDI section of our documentation. This section may also mention a suggested root for SwiftUI apps. |
Steps to reproduce
Sample code or sample project upload
Sample AppDelegate
Expected behavior
It compiles successfully.
Actual behavior
It has two issues:
override
is missing.init()
is already overriden.The text was updated successfully, but these errors were encountered: