Closed joshavant closed 7 years ago
Upon further investigation, the Xcode release notes do mention that users can still use Selector()
syntax to reference Objective-C selectors where using #selector
is not possible.
However, there's a big gotcha to that (which affects Typhoon users, in particular): Selector()
syntax can only refer to the symbol space at a global level. That means if you have a var + func with the same name - even if they are in two different classes - Selector()
syntax cannot differentiate between the two, and the compiler emits a warning for the Selector
instantiation.
I'd expect this would be an issue for nearly all Typhoon users with non-trivial codebases.
Here's a bug I filed in the Swift tracker, for that: https://bugs.swift.org/browse/SR-1038
I suppose one work around is to use Objective-C for the Assembly classes?
In my case, we had to translate all Assembly classes to Objective-C, to avoid the appearance of hundreds of warnings that slow down the compilation and execution of the code.
Anyway, this is a partial solution. The goal, at least for me, is to put aside completely Objective-C gradually and this problem is a serious misstep. I hope Typhoon guys completely translates it to Swift, or I'll have to evaluate other options for dependency injection.
@think-dev
We'll continue to support Typhoon on Objective-C as long as needed. We'll also do the best that we can with Swift, bearing in mind that it has a different philosophy than objective-c. Reflection and introspection are not first class citizens.
As a fully non-profit volunteer project, I'm not sure if we'll have time implement another DI container in pure Swift. It is definitely something that we'd all love to do, but then there's the reality of work commitments, family and other community responsibilities. So we're open to passing the baton to the next generation and/or accepting help.
There's some great progress being made on pure Swift DI containers. This one is not the most popular, but is one of my personal favorites, on the basis of the research that I've done: https://github.com/jkolb/FieryCrucible . . very Typhoon-esque, but really lean and no reflection required.
@jasperblues The community have done a really good work with Typhoon and dependency injection. I did not mean to say otherwise. Because I do not have the time to contribute to a project like Typhoon, I respect all that you have done. Others work together on other community projects.
I just shared my experience with other users. My apologies if you've offended you.
@think-dev Not at all offended, we're proud of our work too. We just don't want to set unfair expectations for loyal users. A pure swift version of Typhoon may happen - there's a good chance. But, since we volunteer in between commercial projects, we can't make a promise of timeline.
What I meant was that, given the way things are moving with Swift, we wouldn't be offended if you decided to work with one of the other projects that are gaining traction.
@jasperblues Glad to read that. Anyway, let's back to the main problem. The solution I've found at the moment is to re-translate all Assembly classes to Objective-C. This removes all warnings.
@joshavant @think-dev For a show-stopper issue, we've left this open pretty long - sorry about that.
I believe we can provide a Swift assembly that just uses strings rather than selectors for getters/setters.
Meantime, workaround appears to be:
Use Selector("propertyName")
not "propertyName"
The following definitions have allowed me to remove hundreds of warnings without changing a single Assembly. This does not provide a function for every method taking a Selector, but it does the job for what my team is using. Hope this helps others.
extension TyphoonDefinition {
@nonobjc public func useInitializer(selector: String, handler: TyphoonMethod -> Void) {
self.useInitializer(Selector(selector)) { handler($0) }
}
@nonobjc public func injectMethod(selector: String, handler: TyphoonMethod -> Void) {
self.injectMethod(Selector(selector)) { handler($0) }
}
@nonobjc public func injectProperty(sel: String) {
self.injectProperty(Selector(sel))
}
@nonobjc public func injectProperty(selector: String, with: AnyObject!) {
self.injectProperty(Selector(selector), with: with)
}
}
Another workaround is to use good old NSSelectorFromString() function. Selector() still shows warnings recommending #selector construction instead.
I would really love to have some built-in workaround (e.g. passing real string instead of selector) in the next version. It really makes my life harder when using Typhoon in big Swift projects... I really don't want to migrate to some other IoC container, Typhoon is really stable and has a lot of great features :-(
@alexgarbarev just previewed Typhoon Swift to me - looks pretty awesome :)
Looks like the problem has a workaround. And besides it we released a pure swift version.
It appears the new #selector behavior on Swift 2.2 is causing critical, language-level breakage for Typhoon users.
For starters, it appears #selector expressions cannot refer to Objective-C getter/setters (reference: Swift language tests here that indicate that an error is expected for such behavior).
I don't immediately see a workaround for this, without some kind of additional code (that is, a change to Typhoon's implementation or some other implementation-level workaround).
Thoughts?