Swift 3 overriding non-open var outside of its defining module - swift

I converted my swift 2 code into swift 3. Then I'm getting this error. Can anyone help me on this?
open override var formatKey: String { //overriding non-open var outside of its defining module
get {
if customFormatKey != nil {
return customFormatKey!
}
return String(describing: type(of: self)).components(separatedBy: ".").last!
}
}

According to the Access Control section of The Swift Programming Language:
Open access applies only to classes and class members, and it differs
from public access as follows:
Classes with public access, or any more restrictive access level, can
be subclassed only within the module where they’re defined.
Class members with public access, or any more restrictive access
level, can be overridden by subclasses only within the module where
they’re defined.
Open classes can be subclassed within the module where they’re
defined, and within any module that imports the module where they’re
defined.
Open class members can be overridden by subclasses within the module
where they’re defined, and within any module that imports the module
where they’re defined.
open in Swift 3 and later is the equivalent of public in Swift 2. For more information, see Swift Evolution proposal SE-0117.
To fix this, change the original definition of formatKey from public to open, and override using override var formatKey: String { ....

I did face with the same issue, then you can try to search all project - include pods/ folder - to make sure this formatKey is not public var somewhere in your project.

Related

How can a Swift module/class work around the lack of language support for "protected" members?

I'm faced with a situation where I am defining a reusable base class in a module, and I want to provide certain functions that should be callable only by subclasses, not external users of that subclass.
I'm writing a framework and packaging it as a Swift module. Part of my framework includes a base class that can be subclassed to add functionality, but whereby the derived class also has a further external purpose as well. Imagine defining a new kind of view: it derives from UIView or NSView, then provides additional logic, and is then itself instantiated by another party.
In this case, I'm the one defining the UIView-like class that is intended to be subclassed, and along with it comes a lot of private UIView internal stuff, like measurement, arranging, who knows, internal stuff.
The point is, end users of this new view class don't want to see the internals of the architecture that supported the subclassing, those should be completely inside the black box of what the subclass represents.
And it strikes me that this is now impossible in Swift.
I really don't understand why Swift got rid of protected access control. According to Apple, the function that I want to expose only to subclasses "isn't really useful outside the subclass, so protection isn’t critical".
Am I missing something? Is this a whole class of design patterns that Swift simply cannot support?
One thought that occurs to me is I could perhaps split up the public-public and the private-public parts of my class into two parts, perhaps using protocols, whereby public-public users would only see the public protocol and "private" public users would see the "private" protocol as well. Alas this seems like a lot of engineering for something that used to be free.
FWIW — I've been continually asking for better access control in Swift (including protected) since before there was access control in Swift. Now, 3.5 years after we were told to give the Swift approach to access control a try, Swift has been my primary language for almost 3 of those years and I still think the access control paradigm is clumsy and unable to model concepts that are easy in almost all similar languages.
The largest mitigating factor for me is that Swift has steered me away from ever using inheritance and subclassing 95% of the time, which I think is a good thing. So this issue comes up less than it may have otherwise. But for situations exactly as you are describing, there isn't an equivalent way to accomplish what you are doing using only protocols and protocol extensions, so you are stuck either polluting a public API with possibly harmful internal details, or using some workaround (like the one that follows) which has the smallest possible public API exposure, and simulates what you want at the cost of boilerplate and awkwardness.
That said, the approach I take is somewhat inspired by Objective C, where there is also no real protected access control, but the convention is to declare a public API header (which client code will import and reference) and a special "+Subclassing" header which only subclasses will import in their implementation, giving them visibility into the not-for-public-consumption internals.
In Swift, this isn't directly possible either, but given a class like this:
open class SomeClass {
private var foo: String
private var bar: Data
public init(){
foo = "foo"
bar = Data()
}
private func doInternalThing() {
print(foo)
}
}
You can add a nested "Protected" wrapper via extension (has to be in the same file as your class declaration), which takes an instance of the class (or a subclass) and exposes the protected-level internals as a sort of proxy:
// Create a nested "Protected" type, which can accept an instance of SomeClass (or one of its subclasses) and expose the internal / protected members on it
public extension SomeClass {
public class Protected {
unowned private var someClass: SomeClass
public var foo: String {
get {
return someClass.foo
}
set {
someClass.foo = newValue
}
}
public init(_ someClass: SomeClass) {
self.someClass = someClass
}
public func doInternalThing() {
someClass.doInternalThing()
}
}
}
Outside of the framework, in the client application, the protected members are accessed in a subclass like this:
class SomeSubclass: SomeClass {
private lazy var protected: SomeClass.Protected = { SomeClass.Protected(self) }()
func doSomething() {
protected.foo = "newFoo" // Accesses the protected property foo and sets a new value "newFoo"
protected.doInternalThing() // Prints "newFoo" by calling the protected method doInternalThing which prints the foo property.
}
}
There are pros and cons for this approach. The cons are mainly the amount of boilerplate you need to write to map all your properties and functions from the Protected wrapper to the actual class instance as shown above. Also, there is no avoiding the fact that consumers will see SomeClass.Protected as a publicly visible type, but hopefully it's clear that it shouldn't be used and it's difficult enough to use it arbitrarily that it won't happen.
The pros are that there isn't a lot of boilerplate or pain for clients when creating subclasses, and its easy to declare a lazy "protected" var to get the desired API. It's pretty unlikely that non-subclass would stumble upon or use this API accidentally or unwittingly, and it's mostly hidden as desired. Instances of SomeSubclass will not show any extra protected API in code completion or to outside code at all.
I encourage anyone else who thinks access control — or really in this case, API visibility and organization — to be easier than it is in Swift today to let the Swift team know via the Swift forums, Twitter, or bugs.swift.org.
You can kinda, sorta work around it by separating out the for-subclasses stuff into a separate protocol, like this:
class Widget {
protocol SubclassStuff {
func foo()
func bar()
func baz()
}
func makeSubclassStuff() -> SubclassStuff {
// provide some kind of defaults, or throw a fatalError if this is
// an abstract superclass
}
private lazy var subclassStuff: SubclassStuff = {
return self.makeSubclassStuff()
}()
}
Then you can at least group the stuff that's not to be called in one place, to avoid it polluting the public interface any more than absolutely necessary and getting called by accident.
You can also reconsider whether you really need the subclass pattern here, and consider using a protocol instead. Unfortunately, since protocols can't nest types yet, this involves giving the subclass-specific protocol an Objective-C-style prefixed name:
protocol WidgetConcreteTypeStuff {
...
}
protocol Widget {
var concreteTypeStuff: WidgetConcreteTypeStuff { get }
}

Access control in swift 4

While upgrading to Swift4 from Swift3, I got some issues related to access control.
Here is the sample code. Which was there in Swift3, working fine in past times -
open class MyClass {
private let value: Int
static var defaultValue: Int { return 10 }
public init(value: Int = MyClass.defaultValue) {
self.value = value
}
}
To make the code run in Swift4, I have to change access control for defaultValue to public.
Here is the Swift4, compiling version
open class MyClass {
private let value: Int
static public var defaultValue: Int { return 10 }
public init(value: Int = MyClass.defaultValue) {
self.value = value
}
}
While I was wondering what is going on, I tried to remove open access control for MyClass, it allowed me to remove access identifier for defaultValue. Even can put it to private.
class MyClass {
private let value: Int
private static var defaultValue: Int { return 10 }
public init(value: Int = MyClass.defaultValue) {
self.value = value
}
}
I understand all the access identifiers, but I am not able to understand this behaviour. Especially the first case where xcode forced me to change access control of defaultValue to public.
Please help.
My original answer (shown below) is now mostly outdated – the beginnings of the resilience model are to be implemented in Swift 4.2 with the introduction of the #inlinable and #usableFromInline attributes, corresponding to the old #_inlineable and #_versioned attributes.
In addition, and more importantly, the rule for what default arguments of publically accessible functions can reference has changed again. To recap the previous rules:
In Swift 3 there was no enforcement of what access level such default argument expressions could reference (allowing your first example where defaultValue is internal).
In Swift 4, such a default argument could only refer to declarations exposed as a part of the module's interface, including those that aren't otherwise directly visible to users in another module (i.e #_versioned internal).
However in Swift 4.2, with the implementation of SE-0193, the rule is now that the default argument expression of a publicly accessible function can only refer to publicly accessible declarations (not even #inlinable internal or #usableFromInline internal).
I believe this is paving the way for the displaying of default argument expressions in a module's generated interface file. Currently Swift just shows an unhelpful = default, but I believe this will change to actually show the default argument. This can only realistically happen with this new access-control restriction in place (Edit: This is now happening).
Old answer (Swift 4)
This change is due to the work towards a resilience model that is already available via underscored attributes (#_inlineable, #_versioned, #_fixed_layout), but is yet to be officially finalised (so you probably shouldn't be using these attributes yourself yet). You can read about the full proposed details of the resilience model here, as well as the the Swift evolution discussion on it here.
In short, an inlineable function is one whose implementation, as well as declaration, is exposed as a part of a module's interface and can therefore be inlined when called from another module. An inlineable function must therefore also be publically accessible to begin with (i.e public or higher).
What you're running into is a change that makes default argument expressions for publically accessible functions inlineable, meaning that they must be available to be evaluated directly in the calling module's binary. This reduces the overhead of calling a function with default parameter values from another module, as the compiler no longer needs to do a function call for each default argument; it already knows the implementation.
I don't believe this change is officially documented in the release of Swift 4 itself, but it is confirmed by Swift compiler engineer Slava Pestov, who says:
Swift 3.1 added resilience diagnostics for inlineable code, which is not an officially supported feature, but in Swift 4 we switched these checks on for default argument expressions as well.
So if you have a publically accessible function with a default argument expression (such as MyClass.defaultValue in your case), that expression can now only refer to things that are also a part of that module's interface. So you need to make defaultValue publically accessible.
Unfortunately, there's currently no way to make a private function's declaration part of a module's interface (which would allow for your usage of it in a default argument expression). The attribute that would facilitate this is #_versioned, but it is forbidden with (file)private due to the following reasons given by Slava Pestov:
It would be a trivial change to allow #_versioned on private and
fileprivate declarations, but there are two pitfalls to keep in mind:
Private symbols are mangled with a ‘discriminator’ which is basically a hash of the file name. So now it would be part of the ABI,
which seems fragile — you can’t move the private function to another
source file, or rename the source file.
Similarly, right now a #_versioned function becoming public is an ABI compatible change. This would no longer work if you could have
private #_versioned functions, because the symbol name would change if
it became public.
For these reasons we decided against “private versioned” as a concept.
I feel like internal is enough here.
You could achieve this with a #_versioned var defaultValue though:
open class MyClass {
private let value: Int
#_versioned static var defaultValue: Int {
return 10
}
public init(value: Int = MyClass.defaultValue) {
self.value = value
}
}
The declaration of MyClass.defaultValue is now exported as a part of the module's interface, but still cannot be directly called from another module's code (as it's internal). However, the compiler of that module can now call it when evaluating the default argument expression. But, as said earlier, you probably shouldn't be using an underscored attribute here; you should wait until the resilience model has been finalised.

Access levels of custom initializers in Swift 3.1

Quote from The Swift Programming Language (Swift 3.1):
Custom initializers can be assigned an access level less than or equal to the type that they initialize. The only exception is for required initializers (as defined in Required Initializers). A required initializer must have the same access level as the class it belongs to.
If so, why does this code compile and work?
private class GoofyClass {
public init(mood: String) {}
public required init(isCrazy: Bool) {}
}
private let shock = GoofyClass(mood: "shocked")
private let crazy = GoofyClass(isCrazy: true)
In Swift, members of a class or struct with a less restrictive access level than the class/struct itself are automatically downgraded to the same level as the class/struct. I believe this is a deliberate design decision on the part of the language designers.
In your case, assuming the class is declared at the top level in the file (i.e. it is not nested inside another type), the inits you have declared public are, in fact, fileprivate.
The only exception is for required initializers (as defined in Required Initializers). A required initializer must have the same access level as the class it belongs to.
This is referring to the fact that you cannot make the access level of a required initialiser more restrictive than its class e.g.
open class Foo
{
internal required init() // error
}

What is the 'open' keyword in Swift?

The ObjectiveC.swift file from the standard library contains the following few lines of code around line 228:
extension NSObject : Equatable, Hashable {
/// ...
open var hashValue: Int {
return hash
}
}
What does open var mean in this context, or what is the open keyword in general?
open is a new access level in Swift 3, introduced with the implementation
of
SE-0117 Allow distinguishing between public access and public overridability
It is available with the Swift 3 snapshot from August 7, 2016,
and with Xcode 8 beta 6.
In short:
An open class is accessible and subclassable outside of the
defining module. An open class member is accessible and
overridable outside of the defining module.
A public class is accessible but not subclassable outside of the
defining module. A public class member is accessible but
not overridable outside of the defining module.
So open is what public used to be in previous
Swift releases and the access of public has been restricted.
Or, as Chris Lattner puts it in
SE-0177: Allow distinguishing between public access and public overridability:
“open” is now simply “more public than public”, providing a very simple and clean model.
In your example, open var hashValue is a property which is accessible and can be overridden in NSObject subclasses.
For more examples and details, have a look at SE-0117.
Read open as
open for inheritance in other modules
I repeat open for inheritance in other modules.
So an open class is open for subclassing in other modules that include the defining module. Open vars and functions are open for overriding in other modules. Its the least restrictive access level. It is as good as public access except that something that is public is closed for inheritance in other modules.
From Apple Docs:
Open access applies only to classes and class members, and it differs from public access as follows:
Classes with public access, or any more restrictive access level, can
be subclassed only within the module where they’re defined.
Class members with public access, or any more restrictive access level, can
be overridden by subclasses only within the module where they’re
defined.
Open classes can be subclassed within the module where they’re defined, and within any module that imports the module where
they’re defined.
Open class members can be overridden by subclasses
within the module where they’re defined, and within any module that
imports the module where they’re defined.
Open is an access level, was introduced to impose limitations on class inheritance on Swift.
This means that the open access level can only be applied to classes and class members.
In Classes
An open class can be subclassed in the module it is defined in and in modules that import the module in which the class is defined.
In Class members
The same applies to class members. An open method can be overridden by subclasses in the module it is defined in and in modules that import the module in which the method is defined.
THE NEED FOR THIS UPDATE
Some classes of libraries and frameworks are not designed to be subclassed and doing so may result in unexpected behavior. Native Apple library also won't allow overriding the same methods and classes,
So after this addition they will apply public and private access levels accordingly.
For more details have look at Apple Documentation on Access Control
open come to play when dealing with multiple modules.
open class is accessible and subclassable outside of the defining module. An open class member is accessible and overridable outside of the defining module.
open is only for another module for example: cocoa pods, or unit test, we can inherit or override

Swift Members / Methods Accessibility Modifiers [duplicate]

In Objective-C instance data can be public, protected or private. For example:
#interface Foo : NSObject
{
#public
int x;
#protected:
int y;
#private:
int z;
}
-(int) apple;
-(int) pear;
-(int) banana;
#end
I haven't found any mention of access modifiers in the Swift reference. Is it possible to limit the visibility of data in Swift?
As of Swift 3.0.1, there are 4 levels of access, described below from the highest (least restrictive) to the lowest (most restrictive).
1. open and public
Enable an entity to be used outside the defining module (target). You typically use open or public access when specifying the public interface to a framework.
However, open access applies only to classes and class members, and it differs from public access as follows:
public classes and class members can only be subclassed and overridden within the defining module (target).
open classes and class members can be subclassed and overridden both within and outside the defining module (target).
// First.framework – A.swift
open class A {}
// First.framework – B.swift
public class B: A {} // ok
// Second.framework – C.swift
import First
internal class C: A {} // ok
// Second.framework – D.swift
import First
internal class D: B {} // error: B cannot be subclassed
2. internal
Enables an entity to be used within the defining module (target). You typically use internal access when defining an app’s or a framework’s internal structure.
// First.framework – A.swift
internal struct A {}
// First.framework – B.swift
A() // ok
// Second.framework – C.swift
import First
A() // error: A is unavailable
3. fileprivate
Restricts the use of an entity to its defining source file. You typically use fileprivate access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
// First.framework – A.swift
internal struct A {
fileprivate static let x: Int
}
A.x // ok
// First.framework – B.swift
A.x // error: x is not available
4. private
Restricts the use of an entity to its enclosing declaration. You typically use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.
// First.framework – A.swift
internal struct A {
private static let x: Int
internal static func doSomethingWithX() {
x // ok
}
}
A.x // error: x is unavailable
Swift 4 / Swift 5
As per mentioned in the Swift Documentation - Access Control, Swift has 5 Access Controls:
open and public: can be accessed from their module's entities and any module's entities that imports the defining module.
internal: can only be accessed from their module's entities. It is the default access level.
fileprivate and private: can only be accessed in limited within a limited scope where you define them.
What is the difference between open and public?
open is the same as public in previous versions of Swift, they allow classes from other modules to use and inherit them, i.e: they can be subclassed from other modules. Also, they allow members from other modules to use and override them. The same logic goes for their modules.
public allow classes from other module to use them, but not to inherit them, i.e: they cannot be subclassed from other modules. Also, they allow members from other modules to use them, but NOT to override them. For their modules, they have the same open's logic (they allow classes to use and inherit them; They allow members to use and override them).
What is the difference between fileprivate and private?
fileprivate can be accessed from the their entire files.
private can only be accessed from their single declaration and to extensions of that declaration that are in the same file; For instance:
// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
private var aPrivate: String?
fileprivate var aFileprivate: String?
func accessMySelf() {
// this works fine
self.aPrivate = ""
self.aFileprivate = ""
}
}
// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
func accessA() {
// create an instance of "A" class
let aObject = A()
// Error! this is NOT accessable...
aObject.aPrivate = "I CANNOT set a value for it!"
// this works fine
aObject.aFileprivate = "I CAN set a value for it!"
}
}
What are the differences between Swift 3 and Swift 4 Access Control?
As mentioned in the SE-0169 proposal, the only refinement has been added to Swift 4 is that the private access control scope has been expanded to be accessible from extensions of that declaration in the same file; For instance:
struct MyStruct {
private let myMessage = "Hello World"
}
extension MyStruct {
func printMyMessage() {
print(myMessage)
// In Swift 3, you will get a compile time error:
// error: 'myMessage' is inaccessible due to 'private' protection level
// In Swift 4 it should works fine!
}
}
So, there is no need to declare myMessage as fileprivate to be accessible in the whole file.
When one talks about making a "private method" 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 values from outside the class if they really want to.
So what we're really talking about here is a way to define a public-facing interface that merely presents 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.
protocol MyClass {
var publicProperty:Int {get set}
func publicMethod(foo:String)->String
}
class MyClassImplementation : MyClass {
var publicProperty:Int = 5
var privateProperty:Int = 8
func publicMethod(foo:String)->String{
return privateMethod(foo)
}
func privateMethod(foo:String)->String{
return "Hello \(foo)"
}
}
Remember, protocols are first-class types and can be used anyplace a type can. And, when used this way, they only expose their own interfaces, not those of the implementing type.
Thus, as long as you use MyClass instead of MyClassImplementation in your parameter types, etc. it should all just work:
func breakingAndEntering(foo:MyClass)->String{
return foo.privateMethod()
//ERROR: 'MyClass' does not have a member named 'privateMethod'
}
There are some cases of direct assignment where you have to be explicit with type instead of relying on Swift to infer it, but that hardly seems a deal breaker:
var myClass:MyClass = MyClassImplementation()
Using protocols this way is semantic, reasonably concise, and to my eyes looks a lot like the Class Extentions we've been using for this purpose in ObjC.
As far as I can tell, there are no keywords 'public', 'private' or 'protected'. This would suggest everything is public.
However Apple may be expecting people to use “protocols” (called interfaces by the rest of the world) and the factory design pattern to hide details of the implementation type.
This is often a good design pattern to use anyway; as it lets you change your implementation class hierarchy, while keeping the logical type system the same.
Using a combination of protocols, closures, and nested/inner classes, it's possible to use something along the lines of the module pattern to hide information in Swift right now. It's not super clean or nice to read but it does work.
Example:
protocol HuhThing {
var huh: Int { get set }
}
func HuhMaker() -> HuhThing {
class InnerHuh: HuhThing {
var innerVal: Int = 0
var huh: Int {
get {
return mysteriousMath(innerVal)
}
set {
innerVal = newValue / 2
}
}
func mysteriousMath(number: Int) -> Int {
return number * 3 + 2
}
}
return InnerHuh()
}
HuhMaker()
var h = HuhMaker()
h.huh // 2
h.huh = 32
h.huh // 50
h.huh = 39
h.huh // 59
innerVal and mysteriousMath are hidden here from outside use and attempting to dig your way into the object should result in an error.
I'm only part of the way through my reading of the Swift docs so if there's a flaw here please point it out, would love to know.
As of Xcode 6 beta 4, Swift has access modifiers. From the release notes:
Swift access control has three access levels:
private entities can only be accessed from within the source file where they are defined.
internal entities can be accessed anywhere within the target where they are defined.
public entities can be accessed from anywhere within the target and from any other context that imports the current target’s module.
The implicit default is internal, so within an application target you can leave access modifiers off except where you want to be more restrictive. In a framework target (e.g. if you're embedding a framework to share code between an app and an sharing or Today view extension), use public to designate API you want to expose to clients of your framework.
Swift 3.0 provides five different access controls:
open
public
internal
fileprivate
private
Open access and public access enable entities to be used within any source file from their defining module, and also in a
source file from another module that imports the defining module. You
typically use open or public access when specifying the public
interface to a framework.
Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that
module. You typically use internal access when defining an app’s or a
framework’s internal structure.
File-private access restricts the use of an entity to its own defining source file. Use file-private access to hide the
implementation details of a specific piece of functionality when those
details are used within an entire file.
Private access restricts the use of an entity to the enclosing declaration. Use private access to hide the implementation details of
a specific piece of functionality when those details are used only
within a single declaration.
Open access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level.
Default Access Levels
All entities in your code (with a few specific exceptions) have a default access level of internal if you do not specify an explicit access level yourself. As a result, in many cases you do not need to specify an explicit access level in your code.
The release note on the topic:
Classes declared as public can no longer be subclassed outside of
their defining module, and methods declared as public can no longer be
overridden outside of their defining module. To allow a class to be
externally subclassed or a method to be externally overridden, declare
them as open, which is a new access level beyond public. Imported
Objective-C classes and methods are now all imported as open rather
than public. Unit tests that import a module using an #testable import
will still be allowed to subclass public or internal classes as well
as override public or internal methods. (SE-0117)
More information & details :
The Swift Programming Language (Access Control)
In Beta 6, the documentation states that there are three different access modifiers:
Public
Internal
Private
And these three apply to Classes, Protocols, functions and properties.
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}
For more, check Access Control.
Now in beta 4, they've added access modifiers to Swift.
from Xcode 6 beta 4 realese notes:
Swift access control has three access levels:
private entities can only be accessed from within the source file where they are defined.
internal entities can be accessed anywhere within the target where they are defined.
public entities can be accessed from anywhere within the target and from any other context
that imports the current target’s module.
By default, most entities in a source file have internal access. This allows application developers
to largely ignore access control while allowing framework developers full control over a
framework's API.
Access control mechanisms as introduced in Xcode 6:
Swift provides three different access levels for entities within your code. These access levels are relative to the source file in which an entity is defined, and also relative to the module that source file belongs to.
Public access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use public access when specifying the public interface to a framework.
Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app’s or a framework’s internal structure.
Private access restricts the use of an entity to its own defining source file. Use private access to hide the implementation details of a specific piece of functionality.
Public access is the highest (least restrictive) access level and private access is the lowest (or most restrictive) access level.
Default accecss it internal, and does as such not need to be specified. Also note that the private specifier does not work on the class level, but on the source file level. This means that to get parts of a class really private you need to separate into a file of its own. This also introduces some interesting cases with regards to unit testing...
Another point to me made, which is commented upon in the link above, is that you can't 'upgrade' the access level. If you subclass something, you can restrict it more, but not the other way around.
This last bit also affects functions, tuples and surely other stuff in the way that if i.e. a function uses a private class, then it's not valid to have the function internal or public, as they might not have access to the private class. This results in a compiler warning, and you need to redeclare the function as a private function.
Swift 3 and 4 brought a lot of change also for the access levels of variables and methods. Swift 3 and 4 now has 4 different access levels, where open/public access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level:
private functions and members can only be accessed from within the scope of the entity itself (struct, class, …) and its extensions (in Swift 3 also the extensions were restricted)
fileprivate functions and members can only be accessed from within the source file where they are declared.
internal functions and members (which is the default, if you do not explicitly add an access level key word) can be accessed anywhere within the target where they are defined. Thats why the TestTarget doesn't have automatically access to all sources, they have to be marked as accessible in xCode's file inspector.
open or public functions and members can be accessed from anywhere within the target and from any other context that imports the current target’s module.
Interesting:
Instead of marking every single method or member as "private", you can cover some methods (e.g. typically helper functions) in an extension of a class / struct and mark the whole extension as "Private".
class foo { }
private extension foo {
func somePrivateHelperFunction01() { }
func somePrivateHelperFunction02() { }
func somePrivateHelperFunction03() { }
}
This can be a good idea, in order to get better maintainable code. And you can easily switch (e.g. for unit testing) to non-private by just changing one word.
Apple documentation
For Swift 1-3:
No, it's not possible. There aren't any private/protected methods and variables at all.
Everything is public.
Update
Since Swift 4, it's possible see other answers in this thread
One of the options you could use is to wrap the instance creation into a function and supply the appropriate getters and setters in a constructor:
class Counter {
let inc: () -> Int
let dec: () -> Int
init(start: Int) {
var n = start
inc = { ++n }
dec = { --n }
}
}
let c = Counter(start: 10)
c.inc() // 11
c.inc() // 12
c.dec() // 11
The language grammar does not have the keywords 'public', 'private' or 'protected'. This would suggest everything is public. Of course, there could be some alternative method of specifying access modifiers without those keywords but I couldn't find it in the language reference.
Hopefully to save some time for those who want something akin to protected methods:
As per other answers, swift now provides the 'private' modifier - which is defined file-wise rather than class-wise such as those in Java or C# for instance. This means that if you want protected methods, you can do it with swift private methods if they are in the same file
Create a base class to hold 'protected' methods (actually private)
Subclass this class to use the same methods
In other files you cannot access the base class methods, even when you subclass either
e.g. File 1:
class BaseClass {
private func protectedMethod() {
}
}
class SubClass : BaseClass {
func publicMethod() {
self.protectedMethod() //this is ok as they are in same file
}
}
File 2:
func test() {
var a = BaseClass()
a.protectedMethod() //ERROR
var b = SubClass()
b.protectedMethod() //ERROR
}
class SubClass2 : BaseClass {
func publicMethod() {
self.protectedMethod() //ERROR
}
}
till swift 2.0 there were only three access level [Public, internal, private]
but in swift 3.0 apple added two new access level which are [ Open, fileType ] so
now in swift 3.0 there are 5 access level
Here I want to clear the role of these two access level
1. Open: this is much similar to Public but the only difference is that the Public
can access the subclass and override, and Open access level can not access that this image is taken from Medium website and this describe the difference between open and public access
Now to second new access level
2. filetype is bigger version of private or less access level than internal
The fileType can access the extended part of the [class, struct, enum]
and private can not access the extended part of code it can only access the
lexical scope
this image is taken from Medium website and this describe the difference between fileType and Private access level