Reputation: 19239
I have a Swift 2 project in XCode 7.3 where I use two different third party frameworks.
'FrameworkA' declares a public UIView
extension declaring cornerRadius
property like this:
extension UIView {
var cornerRadius: CGFloat {
get { return self.layer.cornerRadius }
set(cornerRadius) {
self.layer.masksToBounds = true
self.layer.cornerRadius = cornerRadius
}
}
}
'FrameworkB' declares a UIView
subclass with a cornerRadius
property:
class TagView: UIView {
var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
}
Both frameworks compile perfectly fine as they don't know each other. However, when trying to use the 'FrameworkB' property in my code:
let view = UIView()
view.cornerRadius = 10 // FrameworkA: Ok
let tagView = TagView(title: "")
tagView.cornerRadius = 10 // Compilation error
(tagView as UIView).cornerRadius = 10 // FrameworkA: Ok
It fails with the error:
Ambiguous use of 'cornerRadius'
I'm able to call the 'FrameworkA' extension property type-casting to UIView
, but I am not able to call the 'FrameworkB' class property even if I don't import 'FrameworkA' in this file. As soon as I import 'FrameworkA' somewhere in the project, it starts failing.
Is there any way to explicitly telling the compiler to use 'FrameworkB' method or avoid importing 'FrameworkA' in a Swift file?
Edit: To reproduce it you can use Wakup
and TagListView
pods (FrameworkA and FrameworkB respectively) and try to execute the code above.
Upvotes: 4
Views: 1435
Reputation: 42143
If you're using these different classes in unrelated places, perhaps you could import specific symbols only in source files that actually need them.
import class FrameworkA.TagView
Upvotes: 0
Reputation: 19239
My current solution is to create a dynamic framework target 'ProxyFramework' in the same project. I add the 'FrameworkB' dependency using Cocoapods and declare a new property that doesn't conflicts with the extension method declared in 'FrameworkA':
public extension TagList {
public dynamic var cornerRadius_: CGFloat {
get { return cornerRadius }
set { cornerRadius = newValue }
}
}
In my application target, I add the newly created framework target to 'Target Dependencies', so I'm now able to use the 'FrameworkB' property through this proxy framework:
let view = UIView()
view.cornerRadius = 10 // FrameworkA: Ok
let tagView = TagView(title: "")
tagView.cornerRadius_ = 10 // ProxyFramework -> FrameworkB: Ok
(tagView as UIView).cornerRadius = 10 // FrameworkA: Ok
I'd love to see a cleaner solution.
Upvotes: 1