Chapter 1: Cocoa Development Tools


command+shift+F // search project
shift+F // search current document


Simulator has a lot more memory than an actual device- all your computer memory compared to device.
command+shift+H // home button
command+L // lock phone


Service operated by Apple that allows app to be tested by up to 1,000 testers.


Can design in a storyboard which links the screens together, or each screen individually.
Design interface in Main.storyboard.


There are two types of connections to make between interface and code:
Outlets are variables that refer to objects in the interface. Using outlets, you can instruct a button to change color or size, or hide itself. There are also outlet collections, which allow you to create an array of outlets and choose which objects it contains in the Interface Builder.
Actions are methods in your code that are run in response to the user interacting with an object. These interactions include the user touching a finger to an object, dragging a finger, and so on.

Chapter 2: Programming with Swift

Design principles:
- safety: its strongly typed
- modernity: switch statements, closures, everything is an object
- full-portability with Objective-C

Don’t need to define the type of variables: compiler will do that.

Variables declared with let are constants, meaning it does not change.  Attempting to change the value of a constant is an error. Constants don’t have to be known at compile time: can think of as variables that only set once.

Variables and Constants

When you define a variable using var, you’re allowed to change its value. If you define one using let, it’s never allowed to change. Swift encourages you to use constants as much as possible, because they’re safer.

Constants in Swift are required to have values, otherwise compile error.

Variables (the nonconstant kind, that is) are allowed to not have a value, as long as you never try to access it.

var someVariable : Int
someVariable += 2

This is an error: someVariable doesn't have a value, so can't add 2 to it.

someVariable = 2
someVariable += 2

This works because someVariable has a value to add to.


You don’t need to define what type the variable is. Swift will infer its type from its initial value.

Implicit type of integer:
var anInteger = 2
Most types cannot be combined, because the compiler doesn’t know what the result would be.

"No value" (as opposed to zero) is referred to as nil and is its own type (its not an int).

However, recall that all variables in Swift are required to have values. If you want a variable to be allowed to sometimes be nil, you make it an optional variable. Optional variables are defined by using a question mark (?) as part of their type:

Optional integer, allowed to be nil:

var anOptionalInteger : Int? = nil
anOptionalInteger = 42

When you have an optional variable, you can unwrap it to get at its value. You do this using the ! character.

Note that if you unwrap an optional variable, and it has no value, your program will throw a runtime error, and the program will crash.

Optional types must be unwrapped using !:

anOptionalInteger = 2
1 + anOptionalInteger! // = 3
anOptionalInteger = nil
1 + anOptionalInteger!

Runtime error: anOptionalInteger = nil, can't use nil data

If you don’t want to unwrap your optional variables every time you want to use them, you can declare them as unwrapped, like this:

var unwrappedOptionalInteger : Int!
unwrappedOptionalInteger = 1
1 + unwrappedOptionalInteger // = 2

This lets you use their values directly, but can be unsafe (because it lets you get away with not unwrapping them when needed, which can make you forget that they can sometimes be nil). Use this with caution.

You can convert between different types in Swift. 
let aString = String(anInteger) // = "2"


A tuple is a simple collection of data. Tuples let you bundle multiple values together into a single value:

let aTuple = (1, "Yes")
let theNumber = aTuple.0 // = 1


let arrayOfIntegers : [Int] = [1,2,3]
// Type of array is implied
let implicitArrayOfIntegers = [1,2,3]

You can also create an empty array, but you must provide the type:
let anotherArray = [Int]()

If you define an array with the let keyword, its contents become immutable (i.e., it’s not allowed to change its contents).

var myArray = [1,2,3]
myArray.append(4) // = [1,2,3,4]

Array has methods: append; insert; removeAtIndex; reverse; count.


A dictionary is a type that maps keys to values. Dictionaries are useful for when you want to represent a collection of related information.

var dictionary = [
  "Captain": "Jean-Luc Picard",
  "First Officer": "William Riker",
  "Second Officer": "Data"

Subscripting can return or set values in dictionaries:
crew[“Captain"] // = "Jean-Luc Picard"

Dictionaries can use any type for key / values.

Control Flow

Want control flow over what gets executed when: use if statements, loops

If statements

if 1+1==2 {
  print("The math checks out")

Prints "The math checks out". { } braces are mandatory.

For-in loop to iterate over arrays

let loopingArray = [1,2,3,4,5]
var loopSum = 0

for number in loopingArray {
  loopSum += number

For-in loop over range of values

var firstCounter = 0
for index in 1..<10 {

Loops 9 times.

Range operators

..< means a range that starts at the first value, and goes up to but does not include the last value. For example, the range 5..<9 contains the numbers 5, 6, 7, and 8.

... means a range that includes the last number. The range 5...9 contains the numbers 5, 6, 7, 8, and 9.

For loop

var sum=0
for var i = 0; i < 3; i++ {
  sum += 1

While loop

var countDown = 5
while countDown > 0 {

Do-while loop

The do-while loop runs the code at least once, and then checks the condition:

var countUp = 0
do {
} while countUp < 5

If-let statement

Check if an optional variable has a value, and if it does, assign that value to a constant variable, and then run some code.

var conditionalString : String? = "a string"
if let theString = conditionalString? {
  println("The string is '\\(theString)'")
} else {
  println("The string is nil")

Prints "The string is 'a string'".


let integerSwitch = 3
switch integerSwitch {
case 0:
  println("It's 0")
case 1:
  println("It's 1")
case 2:
  println("It's 2")
default: // note: default is mandatory if not all
  // cases are covered (or can be covered)
  println("It's something else")

Prints "it's something else".

Can switch String values, tuples and ranges. The execution statement doesn’t automatically “fall through”, so don’t need to include the break keyword.  If switching boolean, mush include both options or is compile error.

Functions and Closures

func firstFunction() {

Functions can return a value to the code that calls them. When you define a function that returns a type, you must indicate the type of the data that it returns, by using the arrow (->) symbol:

func secondFunction() -> Int {
  return 123

You can pass parameters to a function, which it’s able to use to do work. When you define parameters for a function, it is also necessary to define the type of those parameters:

func thirdFunction(firstValue: Int, secondValue: Int) -> Int {
  return firstValue + secondValue
thirdFunction(1, 2)

A function can return a single value, as we’ve already seen, but they can also return multiple values, in the form of a tuple.

func fourthFunction(firstValue: Int, secondValue: Int) -> (doubled: Int, quadrupled: Int) {
  return (firstValue * 2, secondValue * 4)
fourthFunction(2, 4)
// Accessing by number:  
fourthFunction(2, 4).1 // = 16
// Same thing but with names:
fourthFunction(2, 4).quadrupled // = 16

When you create names for parameters, you define an external name for the parameter, as well as an internal name. The internal name is how the function refers to the parameter, and the external name is used by the code that calls the function. If you make a function that doesn’t have named parameters, each parameter only has an internal name.

Place a pound sign (#) in front of the parameter name to define a parameter with an external name that’s the same as its internal name.

A parameter with a variable number of values is called a variadic parameter. To do this, use three dots (...) to indicate that a parameter has a variable number of values. Inside the body of the function, the variadic parameter becomes an array, which you can use like any other.

Using Functions as Variables

Functions can be stored in variables. Declare a variable as capable of storing a function that takes certain parameters, and returns a value. Then store any function that takes those types of parameters and returns the same type of value in the variable.

var numbersFunc: (Int, Int) -> Int;
// numbersFunc can now store any function that takes two ints and returns an int
// Using the 'addNumbers' function from before, which takes two numbers // and adds them
numbersFunc = addNumbers
numbersFunc(2, 3) // = 5

Functions can also return other functions.


Another feature of Swift is that of closures—small, anonymous chunks of code that you can use like functions.

var sortingInline = [2, 5, 98, 2, 13]
sortingInline // = [2, 2, 5, 13, 98]


You define classes as the templates for your object.

class Vehicle {
  var color: String?
  var maxSpeed = 80

  func description() -> String {
    return "A \\(self.color) vehicle"

  func travel() {
    println("Traveling at \\(maxSpeed) kph")

Classes contain both properties and methods. Properties are variables that are part of a class, and methods are functions that are part of a class.  Code that’s in a method can access the properties of a class by using the self keyword, which refers to the object that’s currently running the code.

To define an instance of a class, define a variable and call the class’s initialiser.
var redVehicle = Vehicle()


When you define a class, you can create one that inherits from another. When a class inherits from another (called the parent class), it incorporates all of its parent’s functions and properties. In Swift, classes are allowed to have only a single parent class.

To create a class that inherits from another, you put the name of the class you’re inheriting from after the name of the class you’re creating. Inherited classes can override functions:

class Car: Vehicle {
  override func description() -> String {
    var description = super.description()
    return description + ", which is a car"

Classes that inherit from other classes can override functions in their parent class. This means that you can create subclasses that inherit most of their functionality, but can specialize in certain areas. To override a function, you re-declare it in your subclass and add the override keyword to let the compiler know that you aren’t accidentally creating a method with the same name as one in the parent class.  In an overridden function, it’s often very useful to call back to the parent class’s version of that function. You can do this through the super keyword, which lets you get access to the superclass’s functions.

Initialisation and Deinitialisation

Initialiser method called with when object created. Deinitiliser method called right before the object is removed from memory- when the retain count of an object drops to zero.

class InitAndDeinitExample {
  // Designated (i.e., main) initializer
  init () {
    println("I've been created!")
  // Convenience initializer, required to call the designated initializer (above)
  convenience init (text: String) {
    self.init() // this is mandatory
    println("I was called with the convenience initializer!")                 
  // Deinitializer
  deinit {
    println("I'm going away!")


Classes store their data in properties.  Properties, as previously mentioned, are variables or constants that are attached to instances of classes. Any property that you’ve added to a class can be accessed:

class Counter {
  var number: Int = 0
let myCounter = Counter()
myCounter.number = 2

This is known in Swift as a stored property. Computed properties use code to figure out their value. Computed properties provide a simpler interface to information stored in your classes.

To define a computed property, you declare a variable in the same way as you do for a stored property, but add braces ({ and }) after it. Inside these braces, you provide a get section, and optionally a set section:

class Rectangle {
  var width: Double = 0.0
  var height: Double = 0.0
  var area : Double {
    // computed getter
    get {
      return width * height
    // computed setter
    set {
      // Assume equal dimensions (i.e., a square)
      width = sqrt(newValue)
      height = sqrt(newValue)

When working with properties, you often want to run some code whenever a property changes. To support this, Swift properties let you add observers to your properties. These are small chunks of code that can run just before or after a property’s value changes.  Add braces after your property and include willSet and didSet blocks. These blocks each get passed a parameter—willSet, which is called before the property’s value changes, is given the value that is about to be set, and didSet is given the old value.

A lazy property is one that doesn’t get set up until the first time it’s accessed. This lets you defer some of the more time-consuming work of setting up a class to later on, when it’s actually needed. To define a property as lazy, you put the lazy keyword in front of it.


A protocol can be thought of as a list of requirements for a class. A protocol looks very much like a class, with the exception that you don’t provide any actual code—you just define what kinds of properties and functions exist, and how they can be accessed.

Once you have a protocol, you can create classes that conform to a protocol. When a class conforms to a protocol, it’s effectively promising to the compiler that it implements all of the properties and methods listed in that protocol.

The advantage of using protocols is that you can use Swift’s type system to refer to any object that conforms to a given protocol. This is useful, because you get to specify that you only care about whether an object conforms to the protocol—the specific type of the class doesn’t matter.


In Swift, you can extend existing types, and add additional methods and computed properties.

Access Control

Swift defines three levels of access control, which determines what information is accessible to which parts of the application:
Public classes, methods and properties are accessible by any part of the app.
Internal data is only accessible to the module in which they’re defined. A module is an application, library, or framework.
Private data is only accessible to the file in which it’s declared.

The kind of access control that a method or property can have depends on the access level of the class that it’s contained in. You can’t make a method more accessible than the class in which it’s contained. For example, you can’t define a private class that has a public method. By default, all properties and methods are internal.


Swift lets you define new operators, and overload existing ones for your new types.


Swift is a statically typed language. This means that the Swift compiler needs to definitively know what type of information your code is dealing with.

Generics allow you to write code that doesn’t need to know precisely what information it’s dealing with.  To create a generic type, you name your object as normal, and then specify any generic types between angle brackets. T is traditionally the term used, but you can put anything you like.

Interoperating with Objective-C

For example, to use the UIView class which is written in Objective-C, you can construct an instance just like any other Swift class:
var view = UIView(frame: CGRect(x: 0,y: 0,width: 100,height: 100))

To use classes and other code written in Objective-C in your Swift code, you fill out a bridging header.  Inside this header, you add #import statements for all of the Objective-C files you want to export to Swift. Then, inside your Swift code, you can use the Objective-C classes as if they had been originally written in Swift.

Importing Library
1. Drag the .xcodeproj file into the project navigator.
2. Select the Application project in the file explorer and it will bring up the project viewer. In here you can see the settings for the project and the target. Select the target and go to the Build Phases section.  Add the  framework as a target dependency of your application.
3. Add the framework to the Link Binary With Libraries section.
4. Add a new "Copy Files" build phase, set the destination to "Frameworks" and add framework to that. This will package the framework with your application as an embedded private framework.
5. Set the “Header Search Paths” (HEADER_SEARCH_PATHS) build setting to the correct path for the headers in your project. For example, if you added the submodule to your project as External/ObjectiveGit, you would set this build setting to External/ObjectiveGit/External/libgit2/include. If you see build errors saying that git2/filter.h cannot be found, then double-check that you set this setting correctly.
6. #import <ObjectiveGit/ObjectiveGit.h> as you would with any other framework. Or, if using Swift create a new Objective C file and have Xcode configure the bridging header.  In the bridging header file import the framework.


In Swift, just like in Objective-C, code is grouped into modules. When you define a framework or application, all of the code that’s added to it is placed within that target’s module. To get access to the code, you use the import keyword:
import AVFoundation

Memory Management

Objects in Swift are memory managed. When an object is being used, Swift keeps it in memory; when it’s no longer being used, it’s removed from memory.

The technique that Swift uses to keep track of which objects are being used and which are not is called reference counting. When an object is assigned to a variable, a counter called the retain count goes up by 1. When the object is no longer assigned to that variable, the retain count goes down. If the retain count ever reaches 0, that means that no variables are referring to that object, and the object is then removed from memory.

A retain cycle is where you have two objects that refer to each other, but are otherwise not referred to by any other part of the application. Because those objects refer to each other, their retain count is not zero, which means they stay in memory; however, because no variable in the rest of the application refers to them, they’re inaccessible (and consequently useless). Swift solves this using the concept of weak references. A weak reference is a variable that refers to an object, but doesn’t change the retain count of that object. You use weak references when you don’t particularly care whether an object stays in memory or not (i.e., your code isn’t the owner of that object).


Create an empty string literal:
let emptyString = ""
Create empty string using the String's type initialiser:
let anotherEmptyString = String()


In Cocoa, you’ll frequently find yourself working with chunks of arbitrary data that you need to save to or load from disk, or that you’ve downloaded from the network. Cocoa represents these as NSData objects.

If you have a string that you want to convert to an NSData, you can use the string’s dataUsingEncoding method, like so:

let stringToConvert = "Hello, Swift"
let data = stringToConvert.dataUsingEncoding(NSUTF8StringEncoding)

You can also load data from a URL or from a file location on disk. If the file is one of the resources built into your project, you first need to work out where on disk it’s being stored; once you have that, you can load its contents into memory.

To get the location of a built-in file, you first use the NSBundle class to determine where a given file is being stored on disk. Once you’ve done that, you construct an NSData object by providing it either a URL or a file path.

Loading from URL:

if let fileURL = NSBundle.mainBundle()     
  .URLForResource("SomeFile", withExtension: "txt") {
    let loadedDataFromURL = NSData(contentsOfURL:fileURL)

Loading from a file:

if let filePath = NSBundle.mainBundle()
  .pathForResource("SomeFile", ofType: "txt") {
    let loadedDataFromPath = NSData(contentsOfFile:filePath)

Serialisation and Deserialisation

You can also convert an object to data. To do this, you first make an object conform to the NSObject and NSCoding protocols, and then add two methods: encodeWithCoder, and an initializer that takes an NSCoder.

Design Patterns In Cocoa

- MVC pattern;
- delegation pattern (allows both your code and Cocoa to be highly flexible in determining what code gets run by whom);
- notifications (allow your code to watch for important events that happen within your app).


Fundamental design pattern in Cocoa.
Models are objects the contain data.  Purpose is to store data and provide it to other objects.
Views are objects that work directly with the user, providing information and receiving information back.
Controllers are objects that mediate between models and views, and contain the bulk of what some call the “business logic” of an application—the actual logic that defines what the application is and how it responds to user input.  At a minimum, the controller is responsible for retrieving information from the model and providing it to the view.


Delegation is Cocoa’s term for passing off some responsibilities of an object to another.  An example of this in action is the UIApplication object, which represents an application on iOS. This application needs to know what should happen when the application moves to the background.

An object that wants to let another object know that something is going to happen, or has happened, stores a reference to that object as an instance variable. This object is known as the delegate. When the event happens, it checks to see if the delegate object implements a method that suits the event—for delegates of the UIApplication class, for example, the application delegate is asked if it implements the applicationDidEnterBackground method. If it does, that method is called. An object can also be the delegate for multiple objects.

Chapter 3: Applications on OS X and iOS

On OS X and iOS applications are actually folders that contain the compiled binary plus any resources it needs.

When you compile a project in Xcode and generate an application, Xcode creates the application package, and copies in any necessary resources. If you’re creating a Mac application, you can then just zip it up and send it to anyone for them to run it. On iOS, it’s a little different, because apps must be code-signed and provisioned before being run on the device.

Applications, Frameworks, Utilities and More
Applications aren’t the only products that you can produce from Xcode. You can also generate frameworks, which are loadable bundles of code and resources that other applications (including your own) can use. One prime example of a framework is AppKit.framework, which is used by every Mac application. On iOS, the equivalent framework is UIKit.framework.

"Cocoa" is the term used by Apple to refer to the collection of libraries used by applications on OS X. On iOS, the equivalent term is “Cocoa Touch,” as it’s adapted for touchscreen devices.

What are apps composed of? To function apps require at a minimum:
1. the compiled library (the result of Xcode compiling and linking everything together)
2. An information file describing the app to the system (Info.plist file).

Using NSBundle to find Resources in Applications

NSBundle class allows your code to know where it is on the disk and how to get at the compiled resources.

NSBundle allows you to determine both URLs and plain file paths for resources on the disk. All you need to know is the name and type of the resource.

Absolute path of a resource:
let resourcePath = NSBundle.mainBundle() .pathForResource("SomeFile", ofType: "txt")
resourcePath is now a string containing the absolute path reference to SomeFile.txt, or nil.

URLs to resource:
let resourceURL = NSBundle.mainBundle() .URLForResource("SomeFile", withExtension: "txt")
resourceURL is now an NSURL, or nil


The sandbox restricts at a kernel level the system access of the app.  Designed to improve security: mandatory with iOS and OS X (if distributed via the Mac App Store).


Explanation of notifications.

Chapter 4: GUIs

Top-level object is the window.

Each screen is managed by an object called a view controller.  View controllers are classes that manage a single view as well as its subviews.

Applications load the UI from files called nib files (NeXT Interface Builder).  The Interface Builder in Xcode deals exclusively with views. The rest of Xcode handles the model and controller parts of your application, allowing you to concentrate on building the interface in relative isolation.

Nib Files and Storyboards

At the broadest level, nib files contain objects, and a storyboard is an organized grouping of interlinked nib files.

Nib files have the extension .nib or .xib. An .xib file is a nib file that’s stored in an XML-based format. Unless you are working with legacy code, you will rarely see .nib files anymore.

Because nib files simply contain objects, they can also contain objects that are instances of your own class. You can therefore create an instance of a class that is created when a nib is loaded, and connect it to your views.

The Interface Builder provides two ways to connect views to code: outlets (objects) and actions (methods).

Structure of a Nib File

Nib files contain a tree structure of objects. This tree can have many roots—for example, a nib file could contain two windows, each with its own collection of buttons and controls.


Storyboards are now the default way of creating your iOS UI in Interface Builder.  Starting with OS X 10.10, you can now use storyboards for your Mac apps as well.

In a nutshell, a storyboard is a collection of view controllers all linked together via segues.

Outlets and Actions

Relationship between button and application is called target-action relationship.  The object that is contacted is known as the target, and the message that is sent is called the action.

There are two types of connections between objects in the interface: 
1. Outlets are relationships in which one object "plugs in" to another to communicate.
2. Actions are relationships that describe what method another object should run when an event occurs.


Constraints keep the objects spaced apart. A constraint defines a relationship between a property of a view, like its height or the position of its left edge, and a property of another view.

The constraints menu has four parts:
Align defines how different views should line up relative to one another.
Pin defines width, height, and spacing.
Resolve Auto Layout Issues provides some solutions to common constraint issues.
Resizing Behavior defines how constraints should be applied when resizing views.

To address multiple sizes in iOS, the interface builder in Xcode has a concept called size classes. Size classes describe, in very general terms, whether the width and height of the current device’s orientation is either regular sized or compact sized:
On an iPhone 5S and 6 in portrait orientation, the height is regular, and the width is compact.
On an iPhone 5S and 6 in landscape orientation, both the height and width are compact.
On an iPhone 6 Plus in landscape orientation, the height is compact, and the width is regular.
On an iPad, the width and height are both regular.

Launch Screen Files - LaunchScreen.xib

When an application starts up, the first thing that iOS does is display a launch image.  The purpose of the launch image is to create an impression that the app is launching faster than it actually is. Launch images aren’t meant to be "splash images" (i.e., images that contain a big logo and company name, as is the case in some desktop apps like Photoshop). Instead, launch images should present a partial view of the loaded application—all of the toolbars and general shapes should be present, but nothing that looks like a button you can tap on.


Detail on animations.

Chapter 5: Closures and Operating Queues

The Swift language allows you to store code in variables. When you do this, the code is known as a closure, and Cocoa provides a number of tools that allow you to work with closures.

The operation queue lets you schedule closures to run in the future:
Provide code to a function that should be run when that function is complete, such as a download or a long-running computation
Enumerate over a collection of objects, and run some code on each one
Provide code for objects to call when they feel it’s necessary (e.g., event handlers)

In Objective-C, closures are known as blocks. Keep in mind that the terms block and closure are effectively identical.

Because code can be divided up into chunks using closures, you can also give closures to the system for it to run. The mechanism that you use to do this is called operation queues.

Operation queues allow for the UI to be responsive, and for all of the resources available are being used. More than one operation queue can exist at the same time, and there is always at least one operation queue, known as the main queue.

At its simplest, an operation queue runs operations in a first-in-first-out order. Operations are instances of the NSOperation class, which define exactly how the work will be done. NSOperations can be added to an NSOperationQueue; once they are added, they will perform whatever task they have been designed to do.

Getting the main queue (will run on the main thread):

var mainQueue = NSOperationQueue.mainQueue()
mainQueue.addOperationWithBlock() {
  // Add code here

Creating a new queue (will run on a background thread, probably):
var backgroundQueue = NSOperationQueue()

The only thing using multiple queues guarantees is that the operations running on them won’t block each other from running at the same time. It may create new threads, but not necessarily.

Any work involving the GUI can only be done from the main queue. If you access it from any other queue, your application will crash.

Chapter 6: Drawing Graphics and Views

Explanation of drawing graphics.

Chapter 7: SpriteKit

The SpriteKit framework designed for creating games. It is heavily optimized for rendering and animating 2D graphics.

Chapter 8: SceneKit

The SceneKit framework is a collection of classes that let you compose and present a 3D scene in your app. It works on both iOS and OS X, and is an incredibly simple way of drawing 3D graphics.

Chapter 9: Audio and Video

AV Foundation, is identical on both OS X and iOS, and is the one-stop shop for both AV playback and editing.

Chapter 10: iCloud and Storage

User Preferences

The NSUserDefaults class allows you to store settings information in a key-value based way.  Strings, Numbers, NSData, NSDate, Arrays and Dictionaries only can be stored in a defaults object.  Other types would need to be serialised to NSData first.

Create the default values dictionary:

let defaults = NSUserDefaults.standardUserDefaults()
let myDefaults = [
  "greeting": "hello",
  "numberOfItems": 1

Provide this dictionary to the defaults object:
Retrieve a string with the key "greeting" from the defaults object:
let greeting = defaults.objectForKey("greeting") as? String
Setting a preference:
let newGreeting = "hi there" defaults.setObject(newGreeting, forKey: "greeting")

Working with the Filesystem

Files may be stored in one of two places: either inside the application’s bundle or elsewhere on the disk.  In the bundle is reserved for files used at runtime: sounds; images etc.

Interface to the filesystem is the NSFileManager object, which allows you to list the contents of folders; create, rename, and delete files; modify attributes of files and folders; and generally perform all the filesystem tasks that the Finder does.

NSFileManger methods return true on success, and false if there was a problem.

let fileManager = NSFileManager.defaultManager()
let folderURL = NSURL.fileURLWithPath("/Applications/")
var error : NSError? = nil
let folderContents = fileManager.contentsOfDirectoryAtURL(folderURL!, includingPropertiesForKeys:nil, options:NSDirectoryEnumerationOptions(), error:&error)

Files can be placed in a temporary directory (subject to deletion by system anytime).

Return a string with the path of a directory can store files in:
let temporaryDirectoryPath = NSTemporaryDirectory()

NSFileManager can create directories and files:

let newDirectoryURL = NSURL.fileURLWithPath(temporaryDirectoryPath + "/MyNewDirectory")
var error : NSError? = nil
var didCreate = fileManager.createDirectoryAtURL(newDirectoryURL!, withIntermediateDirectories: false, attributes: nil, error: &amp;error)

if (didCreate) {
  // The directory was successfully created
} else {
  // The directory wasn't created (maybe one already exists at the path?)
  // More information is stored in the 'error' variable

Create files (note that the first parameter is the path (as a string), not an NSURL):
fileManager.createFileAtPath(newFilePath!, contents: newFileData, attributes: nil)
Delete files: nb these are permanently deleted, not sent to trash:
fileManager.removeItemAtURL(newFileURL!, error: nil)
Move files:
fileManager.moveItemAtURL(sourceURL!, toURL: destinationURL, error: nil)
Copy files:
fileManager.copyItemAtURL(sourceURL!, toURL: destinationURL, error: nil)
Access location of user’s documents folder:

let URLs = fileManager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask) as [NSURL]
let documentURL = URLs[0]

Create additional:
let fileURL = documentURL.URLByAppendingPathComponent("Example.txt")

Sandboxed Apps

If you want to put your application in the Mac App Store, it must be sandboxed. Apple will reject your application if it isn’t. All iOS apps are automatically sandboxed by the system. An application that runs in a sandbox may only access files that exist inside that sandbox.

One way that you can let the user indicate that your app is allowed to access a file is to use an NSOpenPanel or NSSavePanel. These are the standard open and save windows that you’ve seen before; however, when your application is sandboxed, the panel being displayed is actually not being shown by your application, but rather by a built-in system component called Powerbox. When you display an open or save panel, Powerbox handles the process of selecting the files; when the user chooses a file or folder, it grants your application access to the specified location and then returns information about the user’s selection to you.

let panel = NSOpenPanel()
panel.canChooseDirectories = true
panel.canChooseFiles = false
panel.beginWithCompletionHandler() {
  (result : Int) in
  let theURL = panel.URL
  // Do something with the URL that the user selected;
  // we now have permission to work with this location

Security-Scoped Bookmarks

There are two kinds of security-scoped bookmarks:
- app-scoped bookmarks, which allow your application to retain access to a file across launches; and
- document-scoped bookmarks, which allow your app to store the bookmark in a file that can be given to another user on another computer.

To enable app-scoped bookmarks, you open the Entitlements file and add the following entitlement: Set this entitlement to YES.

iCloud storage

iCloud allows your applications to store files and key-value pairs on Apple’s servers.

Chapter 11: Cocoa Bindings

Can use bindings for simpler MVC applications that just need to bind view to model (no controller).  Bindings are connections between views and objects, where the contents of the object are used to directly drive what the view displays. Bindings are only available in OS X.

Chapter 12: Table Views and Collection Views

In both OS X and iOS, a table view is designed to provide a list of data while a collection view is designed to show a grid of data.

Chapter 13: Document-based Applications

Documents are represented by UIDocument (iOS) and NSDocument (OS X) classes.

A document object (i.e., a subclass of NSDocument or UIDocument) is both a model and a model-controller in the model-view-controller paradigm.

Chapter 14: Networking

The Berkeley sockets API, the fundamental networking and connectivity API used on Windows and Unix OSes (which includes OS X and iOS), is available, allowing you to make connections to any computer on the network and send and receive data.


The NSURL class represents a URL:
let myURL = NSURL(string: "")

Because calling NSURL’s constructor can result in nil (if the URL is not well formed), it always returns an optional.  Need to use ? and ! to unwrap it.
let host = myURL = relativeURL?.host

A file URL looks like file://localhost/Applications
let myFileURL = NSURL(fileURLWithPath:"/Applications/")


Once you have an NSURL object that points to where your resource is located, you con‐ struct an NSURLRequest. While NSURL points to where the resource is on the network, NSURLRequest describes how it should be accessed. For example, if an HTTP request, which request methods, what the request body should be an so on.

Can usually make a NSURL request using NSURLRequest(URL:) method:
let urlRequest = NSURLRequest(URL:myURL!)

If you want to send a POST request or make changes to the request, you can use NSMutableURLRequest. This is the mutable version of the NSURLRequest class, and allows you to configure the request after you create it.

let mutableRequest = NSMutableURLRequest(URL: myURL!) mutableRequest.HTTPMethod = "POST"


Once you have an NSURLRequest to use, you can go ahead and execute that request on the network. Because network requests aren’t instant, your code needs to be able to manage the life cycle of the connection. This is done for you by the NSURLSession object, which represents a connection in progress.

NSURLSession is comprised of four major objects:
NSURLSessionConfiguration: object representing configuration to be used for a session.
NSURLSessionTask: represents an individual task to be handled by the session.  Has methods to cancel, suspend and resume the task.
NSURLSession: responsible for performing any tasks sent to it.  Generally won’t need to use its delegate.

NSURLResponse and NSHTTPURLResponse

If making an HTTP request, the server response is an instance of the NSHTTPURLResponse, which also includes the status code and the headers sent by the server.

You don’t generally create your own NSURLResponse instances, but rather get them from an NSURLSession or NSURLConnection object when it first successfully gets a response from the server and starts downloading content.

Chapter 19: Non-standard Apps

Status Bar Items

Status items can display any text, image, or view when clicked, and can display either a menu or a custom view. You create a status item by asking the system’s status bar to create an NSStatusItem for you; you then customize the status item by setting its title text, image, or view, and providing it with an NSMenu or other view to display when it’s clicked.

You must keep a reference to the NSStatusItem object that you get from the NSStatusBar class. If you don’t, the object will be released from memory and removed from the status bar.

If you are writing an application that only shows a status item, you likely don’t want to show the dock icon. To implement this, set the Application is agent (UIElement) value in the application’s Info.plist file to YES, and the app will not show a dock icon.