{
  "version": 1,
  "name": "Swift essentials",
  "iconName": "cube.fill",
  "colorID": "orange",
  "detail": "Optionals, value types and the idioms of Swift",
  "cards": [
    {
      "title": "let vs var",
      "concept": "let is a constant that can't be reassigned. var can change.",
      "code": "let name = \"Ana\"\nvar score = 0",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Declare an optional",
      "concept": "A type that holds a value or nothing (nil).",
      "code": "var nickname: String? = nil",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Unwrap with if let",
      "concept": "Runs the block only when there is a value.",
      "code": "if let nickname {\n    print(nickname)\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Unwrap with guard let",
      "concept": "Exits early and keeps the value for the rest of the scope.",
      "code": "guard let user else { return }",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Default for nil",
      "concept": "The nil-coalescing operator.",
      "code": "let name = nickname ?? \"Guest\"",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Optional chaining",
      "concept": "Stops and returns nil if anything is nil.",
      "code": "let count = user?.address?.street.count",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Force unwrap",
      "concept": "Crashes if the value is nil. Use only when nil is truly impossible.",
      "code": "let value = text!",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Define a struct",
      "concept": "A value type: copied when assigned or passed.",
      "code": "struct Point {\n    var x: Double\n    var y: Double\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Define a class",
      "concept": "A reference type: shared when assigned or passed.",
      "code": "final class Counter {\n    var value = 0\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "struct vs class",
      "concept": "Structs copy, classes share. Prefer structs unless you need identity or inheritance.",
      "code": "",
      "languageID": "none",
      "kindRaw": "basic",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Define an enum with data",
      "concept": "Each case can carry its own values.",
      "code": "enum Result {\n    case success(String)\n    case failure(Error)\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Switch over an enum",
      "concept": "The switch must cover every case.",
      "code": "switch result {\ncase .success(let text): print(text)\ncase .failure(let error): print(error)\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Define a protocol",
      "concept": "A contract a type can promise to follow.",
      "code": "protocol Greeter {\n    func greet() -> String\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Extend an existing type",
      "concept": "Adds methods without touching the original.",
      "code": "extension String {\n    var shout: String { uppercased() + \"!\" }\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Map, filter, reduce",
      "concept": "Transform, keep, and combine collections.",
      "code": "let sum = nums.filter { $0 > 0 }.map { $0 * 2 }.reduce(0, +)",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Closure syntax",
      "concept": "An unnamed function you can pass around.",
      "code": "let add = { (a: Int, b: Int) in a + b }",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Throw and catch",
      "concept": "Functions that can fail are marked throws and called with try.",
      "code": "do {\n    try save()\n} catch {\n    print(error)\n}",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Async and await",
      "concept": "Call asynchronous code without callbacks.",
      "code": "let data = try await load()",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "What does @State do?",
      "concept": "Gives a SwiftUI view its own source of truth. When it changes, the view redraws.",
      "code": "@State private var count = 0",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "What does @Binding do?",
      "concept": "A two-way connection to a value owned by another view.",
      "code": "@Binding var isOn: Bool",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "What does @Observable do?",
      "concept": "Makes a class publish changes so any view that reads it updates automatically.",
      "code": "@Observable final class Model { var count = 0 }",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Why mark a class final?",
      "concept": "It can't be subclassed, which is clearer and lets the compiler optimize.",
      "code": "",
      "languageID": "none",
      "kindRaw": "basic",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "Weak reference",
      "concept": "Doesn't keep an object alive. It becomes nil when the object goes away. Used to break retain cycles.",
      "code": "weak var delegate: Delegate?",
      "languageID": "swift",
      "kindRaw": "code",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    },
    {
      "title": "What is a retain cycle?",
      "concept": "Two objects holding strong references to each other so neither is ever freed.",
      "code": "",
      "languageID": "none",
      "kindRaw": "basic",
      "styleID": "",
      "notes": "",
      "colorID": "orange",
      "tags": []
    }
  ],
  "subfolders": []
}