Add a preferences window to your macOS app in minutes
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Example
Preferences.xcodeproj
Sources/Preferences
.editorconfig
.gitattributes
.gitignore
Package.swift
Preferences.podspec
license
readme.md
screenshot.gif

readme.md

Preferences

Add a preferences window to your macOS app in minutes

Just pass in some view controllers and this package will take care of the rest.

Requirements

  • macOS 10.12+
  • Xcode 10+
  • Swift 4.2+

Install

SPM

.package(url: "https://github.com/sindresorhus/Preferences", from: "0.1.0")

Carthage

github "sindresorhus/Preferences"

CocoaPods

pod 'Preferences'

Usage

Run the PreferencesExample target in Xcode to try a live example.

First, create a couple of view controllers for the preference panes you want. The only difference from implementing a normal view controller is that you have to add the Preferenceable protocol and implement the toolbarItemTitle and toolbarItemIcon getters, as shown below.

GeneralPreferenceViewController.swift

import Cocoa
import Preferences

final class GeneralPreferenceViewController: NSViewController, Preferenceable {
	let toolbarItemTitle = "General"
	let toolbarItemIcon = NSImage(named: .preferencesGeneral)!

	override var nibName: NSNib.Name? {
		return NSNib.Name("GeneralPreferenceViewController")
	}

	override func viewDidLoad() {
		super.viewDidLoad()

		// Setup stuff here
	}
}

AdvancedPreferenceViewController.swift

import Cocoa
import Preferences

final class AdvancedPreferenceViewController: NSViewController, Preferenceable {
	let toolbarItemTitle = "Advanced"
	let toolbarItemIcon = NSImage(named: .advanced)!

	override var nibName: NSNib.Name? {
		return NSNib.Name("AdvancedPreferenceViewController")
	}

	override func viewDidLoad() {
		super.viewDidLoad()

		// Setup stuff here
	}
}

In the AppDelegate, initialize a new PreferencesWindowController and pass it the view controllers. Then add an action outlet for the Preferences… menu item to show the preferences window.

AppDelegate.swift

import Cocoa
import Preferences

@NSApplicationMain
final class AppDelegate: NSObject, NSApplicationDelegate {
	@IBOutlet private weak var window: NSWindow!

	let preferencesWindowController = PreferencesWindowController(
		viewControllers: [
			GeneralPreferenceViewController(),
			AdvancedPreferenceViewController()
		]
	)

	func applicationDidFinishLaunching(_ notification: Notification) {}

	@IBAction func preferencesMenuItemActionHandler(_ sender: NSMenuItem) {
		preferencesWindowController.showWindow()
	}
}

API

protocol Preferenceable: AnyObject {
	var toolbarItemTitle: String { get }
	var toolbarItemIcon: NSImage { get }
}

class PreferencesWindowController: NSWindowController {
	init(viewControllers: [Preferenceable])
	func showWindow()
	func hideWindow()
}

FAQ

How is it better than MASPreferences?

  • Written in Swift. (No bridging header!)
  • Swifty API using a protocol.
  • Fully documented.
  • The window title is automatically localized by using the system string.
  • Less code (and less chance of bugs) as it uses NSTabView instead of manually implementing the toolbar and view switching.

Related

  • Defaults - Swifty and modern UserDefaults
  • LaunchAtLogin - Add "Launch at Login" functionality to your macOS app
  • DockProgress - Show progress in your app's Dock icon

You might also like my apps.

License

MIT © Sindre Sorhus