21

How do I make a private function in Swift?

Here is an example:

import UIKit

class AnotherClass {

    var someVar = 1
    let someConst = 2

    func somePrivateFunc() -> Bool {
        return true
    }

    func someFunc() -> (Int -> Bool) {
        var someInnerFuncVar = { (num: Int)->Bool in
            return true
        }

        return someInnerFuncVar
    }

    init() {
        var vc = ViewController()
    }

}

But if this is the only way to do it....

Slipp D. Thompson
  • 33,165
  • 3
  • 43
  • 43
SirRupertIII
  • 12,324
  • 20
  • 72
  • 121

3 Answers3

17

At the moment there are no visibility modifiers in swift.

On the developers forum, the language authors said it's on the top of their priority list.

Quoting greg parker from here:

We don't usually promise anything for the future, but in this case we are making an exception. Swift will have access control mechanisms.

In the same forum they suggest you can use nested classes, in this fashion, but this is really only for preventing the code-completion to catch the inner methods. They're not really private in the sense that anyone can instantiate the nested class and access those methods.

import Foundation

class KSPoint {

    class _KSPointInner {
        class func distance(point p1 : KSPoint, toPoint p2 : KSPoint) -> Double {
            return sqrt(pow(Double(p2.x - p1.x), 2) + pow(Double(p2.y - p1.y), 2))
        }
    }

    var x : Int

    func distance(point : KSPoint, toPoint : KSPoint) -> Double {
        return _KSPointInner.distance(point: point, toPoint: toPoint)
    }
}
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
3

Alternatively, you can use Nested Classes like so:

// Public interface
class Bakery
{
    // Private implementation
    class Baker
    {
        func prepareToMakeBread(numberOfLoafs:Int)
        {
            println("Preparing to make \(numberOfLoafs) loafs of bread...")
        }

        func bakeBread()
        {
            println("Baking the bread...")
        }

        func packageBread()
        {
            println("Packaging the freshly baked bread...")
        }
    }

    // Public method
    func buyBread(numberOfLoafs:Int)
    {
        println("Customer requests \(numberOfLoafs) loafs of bread!")

        let baker = Bakery.Baker()

        baker.prepareToMakeBread(numberOfLoafs)
        baker.bakeBread()
        baker.packageBread()
    }
}

let bakery = Bakery()    
bakery.buyBread(4)

Output:

Customer requests 4 loafs of bread!  
Preparing to make 4 loafs of bread...  
Baking the bread...  
Packaging the freshly baked bread...  

However, technically they are not private as someone can instantiate a Bakery.Baker and call the methods. Functions inside functions do work but are ugly...

pkamb
  • 33,281
  • 23
  • 160
  • 191
Erik
  • 12,730
  • 5
  • 36
  • 42
2

See my answer over here.

In short, when you talk about making a "private method" or "private function" in Swift or ObjC (or ruby or java or…) those methods aren't really "private". There's no actual access control around them. Any language that offers even a little introspection lets developers get to those value from outside the class if they really want to.

So what we're talking about, then, is a way to define a public-facing interface that shows only the functionality we want it to, and "hides" the rest that we consider "private".

The swift mechanism for declaring interfaces is the protocol, and it can be used for this purpose.

Community
  • 1
  • 1
jemmons
  • 18,605
  • 8
  • 55
  • 84
  • "those methods aren't really "private"". I can't disagree more with this view. Seems like a bad justification for not having basic features on a language. What you are describing is workarounds or hacks, not normal developers day to day. – Gonçalo Jul 02 '21 at 12:45