coredata

-How the table displays changes
-How a user can add a new note
-Saving and persisting changes
-Memory management

class CoreDataTableViewController: UITableViewController {
	
	var fetchedResultsController : NSFetchedResultsController<NSFetchRequestsResult>?{
		didSet {
			fetchedResultsController?.delegate = self
			executeSearch()
			tableView.reloadData()
		}
	}

	init(fetchedResultsController fc : NSFetchedResultsController<NSFetchRequestResult>, style: UITableViewStyle = .plain){
		fetchedResultsController = fc
		super.init(style: style)
	}

	required init?(coder aDecoder: NSCoder){
		super.init(coder: aDecoder)
	}
}
class NotebooksViewController: CoreDataTableViewController {
	
	// MARK: Life Cycle

	overeride func viewDidLoad(){
		super.viewDidLoad()

		title = "CoolNotes"

		let delegate = UIApplication.shared.delegate as! AppDelegate
		let stack = delegate.stack

		let fr = NSFetchRequest<NSFetchRequestResult>(entityName: "Notebook")
		fr.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true), NSSortDescriptor(key: "creationDate", ascending: false)]

		fetchedResultsController = NSFetchedResultsController(fetchRequest:  fr, managedObjectContext: stack.context, sectionNameKeyPath: nil, cacheName: nil)

	}

	override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
		let nb = fetchedResultsController!.object(at: indexPath) as! Notebook

		let cell = tableView.dequeueReusableCell(withIdentifier: "NotebookCell", for: indexPath)

		cell.textLabel?.text = nb.name
		cell.detailTextLabel?.text = "\(nb.notes!.count) notes"

		return cell
	}
}

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

Git log

Forking a repository
Reviewing another developer’s changes
Knowing what changes to make

Forking is an action that’s done on a hosting service, like GitHub. Forking a repository creates an identical copy of the original repository and moves this copy to your account. You have total control over this forked repository. Modifying your forked repository does not alter the original repository in any way.

GoogleChrome lighthouse
https://github.com/GoogleChrome/lighthouse

[vagrant@localhost ~]$ mkdir lighthouse
[vagrant@localhost ~]$ cd lighthouse
[vagrant@localhost lighthouse]$ git clone https://github.com/GoogleChrome/lighthouse.git
Cloning into ‘lighthouse’…
remote: Counting objects: 22863, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 22863 (delta 3), reused 2 (delta 2), pack-reused 22852
Receiving objects: 100% (22863/22863), 16.75 MiB | 998.00 KiB/s, done.
Resolving deltas: 100% (16111/16111), done.
Checking connectivity… done.
[vagrant@localhost lighthouse]$ ls
lighthouse
[vagrant@localhost lighthouse]$ cd lighthouse
[vagrant@localhost lighthouse]$ ls
AUTHORS chrome-launcher lighthouse-core package.json yarn.lock
CONTRIBUTING.md docs lighthouse-extension plots
LICENSE jsconfig.json lighthouse-logger readme.md
assets lighthouse-cli lighthouse-viewer typings

git shortlog displays an alphabetical list of names and the commit messages that go along with them. If we just want to see just the number of commits that each developer has made, we can add a couple of flags: -s to show just the number of commits (rather than each commit’s message) and -n to sort them numerically (rather than alphabetically by author name).

Filter By Author
$ git log –author=Surma

$ git show 5966b66