Syntax similar to Rust
var(mutable) vslet(immutable)- Type inference
- Emojis are valid variable names (??)
nil-safety: declare optionals like this:Int?- Unwrap:
if let x = optionalVariable { } - Optional chaining:
person?.residence?.address
- Unwrap:
- Data Structures: Tuples (index with
.i), Structs, Classes - No braces around
if/switch/... (thank god) - Type casts:
as!(can crash),as?(returnsnilon fail) - Guard:
guard condition else {}- Nice for early returns:
guard req.isValid else { return }
- Nice for early returns:
Any,AnyObject: Unknown type- Computed properties
- include
willSet&didSetobservers - use
oldValue&newValue
- include
Strings #
.countfor length (.isEmptyfor.count == 0)- No single quotes,
Stringis coerced toCharacter - Can be
.lowercased - Interpolation:
"Variable a has value \(a)"
Loops #
- For:
for n in 0...8;for (i, char) in "ABCD".enumerated() - While:
while condition
Functions #
- Declared with
func - Parameter labels:
1func sayHello(to person: String) {
2 print("Hello \(person)")
3}
4sayHello(to: "Denis <3")
_label to drop
Enums #
1enum Compass {
2 case north east, south, west
3}
4let heading: Compass = .west
Structs #
- Value types
- Can contain functions
- These are immutable by default
- Mutation: need to be
mutating func - Use
selfto reference current instance
- Constructor function:
init - Preferred over classes
Classes #
- Reference types
Generics #
Type constraints:
1struct DictionaryA<Key: Hashable, Value> {}
2struct DictionaryB<Key, Value> where Key : Hashable {}
Protocols #
- What others call an
interface - Generics via
associatedType TypeName: gets inferred
Extensions #
- Add stuff to defined types
- You can add: computed properties, methods, initializers, protocol implementation
- You can't add: properties
1extension UIColor {
2 static var coolColor: UIColor {
3 return UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
4 }
5}
Closures #
- Syntax:
let closure = { val in ... } - Type:
(string: String) -> Void
Collections #
- Arrays
- Dictionaries:
var scores: [String: Int] = ["Richard": 500, "Luke": 300] - value types
UIKit #
- Inheritance-based; base class:
UIVIew - Outlets: Drag-&-drop connection between UI & code (annotation
@IBOutletfor UI elements,@IBActionfor functions) - Uses MVC (Model, View, Controller)
Delegates #
- Hand off responsibilities to other object
- Example:
1class MyViewController: UITableViewDelegate {
2 myTableView.delegate = self
3}
Navigation #
- Transition using Sequges
UINavigationController: Provides navigation UIUITabBarController: Bottom tab bar
View Controller #

AppDelegate #
- Single instance for application
- Stuff like
configurationForConnecting,didFinishLaunchingWithOptions:
1func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2 return true
3}
SceneDelegate #

- Per scene (i.e. per split view in iPadOS)
- Stuff like
func sceneDidDisconnect(_ scene: UIScene) { }
Auto Layout #
- Leading & trailing: left & right, except they support RTL-Layouts
Safe Area #
- Space that doesn't contain views
- Prevent collisions with dynamic island, bottom navigation, ...
Constraints #
- Rules where to align views
- Examples: Center, position relative to other view, size relative to other view
- Usually attach to Safe Area instead of whole device
Intrinsic Sizes #
- Some views know their size (labels, switches, ...)
- Only need position, not size
Hugging & Compressing #
- Views don't want to grow, so they hug their content
- Views have compression resistance priority (to determine who shrinks)
- Equal priorities: layout ambiguities
Variants #
- Attributes based on device class (think CSS media queries)
- Sizes:
Compact(iPhone),Regular(iPad),Any
Views #
Scroll View #
- Makes stuff scrollable (duh)
.frame: How large is the visible "window"?.contentSize- Insets: Add padding
- Has
UIScrollViewDelegate(scrollViewDidScroll,viewForZooming, ...)
Table View #
- Subclass of
UIScrollView - Shows vertical list of items (supports sections)
- Static vs. dynamic
- Styles: Plain, Grouped, Inset Grouped
- Uses cells (with default styles)
Collection Views #
- Subclass of
UIScrollView - Uses separate layout object (can change betweeen them)
- Has abstract
UICollectionViewLayoutbaseclass - Provided by UIKit:
UICollectoinViewFlowLayout(handles common cases like grids)
- Has abstract
- Compositional layouts as alternative to building layout
- Compose layouts from smaller ones
NSCollectionLayoutItem: Cell or supplementary view; needs sizeNSCollectionLayoutGroup: One or many items, defined as horizontal, vertical or custom; needs sizeNSCollectionLayoutSection: Configurable to scroll orthogonally to collection view
- Cells don't have builtin styles
Search Controller #
- Search functionality, integrated with navigation controllers
- Optional: secondary view to display result
Animations #
1UIView.animate(withDuration: 2.0) {
2 view.alpha = 0
3}
- Animate-able: alpha, backgroundColor, bounds, center, frame, transform
Data changes #
- Update views with
reloadData() - Animate changes:
performBatchUpdates() - Uses diffable datasources
Web access #
try await URL(string: "https://alexbaron.me")!- Query params:
URLComponents(string: "...").queryItems = [URLQueryItem(name: "key", value: "value")]
Concurrency #
- Use async to free up main thread
- Actors: Organize multithreading;
MainActorfor UIKit Main-Thread DispatchQueue.global(qos: .background).async { DispatchQueue.main.async { } }
SwiftUI #
- Declarative
- MVVM instead of MVC
- Up to 10 children per trailing closure (-> stuff like
ForEachneeded) - Idea: DSL for UI
- Bindings:
$varname,@Binding
Modifiers #
- Adjust views: return another view
- order matters
- Auto-applied to children
- Common examples:
.font.foregroundColor,.background.frame.padding.overlay: Add stuff above
XCode #
- Live Preview in the
Canvasview - Provide dummy data:
PreviewProvider- Options: preffered color scheme (light/dark), device, environment (dynamic font size, ...)
- Attribute Inspector: Change Code from UI (apparently pretty smart)
Layout Views #
- Push-out vs. pull-in
VStack,HStack,ZStack: pull-in (all up to 10 children)LazyVStack&LazyHStack
List: A list; supportsSectionsFormSpacer: Evenly-spaced spaces, supportsminLength
MVVM #
- Model / View / ViewModel
- ViewModel: Contains state, uses bindings
Navigation #
- NavigationStack
- NavigationLink
@Environment&.environmentObject(...)for params
Storing Data #
Serialization #
- Use
Codableprotocol - Convert with
try? PropertyListEncoder().encode(myData)
File Manager #
- Get path(s):
FileManager.default.urls(for: .documentDirectory, in: .useDomainMask).first! - Write:
encodedStuff.write(to: url, options: .noFileProtection) - Read:
try? Data(contentsOf: url)
last updated: