
Model-View-Controller (MVC)
The model layer holds data and instances in the model layer usually represent real things in the world of the user
The view layer contains objects that are visible to the user
The controller layer is where the application is managed. Controllers configure the views that the user sees and make sure that the view and model objects stay synchronized
Models and views do not talk to each other directly. Controllers sit squarely in the middle of everything, receiving messages and dispatching instructions
Interface Builder is an object editor that can create instances of objects and manipulate their properties. When you are done editing an interface, it does not generate code that corresponds to the work you have done
Auto Layout works by specifying position and size constraints for each view object in a scene. The constraints can be relative to neighboring views or to container views
A connection lets one object know where another object is in memory so that the two objects can communicate
An outlet is a reference to an object
An action is a method that gets triggered by a button or some other view that the user can interact with
@IBOutlet tells Xcode that you will connect these outlets to label objects using Interface Builder
When a UIButton is tapped, it calls a method on another object. The object is called the target. The method that is triggered is called the action
The @IBAction keyword tells Xcode you will be making these connections in Interface Builder
The ViewController is the target for both buttons
You set the properties in the ViewController to reference the label objects
A constant is denoted with the let keyword
A variable is denoted by the var keyword
Swift types are arranged into three basic groups: structures, classes, and enumerations
All three types have properties (values associated with a type), initializers (code that initializes an instance of a type), instance methods, and class or static methods
Optionals allow you to store either a value or no value at all
Arrays are strongly typed meaning they can only contain one type of value and are defined by Array<T> or [T]
Dictionaries are also strongly typed and are defined by Dictionary<T, T> or [T:T]
To forcibly unwrap an optional, you append a ! to its name
Optional binding works within a condition if-let statement where you assign the optional to a temporary constant of the corresponding non-optional type, if your optional has a value, then the assignment is valid and you proceed using the non-optional constant, if the optional is nil, then you can handle that case with an else clause
Enumerated returns a sequence of integers and values from its argument
String interpolation uses (...)
Every application has a single instance of UIWindow that serves as the container for all the views in the application
When you initialize a view programmatically, you use its init(frame:) designed initializer, which takes in one CGRect argument that will become the view's frame
A CGRect contains the members origin and size. Origin is a structure of type CGPoint and two CGFloat properties: x and y. The size is a structure of CGSize and has two CGFloat properties: width and height
Values are in points, not pixels
A view's frame is relative to its superview
The frame encompasses the entire view, the alignment rectangle only encompasses the content that you wish to use for alignment purposes
A constraint defines a specific relationship in a view hierarchy that can be used to determine a layout attribute for one or more views
A general rule of thumb, you need at least two constraints per dimension
A view's intrinsic content size acts as implicit width and height constraints
A property observer is a chunk of code that gets called whenever a property's value changes
A property observer is not triggered when the property value is changed from within an initializer
Delegation is an object-oriented approach to callbacks
You supply a single delegate to receive all of the event-related callbacks for a particular object and the delegate object can then store, manipulate, act on, and relay the information from the callbacks
You declare the view controller to conform to the delegates protocol
The protocol declares the methods that an object can call on its delegate
A view controller manages a view hierarchy. It is responsible for creating view objects that make up the hierarchy and for handling events associated with the view objects in its hierarchy
All view controllers inherit an important property: view, which pointers to a UIView instance that is the root of the view controller's view hierarchy
UIWindow has a rootViewController property and when a view controller is set as the window's rootViewController, that view controller's view gets added to the window's view hierarchy
When the application launches, the initial view controller for the main interface gets set as the rootViewController of the window
viewWillAppear is called just before a view controller's view is added to the window
Override viewDidLoad if the configuration only needs to be done once during the run of the app. Override viewWillAppear if you need the configuration to be done each time the view controller's view appears onscreen
loadView is overridden to create a view controller's view programmatically
PNG and JPEG are bitmap images
Use anchors to create constraints. Anchors are properties on the view that correspond to attributes that you might want to constrain to an anchor on another view
Constraints need to be added to the most recent common ancestor for the views associated with the constraint
Setting the active property on a constraint calls the addConstraint method on the appropriate view
View controllers expose two layout guides to assist with layout content: the topLayoutGuide and the bottomLayoutGuide which indicate the extent to which the view controller's view contents will be visible
UIEdgeInsets is a type of frame and every view has a property called layoutMargins that denotes the default spacing to use when laying out content which is an instance of UIEdgeInsets
layoutMarginsGuide exposes anchors that are tied to the edges of the layoutMargins
NSLayoutConstraint attributes: left, leading, top, width, centerX, firstBaseline, right, trailing, bottom, height, centerY, lastBaseline
UIControlEvents: touchDown, touchUpInside, valueChanged, editingChanged
Internationalization is making sure your native cultural information (language, currency, date format, number format, etc.) is not hardcoded into your application
i18n is short for internationalization and L10n is short for localization
Locale knows how different regions display symbols, dates, and decimals and whether they use the metric system
Localization creates application-specific substitutions for different region and language settings. Localization usually involves either generating multiple copies of resources (like images, sounds, and interface files) for different regions and languages or creating and accessing strings tables to translate text into different languages
Base internationalization creates the Base.lproj directory, which contains the main interface files and localizing individual interface files can then be done by creating just the Localizable.strings files
Line count 0 tells the text that their text should wrap to multiple lines if needed
A closure is a discrete bundle of functionality that can be passed around your code
Syntax: { (arguments) -> return type in // code }
If you change a constraint, you must ask the system to recalculate the frames when you are done with the view method layoutIfNeeded()
The default animation timing is an ease-in/ease-out timing function
Other timing functions: linear, ease-in, ease-out
Possible animation options: animation curve options, allowUserInteraction, repeat, autoreverse
Caveman debugging: strategically placing print() calls in your code to verify that functions and methods are being called and to log variable values to the console
You can delete a breakpoint by dragging it out of the gutter
Use print-object or po in the debugger command line to print objects
You can also use the print command, abbreviated p
A UITableView needs a view controller to handle its appearance, a data source for the number of rows to display, the data to be shown in those rows, and other tidbits that make a UITableView a useful UI and conforms to the UITableViewDataSource, and a delegate that can inform other objects of events involving the UITableView which conforms to the UITableViewDelegate
Classes can have two kinds of initializers: designated initializers and convenience initializers
A designated initializer is a primary initializer for the class. They ensure that all properties in the class have a value. Once it ensures that, a designated initializer calls a designated initializer on its superclass
You can utilize the free initializer that classes have when all of your class's properties have default values and you do not need to do additional work to create the new instance
The table view asks another object - its dataSource - what it should display
The dependency inversion principle states that 1. High-level objects should not depend on low-level objects. Both should depend on abstractions. 2. Abstractions should not depend on details. Details should depend on abstractions
UITableViewCellStyles: default, subtitle, value1, value2
The contentInset property is similar to padding for all sides of the scroll view
UITableView has an editing property which puts the UITableView into editing mode
The TableViewController is the table view's dataSource
You must keep the table view in sync with the underlying data store
The two available alert styles are UIAlertControllerStyle.actionSheet and UIAlertControllerStyle.alert
If the user can back out of a decision or if the action is not critical, then an .actionSheet is probably the best choice
Actions the user can choose from when shown an alert are instances of UIAlertAction
A design pattern solves a common software engineering problem
The consistent use of design patterns throughout the development process reduces the mental overhead in solving a problem so you can create complex applications more easily and rapidly
Delegation: One object delegates certain responsibilities to another object
Data source: provides data to another object when requested
A stack view allows you to create a vertical or horizontal layout that is easy to lay out and manages most of the constraints that you would typically have to manage yourself
The content hugging priority is like a rubber band that is placed around a view. The rubber band makes the view not want to be bigger than its intrinsic content size in that dimension. Each priority is associated with a value from 0 to 1000. A value of 1000 means that the view cannot get bigger than intrinsic content size on that dimension
The view with the higher content hugging priority is the one that does not stretch to fill the available space
The higher the priority value, the stronger the rubber band
The content compression resistance priorities determine how much a view resists getting smaller than its intrinsic content size
The view with the greater content compression resistance priority is the one that will resist compression and, therefore, not truncate its text
A UINavigationController maintains an array of view controllers presenting related information in a stack
Its view always has two subviews: a UINavigationBar and the view of topViewController
To dismiss the keyboard, you call resignFirstResponder() on the text field that is the first responder
endEditing is a convenient way to dismiss the keyboard without having to know which text field is the first responder. It will check to see if any text field in its hierarchy is the first responder
The cache will automatically remove objects if the system gets low on memory
// MARK: comments are a great way to organize methods in a file
Saving and loading 'data' almost always means saving and loading model objects
Archiving an object involves recording all of its properties and saving them to the filesystem
Classes whose instances need to be archived and unarchived must conform to the NSCoding protocol and implement its two required methods, encode(with:) and init(coder:)
Structs do not support inheritance and are value types rather than reference types
setNeedsDisplay() flags the view to be redrawn
A UIGestureRecognizer intercepts touches that are on their way to being handled by a view
UIGestureRecognizer state: possible, failed, began, cancelled, changed, recognized, ended
URLSession tasks are always created in the suspended state so we need to call resume on the task to start the web service request
Enumerations are a convenient way of defining and restricting the possible values for a variable
You tell Core Data what needs storing and let it work out how to store it
