App Development with Swift cheat sheet
App Development with Swift · Keep the key ideas within reach.
Swift Language Fundamentals
letbinds a value once and cannot be reassigned;varis mutable. The type is fixed at compile time in both cases and is inferred from the initializer when no annotation is written.Integer literals default to
Intand floating-point literals toDouble; no implicit numeric conversion exists, soInt(3.9)truncates toward zero and mixed-type arithmetic requires explicit conversions.Structures, enumerations, and tuples are value types copied on assignment and argument passing; classes are reference types, so copies of a reference share one instance.
===and!==compare class instance identity;==requiresEquatableconformance and compares values. Identity operators cannot be applied to value types.String interpolation
\(expr)inserts any value into a literal; multi-line literals use triple double quotes, and text inside double-quoted single hash delimiters turns off interpolation and escape processing.T?is shorthand forOptional<T>, andnilis assignable only to optional types.Anyholds values of any type whileAnyObjectholds class instances.Access levels, narrowest first:
private(enclosing declaration and same-file extensions),fileprivate,internal(the default, whole module),public, andopen(public plus subclassable and overridable outside the module).typealiasgives an existing type a second name and creates no new type, so the alias and the original type are interchangeable everywhere.Range operators:
a...bis closed,a..<bis half-open, anda...or...ais one-sided; ranges and the~=operator back the pattern matching used byswitchcases.
Control Flow, Functions, and Closures
switchmust be exhaustive over the matched type, performs no implicit fallthrough, and supports range, tuple, andwhere-clause patterns; thefallthroughkeyword continues execution into the next case body.guardrequires itselseblock to exit scope viareturn,break,continue,throw, or a Never-returning call, and names bound byguard letstay visible for the rest of the enclosing scope.A parameter's internal name doubles as its external argument label; an underscore before the name removes the label, and a default value makes that argument omittable at the call site.
Variadic parameters such as
Int...collect zero or more arguments into an array;inoutparameters mutate the caller's variable, which must be passed with an ampersand prefix.stride(from:to:by:)excludes the end value whilestride(from:through:by:)includes it;repeat-whileevaluates its condition after the body, guaranteeing at least one iteration.Closures use the form
{ (parameters) -> ReturnType in statements };$0,$1are shorthand parameter names, and a trailing closure may be written after the call parentheses.Closures are non-escaping by default and may not outlive the call;
@escapingis required for stored or delayed execution, as with completion handlers.Closures capture referenced variables rather than copies of them; a capture list such as
[weak self]or[unowned self]changes ownership and breaks retain cycles.deferblocks run at scope exit in reverse order of their declaration, on every exit path including a thrown error.
Data Modeling with Structures, Classes, Enumerations, and Protocols
A structure with no custom initializer receives a synthesized memberwise initializer covering all stored properties in declaration order; classes never receive a memberwise initializer.
Struct and enum methods that assign to stored properties must be marked
mutating, becauseselfis immutable inside non-mutating methods of value types.Class initialization runs in two phases: every stored property must be initialized before
selfis used or an instance method is called, andconvenienceinitializers delegate withself.init.deinitexists only on classes and runs automatically when the final strong reference is released; arequired initforces every subclass to implement that initializer.Enumeration cases may carry associated values extracted by
case let .name(value)in a switch; declaring a raw type gives each case arawValueand a failableinit?(rawValue:).CaseIterablesynthesizesallCasesonly when no case has associated values, andindirectmarks an enumeration whose cases recursively contain the enumeration itself.Protocol extensions supply default implementations of requirements; members declared only in an extension are dispatched statically rather than through dynamic polymorphism.
Equatable,Hashable, andCodableare synthesized when every stored property conforms, andIdentifiablerequires anidproperty.some Pis an opaque concrete type chosen by the callee whileany Pis an existential box; protocol compositionA & Brequires both.finalblocks subclassing andstaticblocks overriding.
Collections, Optionals, and Error Handling
Arrayis ordered and indexed byInt;DictionarymapsHashablekeys to values with no guaranteed order;Setstores uniqueHashableelements with no guaranteed order.All three standard collections have value semantics: assignment or parameter passing copies the collection, so mutating the copy leaves the original unchanged.
Subscripting a dictionary with a key returns an optional that is
nilfor a missing key; assigningnilthrough that subscript removes the key-value pair.mappreserves element count;compactMapdiscardsnilresults and returns non-optionals;flatMapconcatenates nested sequences;reduceandreduce(into:)fold to a single value.sorted()returns a new array whilesort()mutates in place;filterreturns a new collection, andfirst(where:)andfirstIndex(of:)return optionals.trymarks a throwing call;do/catchhandles errors, and a non-throwing function must handle or propagate them.try?givesnilon failure, whiletry!traps at runtime.Custom error types conform to
Error, most often as an enumeration whose cases describe each failure, andcatchclauses match those cases by pattern.Optional binding with
if letorguard letshadows the original name;if case letandguard casematch enum cases carrying associated values without a full switch.??unwraps an optional or substitutes a default; chained access with?.short-circuits tonilat the first missing link and always produces an optional result.
User Interfaces and App Architecture
SwiftUI views are value types conforming to
Viewwhosebodyreturnssome View; a state change re-evaluatesbody, and the framework diffs the result against the previous hierarchy.@Stateowns view-local mutable storage that persists across body updates;@Bindingreferences state owned by an ancestor and allows two-way writes, passed with the$prefix.@StateObjectcreates and owns anObservableObjectfor the view's lifetime;@ObservedObjectonly observes an instance owned elsewhere;@EnvironmentObjectreads an object injected by an ancestor.@Publishedproperties on anObservableObjectannounce changes and trigger view updates; mutating them from a background thread requires handing the work back to the main thread.The app entry point is a type marked
@main: anAppwith aWindowGroupscene in SwiftUI, or aUIApplicationDelegatepaired with aSceneDelegatein UIKit.UIKit lifecycle order:
viewDidLoadonce, thenviewWillAppear,viewDidAppear,viewWillDisappear,viewDidDisappear;viewWillLayoutSubviewsandviewDidLayoutSubviewswrap each layout pass.Programmatic Auto Layout requires setting
translatesAutoresizingMaskIntoConstraintstofalsebefore activating constraints, otherwise the generated autoresizing constraints conflict.All interface updates occur on the main thread, so background results return through
@MainActor,MainActor.run, orDispatchQueue.main.async;@IBOutletand@IBActionconnect storyboard objects to code.NavigationStackpushes screens viaNavigationLinkornavigationDestination, andListneedsIdentifiablerows or an explicitidkey path to track identity.