DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your code here

@Binding, @State, @ObservableObject

Example Swift projects

Play while muted

do {
	try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
	try AVAudioSession.sharedInstance().setActive(true)
} catch {

Persist Local Data

USerDefaults - key value dictionary; Keychain - pw, credentials, userids, secure stuff (key value) CoreData - database, queries, etc. Can ship a fullly filled database

Android: Jetpack Compose (just ios 14)

In Simulator, hold down Option for 2-finger gestures; Hold down Option+Shift for 2 finger swipe

Apple tends to use “is..Presented”

Settings > Accessibility > Display & TExt size > Largessibility Sizes (X) > Make text size large

Accessibility Inspector Lets you explore items running in sumulartor

Property observers Run code when something is set

var lesson: Lesson? {
        didSet {
            print("Lesson: ", lesson ?? "None")

Functions should read as sentences (e.g. Play Audio ForLesson…)

External parameter vs local parameter name

private func playAudio(forLesson lesson: Lesson) { lesson.audioResource)

$ converts @State to @Binding

if you private struct within a view, dont have direct access to the parent properties; must used @Binding if using functions, have access to the vars

Background color for a VStack or HStack .background(Color.gray)

If you have more than one view, be explicit about putting it in vstack, hstack or group


  • Move into the safe area (away from Status bar / notch & Home indicator)

google everything with “hacking with swift”

Error handling

If let

If the right hand expression returns a non-optional, then execute the if statement. If the expression returns nil, then run the else

Using Protocol as an EnvironmenObect (ObservedObject)


Options > Text Editing > Editing > While Editing > [X] Including whitespace-only lines (trims new lines)

cant have an onbservable object for a protocol

Show Editor Only: CMD+Enter Open up Preview pane: CMD+option+Enter OPen Preferences: CMD+,

Ordering public injjcted properties public self creted properties body private variables private functions

iOS controls


swift :help :quit


decoding : from string to object

import Foundation

struct Lesson: Decodable {
    let name: String
    let index: Int

let json =
  "name": "Lesson 1",
  "index": 1

let data = .utf8)!

let decoder = JSONDecoder()
let lesson = try! decoder.decode(Lesson.self, from: data)

Multiple objects

let lessons = try! decoder.decode([Lesson].self, from: data)


Force try! - let error propagate all the way up to AppDelegate, can then crash the whole app


gotta implement method to conform to it can add functionality Can add methods but not properties (variables)


How to easily wrap a function/block araound another without counting { }?

Nil Coelescing Operator (??)

If left is nil, then return right side

Text(lesson.phrase.pronunciation ?? "None").font(.title)
func nilTesting() {
    let optionalString: String? = nil
    print(optionalString ?? "(empty)") // (empty)
    let optionalString2: String? = "foo"
    print(optionalString2 ?? "(empty)") // foo
    let optionalBool: Bool? = nil
    print(optionalBool ?? false) // false
    print((optionalBool ?? false) || true) // true
    let somethingElse = true
    if (optionalBool ?? false) || somethingElse {

Optional Unwrapping

func optionalUnwrapping() {
    let optionalString: String? = "foo"
    let optionalString2: String? = nil
    print(optionalString!) // force unwrapping, crashes if nil
    if let string = optionalString { // if let unwrapping
    } else {
        // optionalString is nil
    // using guard to unwrap optionals
    guard let string = optionalString,
        let string2 = optionalString2,
        2 > 1
        else { return }
    print(string) // type String, not optional
    print(string2) // type String, not optional
    // nested unwrapping with guard
    let optionalLesson: Lesson? = nil
    guard let lesson = optionalLesson,
        let pronunciation = lesson.phrase.pronunciation
        else { return }
    // nested if let unwrapping = pyramid of doom
    if let lesson = optionalLesson {
        if let pronunciation = lesson.phrase.pronunciation {

For each, shorthand parameters

func foo() {
    let strings = ["One", "Two", "Three"]
    // More modern way
    strings.forEach { string in
    // C-style way
    for string in strings {
    // Example mapping to a constant (modern way of doing this)
    let mapFoo = { string in
        "awesome \(string)"
    // Best version - shorthand parameter name
    let mapFoo2 = { "awesome \($0)" }
    // Appending with foreach (not preferred)
    var forEachFoo = [String]()
    strings.forEach { string in
        forEachFoo.append("awesome \(string)")
    let _ = strings.sorted { (lhs, rhs) -> Bool in
        lhs < rhs
    let _ = strings.sorted { $0 < $1 }


enum Fan {
    case small
    case medium
    case large

func fan(_ fan: Fan) {

func main() {
    printMyName(name: "Joe")
    printMyNameAThirdTime(paramName: "Joe")

Named Parameters

// Named parameter
func printMyName(name: String) {

// Implicit parameter
func printMyNameAgain(_ name: String) {

// Renamaed parameter
func printMyNameAThirdTime(paramName name: String) {



NavigationView {
}.alert(isPresented: $isAlertPresented) {
            Alert(title: Text("Alert me"))


  • Set a breakpoint - single click line gutter
  • Check out the debug area, see variables
  • lldb is the console, can do stuff like:
    • po self.whatever and it’ll print out


  • Order matters in modifiers (.padding, .font, .background etc)
Text("Hello, Bob!")

  • Makes sure stays in safe area
struct ContentView: View {
    @State var isCool: Bool = true
    @State var isAlertPresented: Bool = false
    var body: some View {
        NavigationView {
            VStack {...

Scheme: Different buildr/run configs

Folder Org

  • App
    • Framework - app delegate, scene delegate
    • Helpers - extensions on existing classes (e.g. colors, fonts)
    • Models
    • Resources - assets directory, icons, appstore logo. Not configuration, not code
      • HTML,e tc
    • Supporting Fiels
      • info.plist, fonts,
    • UIKit
      • no i
    • Views
  • Frameworks )manged)
  • Pods (managed)
  • Products )(not usred)
  • Tests

no idea of webview in swiftUI yet

Property Decorators


When a variable is decorated with this, and it changes, redraw body when try to change, creates to new struct to replace @State var isCool: Bool = true $varname = bind to this variable

struct ContentView: View {
    @State var isCool: Bool = true
    @State var isAlertPresented: Bool = false


  • sheets - modal (like iMessage > new msg)


struct cannot be modified (static)


How to create a toggle

@State var isCool: Bool = true Toggle(isOn: $isCool) Text("Are we cool? \(isCool ? "Yes" : "No")")

Misc SwiftUI Info

  • SwiftUI requires iOS13+ & Catalina
  • app delegate - launching point; application function
  • didFinishLaunchingWithOptions
  • UISceneConfiguration returns appdelegate.swift

[[iOS Dev - Xcode Keyboard Shortcuts]]

XCode UI

  • Autocomplate parameters. when its blue, start typing
    • Tab goes to next placeholder


Blue in the gutter, uncommited changes “M” next to the filename in Project Explorer = modified file, A for added

Open Questions

  • how to set variable in lldb?
  • how to log to debug / levels?



Tutorials @twoStraws

  • Tons of tutorials, super short
  • “how to make my text colored”