Oniikal3
Oniikal3

Reputation: 597

Can't use private property in extensions in another file

I can't use private property in extension. My extension is in another file.

How can I use private property in extension?

Upvotes: 40

Views: 18800

Answers (3)

infiniteLoop
infiniteLoop

Reputation: 2183

It's not a good practice to write a private variable in extensions (even if we can). It will introduce unexpected bugs.

If you want to access the variable, you can use private(set) for that variable to make it read only for outside world.

Ex.

private(set) var myPrivateVariable:Int

Upvotes: 1

nhgrif
nhgrif

Reputation: 62062

Update Starting with Swift 4, extensions can access the private properties of a type declared in the same file. See Access Levels.

If a property is declared private, its access is restricted to the enclosing declaration, and to extensions of that declaration that are in the same file.

If the property is declared fileprivate, it can only be used within the file it is declared (and by anything in that file).

If the property is declared internal (the default), it can only be used within the module it is declared (and by anything in that file).

If the property is declared public or open, it can be used by anything within the module as well as outside of the module by files that import the module it is declared in.

Upvotes: 44

Benny Davidovitz
Benny Davidovitz

Reputation: 1202

While @nhgrif is correct about how painful is that protected is missing in Swift, There is a way around.

Wrap your object with protocol, and declare only about the methods and properties that you wish to expose.

For Example

MyUtiltyClass.swift

protocol IMyUtiltyClass {
    func doSomething()
}

class MyUtiltyClass : IMyUtiltyClass {

    static let shared : IMyUtiltyClass = MyUtiltyClass()

    /*private*/
    func doSomethingPrivately() {

    }
}

MyUtiltyClass+DoSomething.swift

extension MyUtiltyClass {
    func doSomething() {
        self.doSomethingPrivately()
        print("doing something")
    }
}

And then you treat the object as the interface type and not the class/struct type directly.

MyViewController.swift

class MyViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        MyUtiltyClass.shared.doSomething()
        /*
         //⚠️ compiler error
         MyUtiltyClass.shared.doSomethingPrivately()
         */
    }
}

Happy Coding 👨‍💻

Upvotes: 7

Related Questions