Swift is now open source. For the latest news, visit the Swift open source blog

Access Control

In Xcode 6 beta 4, Swift adds support for access control. This gives you complete control over what part of the code is accessible within a single file, available across your project, or made public as API for anyone that imports your framework. The three access levels included in this release are:

  • private entities are available only from within the source file where they are defined.
  • internal entities are available to the entire module that includes the definition (e.g. an app or framework target).
  • public entities are intended for use as API, and can be accessed by any file that imports the module, e.g. as a framework used in several of your projects.

By default, all entities have internal access. This allows application developers to largely ignore access control, and most Swift code already written will continue to work without change. Your framework code does need to be updated to define public API, giving you total control of the exposed interface your framework provides.

The private access level is the most restrictive, and makes it easy to hide implementation details from other source files. By properly structuring your code, you can safely use features like extensions and top-level functions without exposing that code to the rest of your project.

Developers building frameworks to be used across their projects need to mark their API as public. While distribution and use of 3rd-party binary frameworks is not recommended (as mentioned in a previous blog post), Swift supports construction and distribution of frameworks in source form.

In addition to allowing access specification for an entire declaration, Swift allows the get of a property to be more accessible than its set. Here is an example class that is part of a framework:

public class ListItem {

	// Public properties.
	public var text: String
	public var isComplete: Bool

	// Readable throughout the module, but only writeable from within this file.
	private(set) var UUID: NSUUID

	public init(text: String, completed: Bool, UUID: NSUUID) {
		self.text = text
		self.isComplete = completed
		self.UUID = UUID
	}

	// Usable within the framework target, but not by other targets.
	func refreshIdentity() {
		self.UUID = NSUUID()
	}

	public override func isEqual(object: AnyObject?) -> Bool {
		if let item = object as? ListItem {
			return self.UUID == item.UUID
		}
		return false
	}
}

When mixing Objective-C and Swift, because the generated header for a framework is part of the framework’s public Objective-C interface, only declarations marked public appear in the generated header for a Swift framework. For applications, the generated header contains both public and internal declarations.

For more information, The Swift Programming Language and Using Swift with Cocoa and Objective-C books have been updated to cover access control. Read the complete Xcode 6 beta 4 release notes here.

All Blog Posts