Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Extension: same extension function in two Modules

Say I have a Framework called SwiftKit, which has a UIView's extension class method named someClassMethod and a property named someProperty within it:

// SwiftKit public extension UIView {     class func someClassMethod() {         print("someClassMethod from Swift Kit")     }      var someProperty: Double {         print("someProperty from Swift Kit")         return 0     } } 

And I also have a Framework called SwiftFoundation, which also has a UIView's extension class method named someClassMethod and a property named someProperty within it:

// SwiftFoundation public extension UIView {     class func someClassMethod() {         print("someClassMethod from Swift Foundation")     }      var someProperty: Double {         print("someProperty from Swift Foundation")         return 0     } } 

Then I created a project introduced these Frameworks, things is, if I import both of them in the same swift file and access those extensions, I got a "Ambiguous use of someProperty/someClassMethod()" error, even if I specified the call in the form of SwiftKit.UIView.someClassMethod() :

import UIKit import SwiftKit import SwiftFoundation  class ViewController: UIViewController {     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view, typically from a nib.          self.view.someProperty              // error: Ambiguous use of 'somProperty'         SwiftKit.UIView.someClassMethod()   // error: Ambiguous use of 'someClassMethod()'     } } 

If I only import one of them, the ambiguous error goes away, but more strange thing happens:

import UIKit import SwiftKit //import SwiftFoundation  class ViewController: UIViewController {     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view, typically from a nib.          self.view.someProperty         SwiftKit.UIView.someClassMethod()     } } 

The console print out:

someProperty from Swift Foundation

someClassMethod from Swift Foundation

My question is: How can I call these extensions(both class/instance method, properties) without ambiguous? If I cannot, does it mean we should add prefix to extension names as we usually do with Objective-C?

like image 298
guojiubo Avatar asked Sep 23 '15 10:09

guojiubo


People also ask

Can Swift override extension?

It is not possible to override functionality (like properties or methods) in extensions as documented in Apple's Swift Guide. Extensions can add new functionality to a type, but they cannot override existing functionality. The compiler is allowing you to override in the extension for compatibility with Objective-C.

Can extension have properties Swift?

As you may know Swift does not allow stored properties into extensions. That's by design: “Extensions may not contain stored properties.”

What is difference between extension and inheritance Swift?

Protocol extensions can add implementations to conforming types but can't make a protocol extend or inherit from another protocol. Protocol inheritance is always specified in the protocol declaration itself.


1 Answers

Details

  • Swift 3, Xcode 8.1
  • Swift 4, Xcode 9.1
  • Swift 5.1, Xcode 11.2.1

Problem

frameworks SwiftFoundation and SwiftKit has the same names of the properties and functions

decision

Way1

Use different names of the properties and functions

// SwiftFoundation public extension UIView {     public class func swiftFoundationSomeClassMethod() {         print("someClassMethod from Swift Foundation")     }      public var swiftFoundationSomeProperty: Double {         print("someProperty from Swift Foundation")         return 0     } } 

Way2

Group the properties and functions

// SwiftKit public extension UIView {     public class SwiftKit {         public class func someClassMethod() {             print("someClassMethod from Swift Kit")         }          public var someProperty: Double {             print("someProperty from Swift Kit")             return 0         }     }      var SwiftKit: SwiftKit { return SwiftKit() } } 

Result

import UIKit import SwiftKit import SwiftFoundation  class ViewController: UIViewController {      override func viewDidLoad() {         super.viewDidLoad()          _ = view.SwiftKit.someProperty         UIView.SwiftKit.someClassMethod()          _ = view.swiftFoundationSomeProperty         UIView.swiftFoundationSomeClassMethod()     } } 

Project

enter image description here enter image description here

Your method

SwiftFoundation.UIView.swiftFoundationSomeClassMethod() 

Your variant of using the namespaces is not correct because all UIView extensions from both frameworks are included in you UIView class. Look at image bellow, you can see SwiftKit class and swiftFoundationSomeClassMethod() inside SwiftFoundation. This can confuse other developers.

enter image description here

like image 144
Vasily Bodnarchuk Avatar answered Sep 19 '22 09:09

Vasily Bodnarchuk