
An iOS application is a giant run loop. It waits for user input and gets interrupted by external signals such as phone calls, push notifications, home button press, and other app life cycle events
Callback methods to UIAppDelegate: application:willFinishLaunchingWithOptions:, application:didFinishLaunchingWithOptions:, applicationDidBecomeActive:, applicationDidEnterBackground:, applicationWillResignActive:, applicationWillEnterForeground:
Your code can be grouped into the following layers of responsibility: storage layer, service layer, business logic layer, and UI layer
The key to a happy and healthy iOS codebase is a skinny controller
The business logic layer helps us keep services, storages, and other layers decoupled from each other and tells them what to do to achieve results. This layer makes your application useful
SOLID principles: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion
Structs and classes have properties, methods, subscripts, initializers, can be extended, and conform to protocols
Classes are reference types
Structs are value types
Properties in Objective-C are used to store data in instances of classes
Protocols are declarations of what a type that adopts them should implement
Categories allow you to add additional methods to a class or type without subclassing
Categories cannot add new properties
Categories are globally applied to all instances of the type
Blocks are an executable piece of code that will be used at a later time
Blocks retain a reference to everything put in them unless otherwise specified with __block or __weak
Singleton is a class that returns only one-and-the-same instance no matter how many times you request it
The Delegate pattern is a variation of the Observer pattern where only one object can observe events coming from another objecct
Delegates are a one-to-one relationship
KVO (Key-Value Observation) allows you to observe changes on properties in iOS
Many-to-one relationship. Multiple objects can subscribe to changes in a property of another object. As soon as that property changes, all objects subscribing to it will be notified
Implementation uses instance variables defined with properties to store the value of the property. When you assign a property it will call willChangeValueForKey: and didChangeValueForKey: to trigger the change broadcast to observers
The main point of entry into iOS apps is UIApplicationDelegate. UIApplicationDelegate is a protocol that your app has to implement to get notified about user events such as app launch, app goes into background or foreground, app is terminated, a push notification was opened, etc.
When an iOS app is launched the first thing called is application:willFinishLaunchingWithOptions:. This method is intended for initial application setup
The options identify if the app was called to handle a push notification or url or something else. Return true if your app can handle the given activity or url
Every time your app becomes active, applicationWillEnterForeground: is called
applicationWillResignActive:, applicationDidEnterBackground:, applicationWillTerminate:
Use View Controllers to get lifecycle callbacks for the view that the VC is managing and to get handy built-in system integrations to present and dismiss VCs using UINavigationController, modal presentation, or parent/child containment API
Lifecycle callbacks: viewWillAppear: viewDidAppear: viewWillDisappear: viewDidDisappear:
viewDidLoad(): gets called once when your VC's view was loaded in memory for the first time. Do any additional setup and initializations here. Most of your custom view initialization and autolayout set will go here. Also, start your services and other async data-related stuff here
Use viewWillAppear(): to do final UI customizations, hook up UI observers, etc.
We connect with backend APIs via HTTP
HEAD returns header information about a response
GET returns actual data for the resource your requested
POST posts something to your server
PATCH is used to change a resource's data
PUT replaces everything about the resource with the data you submit leaving on the unique ID intact
DELETE destroys a resource on the backend
Contracts between server and client were made for the purpose of not only convenience but consistency and predictability
REST is an API architecture that revolves around resources and HTTP verbs. Each resource is represented by a set of endpoints that can receive some of the HTTP verb requests to do various CRUD (Create, Read, Update, Destroy) operations
A service layer in your application usually has a networking/HTTP manager like NSURLSession, an APIClient object which actually performs HTTP requests against your API domain and is usually responsible for signing every request with authentication token/credentials, and a set of service objects that work with individual resources of your RESTful API
There are two ways you can issue HTTP requests with NSURLSession: either by receiving a completion handler block callback or by implementing delegate methods and receiving notifications as the data comes back
Don't block the main UI thread
NSJSONSerialization is the go-to tool for JSON dictionaries/arrays/primitives serialization
Map your objects into your custom domain model objects
You can use NSURLSession to download an image at a given URL as binary data, convert it from NSData to UIImage, and then display it in a UIImageView
In-memory cache could be as simple as a Dictionary that keeps reference to UIImage objects and uses the URLs they were downloaded from as unique keys or it could actually be NSCache that performs similar stuff for you and also can be configured
Database storage is used for image caching when you save downloaded image binary to Core Data or a similar database
NSCoding is a protocol for data serialization for data-storing operations with NSUserDefaults, NSFileManager, and Keychain
NSUserDefaults is a key-value storage that can persist serialized NSCoding compliant objects and primatives
Typically used for some locally stored user preferences and/or flags
It is not secure and does not persist between app installs
Keychain is a key-value store that is encrypted by the system and persists between app reinstalls
Core Data is an object graph and persistence framework
You need to serialize your data into NSManagedObjects before saving them to the Core Data database
GCRect is a struct that represents a rectangle that a view is placed at. It has an origin with x and y values, and a size with width and height values
The higher the compression resistance is, the less chance it's going to 'budge' under the other constraint's pressure to compress it
Hugging priority defines how likely is it the view will grow under pressure from other constraints
All UI changes have to be done on the main thread
frame, bounds, center, transform, alpha, and backgroundColor are all animatable with UIKit's animateWithDuration
Core Animation is used for more advanced animations
Using singletons to store a global state is never a good idea due to race conditions and other types of data overrides
The main purpose if the UI layer is to display UI elements on the screen and to take user input in and delegate it to the rest of your application
The service layer is responsible for all external communication your application has
The Single Responsibility Principle (SRP) states that every module should have only one responsibility and reason to change
The Open/Closed Principle states that your modules should be open for extension but closed for modification. You should be able to extend the behavior of your objects through inheritance, polymorphism, and composition by implementing them using interfaces, abstractions, and dependency injection
The Liskov Substitution Principle states that objects in a program should be replaceable with instances of their subtypes without altering the correctness of the program. When you inherit from a class or an abstract class or implement an interface, your objects should be replaceable and injectable wherever that interface or class that you subclassed from was used
The Interface Segregation Principle says many client-specific interfaces are better than one general-purpose interface. No client should be forced to depend on and implement methods it does not use
The Dependency Inversion Principle states, depend on abstractions, not concretions
When yyou create an object, you supply and inject all of its dependencies upon it's initialization or configuration rather than let the object create or fetch/find its dependencies for itself
The functional programming paradigm avoid mutability and state change
The Factory Method pattern is used to replace class constructors by abstracting and hiding object's initialization so that the type can be determined at runtime
The Adapter design pattern helps you adapt the interface of one object to the interface of another
The Decorator pattern is a wrapper around another class that enhances its capabilities. It wraps around something that you want to decorate, implements its interface, and delegates messages sent to it to the underlying object or enhances them or provides its own implementation
The Command design pattern has an object that represents an operation that you would like to execute and it has its own state and logic to perform on top of the underlying operation
The Template design pattern has a base class that outlines the algorithm of what needs to be done. The base class has several abstract methods that are required to be implemented by its concrete subclasses. These methods are called hook methods. Users of the Template Method classes only interact using the base class that implements the algorithm steps, concrete implementations of those steps are supplied by subclasses
Typically we think of NSUserDefaults as a solution to store user settings or preferences or tokens
NSManagedObjects represent data stored in the database. You can think of them as model objects
NSManagedObjectContext allows you to insert, save, and retrieve NSManagedObjects from the database
NSFetchRequest is a query object that you use to retrieve NSManagedObjects from the database, optionally filtered with an NSPredicate and sorted with an NSSortDescriptor
