Creating managed objects

import Foundation
import CoreData

extesion Note {
	@NSManaged var creationDate: NSDate?
	@NSManaged var text: String?
	@NSManaged var notebook: Notebook?
}
import Foundation
import CoreData

extesion NSManagedObject {
	convention init(text:String = "New Note", context: NSManagedObjectContext){
		if let ent = NSEntityDescription.entityForName("Note",
			inManagedObjectContext; context){
			self.init(entity: ent, insertIntoManagedObjectContext: context)
			self.text = text
			self.creationDate = NSDate()
		} else {
			fatalError("Unable to find Entity name!")
		}
	}
}

relationship

// Don't worry about the @NSManaged thing.
// it's just a cue to the compiler that the property
// will be managed by Core Date
class Note: NSManagedObject {
	@NSManaged var notebook : Notebook
}

class Notebook: NSManagedObject {
	@NSManaged var note : ????
}
import CoreData
struct CoreDataStack {
	// MARK: - Properties
	private let model : NSManagedObjectModel
	private let coordinator : MSPersistentStoreCoordinator
	private let modelURL : NSURL
	private let dbURL : NSURL
	let context : NSManagedObjectContext

	// MARK: - Initializers
	init?(modelName: String){

		guard let modelURL = NSBundle.mainBundle().URLForResource(modelName,
			withExtension: "momd") else {
				print("Unable to find \(modelName)in the main bundle")
				return nil}
		self.modelURL = model URL

		// Try to create the model from the URL
		guard let model = NSManagedObjectModel(contentsOfURL: modelURL) else{
			print("unable to create a model from \(modelURL)")
		}
		self.model = model

		coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)

		context = NSManagedObjectContext(concurrencyType: .
			MainQueueConcurrencyType)
		context.persistentStoreCoordinator = coordinator

		// Add a SQLite store located in the documents folder
		let fm = NSFileManager.defaultManager()

		guard let docUrl = fm.URLsForDirectory(.DocumentDirectory, inDomains: UserDomainMask).first else {
			print("manage to people the document folder")
			return nil
		}
	}
}

Core Data intro

-core data intro
-core data architecture
-create a model, managed objects, and begin our own app

core data
Model(managed objects), View, Controller

Object Model
(aka “managed Object Model”)
-specifies app classes and relationships

Managed Object
-class:NSManagedObject
-example:a character of a game app
-saves the contents of its properties to a DB file

Context
-class:NSManagedObject+Context
-imagine as a place
-where objects live and where operations take place

Fetch request
-searches context for certain managed objects

Fetched Results Controller
-part of controller layer
-controls how data from a fetch request is displayed in a view

Stores
-where managed objects are stored

Store coordinator
-allow you to have multiple stores

The iOS file system

The iOS file system
The sandbox
Subfolders of the sandbox
Writing and reading to the file system

“sandbox”: where the app keeps all of its “stuff”.

Sandbox
Bundle Container – MyApp.app
-> executable code, resources
Data Container – Documents, Library, Temp
-> user data(Documents/Inbox), non-user data(Library/Applications Support, Library/Caches)
iCloud Container – …

Library/Preferences/info.myapp.mobile.plist

*Documents: important stuff
*Caches:
*Library:

1. Find where the sandbox is.
2. Write to a file

-NSFileManager to get the path to the sandbox
-String to write or read text files
-NSData to write or read binary files

func sandboxPlayground(){
	let fm = FileManager.default
	let urls = fm.urls(for:.documentDirectory, in: .userDomainMask)
	let url = urls.last?.appendingPathComponent("file.txt")

	do {
		try "Hi There!".write(to: url!, atomically: true, encoding: String.Encoding.utf8)
	} catch { 
		print("Error while writing")
	}

	do {
		let content = try String(contentsOf: url!, encoding: String.utf8)

		if content == "Hi There!"{
			print("yay")
		} else {
			print("oops")
		} 
	} catch {
		print("Something went wrong")
	}

}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
	
	sandboxPlayground()
	return true
})

ViewController.swift

func checkIfFirstLaunch(){
	if UserDefaults.standard.bool(forKey: "HasLaunchedBefore"){
		print("App has launched before")
	} else {
		print("This is the first launch ever!")
		UserDefaults.standard.set(true, forKey: "HasLaunchedBefore")
		UserDefaults.standard.set(0.0, forKey: "Slider Value Key")
		UserDefaults.standard.synchronize()
	}

	func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool{
		print("App Delegate: will finish launching")
	}

}
override func viewDidLoad(){
	super.viewDidLoad()

	do {
		audioPlayer = try AVAudioPlayer(contentsof: receivedAudio.filePathUrl as URL)
	} catch _ {
		audioPlayer = nil
	}
	audioPalyer.enableRate = true

	audioEngine = AVAudioEngine()
	do {
		audioFile = try AVAudioFile(forReading: receivedAudio.filePathUrl as URL)
	} catch _ {
		audioFile = nil
	}

	sliderView.value = UserDefaults.standard.float(forKey: SliderValueKey)

	setUserInterfaceToPlayMode(false)
}

	@IBAction func playAudio(_ sender: UIButton){
		let pitch = sliderView.value

		playAudioWithVariablePitch(pitch)
		setUserInterfaceToPlayMode(true)

		UserDefaults.standard.set(sliderView.value, forKey: SliderValueKey)
	}

Before we diveinto

default database <- system-wide feault, language defaults, app-specific defaults NSUserDefaults.standardUserDefaults() -> shared defaults object

key, value
“address” -> “P. Sherman, 42 Wallaby Way, Sydney”

NSUserDefaults.standardUserDefaults().valueForKey(key:String)

stringForKey(key:String), boolForKey(key:String), floatForKey(key:String)

NSUserDefaults.standardUserDefaults().setValue(AnyObject?, key:”keyString”)

import UIKit
import Foundation

class ViewController: UIViewController {
	@IBOutlet var mainView: UIView!
	@IBOutlet weak var midnightThemeLabel: UILabel!
	@IBOutlet weak var themeSwitch: UISwitch!
	@IBOutlet weak var titleLabel: UILabel!
	@IBOutlet weak var imageView: UIImageView!

	override func viewDidLoad(){
		super.viewDidLoad()
		if let weWantMidnight = NSUserDefaults.standardUserDefaults().valueForKey("midnightThemeOn") {
			if weWantMidnight as Bool {
				switchToMidnight()
				print("we lik midnight")
			} else {
				print("we like daylight")
			}
		} else {
		NSUserDefaults.standardUserDefaults().setValue(false, forKey:"midnightThemeOn")
		print("This is the first launch ever!")
		}
	}
}

Persistence

Persistence: Saving data to a place where it can be re-accessed and retrieved upon restart of the device or app.

Necessary for any app that wants to store data log term and keep it available to the user.

NSUser Defaults
-essentially, a persistent dictionary
-user preferences
-saves data in plist file
-data, string, number, data, array, dictionary
-keep NSUserDefaults < 1MB 1.Store thousands of notes, images, and geolocations 2. Store m4v files 3. Store TableViewCollectionView user preference

Asynchronous

@IBAction func simpleAsynchronousDownload(_ sender: UIBarButtonItem){
	let  url = URL(string: BigImages.shark.rawValue)

	let downloadQueue = DispatchQueue(label: "download", attributes: [])

	downloadQueue.async {() -> Void in

		let imgData = try? Data(contentsOf: url!)

		let image = UIImage(data: imgData!)

		DispatchQueue.main.async(execute: {()-> Void in
			self.photoView.image = image
		})
	}
}
func withBigImage(completionHandler handler: @escaping(_ image: UIImage) -> Void){
	
	DispatchQueue.global(qos: .userInitiated).async{() -> Void in
		if let url = URL(string: BigImages.whale.rawValue), let imgData = try? Data(contentsOf: url), let img = UIImage(data: imgData){

			// all set and done, run the completion closure!
			DispatchQueue.main.async(execute: {() -> Void in
				handler(img)
			})
		}

	}
}

Variable Capture at last

//: Variable Capture at last!!!

typealias IntMaker = (Void)->Int

func makeCounter()->IntMaker{
	var n = 0
	func adder()->Int{
		n + n + 1
		return n
	}

	return adder
}

let counter1 = makeCounter()
let counter2 = makeCounter()

counter1()
typealias BinaryFunc = (Int, Int) -> Int

var z = 42.42

func g(x:Int)->Double{
	return Double(x) / z
}

The answer to life the universal and everything

let deepThought = {(ask question: String) in
	return "The answer to\"\(question)\" is \(7 * 6)!"}

deepThought(ask: "how old are you")

Adding closures to an Array

let sum = {(a:Int, b:Int) -> Int in return a + b}
let sumf = {(a:Float, b:Float) -> Float in return a + b}

let closures = [sum, sumf]
func foo(x:Int) -> Int{
	return 42 + x
}

let bar = {(x: Int) -> Int
	in
	42 + x
}
func curly(n:Int) -> Int{
	return n * n
}

func larry(x: Int) -> Int{
	return x * (x + 1)
}

func moe(m: Int) -> Int{
	return m * (m - 1) * (m - 2)
}

var stooges = [curly, larry, moe]
stooges.append(bar)

for stooge in stooges{
	stooge(42)
}

func baz(x:Int)->Double{
	return Double(x) / 42
}

type Alias

//: Typealias

typealias Integer = Int

let z: Integer = 42
let zz: Int = 42

// (Int)->Int
typealias IntToInt = (Int)->Int

typealias IntMaker = (Void)->Int