{"checkpoints":{"s-sw-1":[{"q":"<p>What does this print?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> input </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"abc\"</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Int</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(input) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">??</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span></code></pre></div>\n","options":[{"text":"Nothing; it doesn’t compile because <code dir=\"ltr\">Int(input)</code> is optional.","why":"<code dir=\"ltr\">??</code> unwraps the optional with a default, so the expression is a plain <code dir=\"ltr\">Int</code> and compiles."},{"text":"It crashes, because “abc” isn’t a number.","why":"<code dir=\"ltr\">Int(_:)</code> returns <code dir=\"ltr\">nil</code> for bad input instead of crashing; only a force unwrap would crash."},{"text":"<code dir=\"ltr\">abc5</code>","why":"Swift never joins a <code dir=\"ltr\">String</code> and an <code dir=\"ltr\">Int</code> with <code dir=\"ltr\">+</code>; both sides here are already <code dir=\"ltr\">Int</code>."},{"text":"<code dir=\"ltr\">5</code>","why":"Correct. <code dir=\"ltr\">Int(&quot;abc&quot;)</code> is <code dir=\"ltr\">nil</code>, <code dir=\"ltr\">?? 0</code> substitutes 0, and 0 + 5 is 5."}],"answer":3},{"q":"<p>Given <code dir=\"ltr\">func convert(_ amount: Decimal, to currency: String) -&gt; Decimal</code>, which call compiles?</p>","options":[{"text":"<code dir=\"ltr\">convert(12, to: &quot;EUR&quot;)</code>","why":"Correct. The first parameter’s label is <code dir=\"ltr\">_</code>, so it’s omitted; the second uses the label <code dir=\"ltr\">to</code>."},{"text":"<code dir=\"ltr\">convert(amount: 12, to: &quot;EUR&quot;)</code>","why":"<code dir=\"ltr\">amount</code> is the parameter name used inside the function; <code dir=\"ltr\">_</code> means callers write no label."},{"text":"<code dir=\"ltr\">convert(12, &quot;EUR&quot;)</code>","why":"The second parameter has the argument label <code dir=\"ltr\">to</code>, and Swift requires it at the call site."},{"text":"<code dir=\"ltr\">convert(12, currency: &quot;EUR&quot;)</code>","why":"<code dir=\"ltr\">currency</code> is the internal name. Callers must use the external label <code dir=\"ltr\">to</code>."}],"answer":0},{"q":"<p><code dir=\"ltr\">func monthlyAverage(_ amounts: [Decimal]) -&gt; Decimal?</code> must return <code dir=\"ltr\">nil</code> for an empty array. Which first line is the idiomatic Swift way to handle that?</p>","options":[{"text":"<code dir=\"ltr\">let first = amounts[0]</code>","why":"Subscripting an empty array crashes with “Index out of range” before you can return anything."},{"text":"<code dir=\"ltr\">if amounts.isEmpty { amounts = [0] }</code>","why":"Function parameters are constants, so this doesn’t compile; it would also hide the empty case."},{"text":"<code dir=\"ltr\">guard amounts.count &gt; 0 else { print(&quot;empty&quot;) }</code>","why":"A <code dir=\"ltr\">guard</code>’s <code dir=\"ltr\">else</code> must leave the scope, so a bare <code dir=\"ltr\">print</code> is a compile error."},{"text":"<code dir=\"ltr\">guard !amounts.isEmpty else { return nil }</code>","why":"Correct. The guard states the rule, exits early, and the rest of the function can assume data exists."}],"answer":3},{"q":"<p>You loop over expenses and want to count how many fall in each category, starting from an empty <code dir=\"ltr\">var counts: [String: Int] = [:]</code>. Which line goes inside the loop?</p>","options":[{"text":"<code dir=\"ltr\">counts[category] += 1</code>","why":"The subscript returns <code dir=\"ltr\">Int?</code>, and you can’t add 1 to an optional without unwrapping it."},{"text":"<code dir=\"ltr\">counts.append(category)</code>","why":"Dictionaries have no <code dir=\"ltr\">append</code>; that’s an array method."},{"text":"<code dir=\"ltr\">counts[category, default: 0] += 1</code>","why":"Correct. The <code dir=\"ltr\">default:</code> subscript reads 0 for a new key, adds 1, and stores the result."},{"text":"<code dir=\"ltr\">counts.insert(category)</code>","why":"<code dir=\"ltr\">insert</code> is a <code dir=\"ltr\">Set</code> method; it would record membership, not a count."}],"answer":2},{"q":"<p>What is <code dir=\"ltr\">result</code>?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> values </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">30</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> result </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> values.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 10</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$0</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> *</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">reduce</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">84</code>","why":"Correct. <code dir=\"ltr\">filter</code> keeps 12 and 30, <code dir=\"ltr\">map</code> doubles them to 24 and 60, and <code dir=\"ltr\">reduce</code> adds them."},{"text":"<code dir=\"ltr\">94</code>","why":"That includes the 5, doubled to 10. <code dir=\"ltr\">filter</code> removed it before <code dir=\"ltr\">map</code> ran."},{"text":"<code dir=\"ltr\">[24, 60]</code>","why":"That’s the value after <code dir=\"ltr\">map</code>. <code dir=\"ltr\">reduce</code> then combines the array into a single number."},{"text":"<code dir=\"ltr\">42</code>","why":"That’s 12 + 30 without doubling. The <code dir=\"ltr\">map</code> step runs before <code dir=\"ltr\">reduce</code>."}],"answer":0}],"s-sw-2":[{"q":"<p><code dir=\"ltr\">Expense</code> is a struct with <code dir=\"ltr\">var amount: Decimal</code>. What does this print?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> list </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">Expense</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">amount</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)]</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> first </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> list[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">first.amount </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 9</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(list[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].amount)</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">5</code>","why":"Correct. Reading <code dir=\"ltr\">list[0]</code> into <code dir=\"ltr\">first</code> copies the struct; changing the copy leaves the array untouched."},{"text":"<code dir=\"ltr\">9</code>","why":"That’s class behaviour. Structs are copied on assignment, so <code dir=\"ltr\">first</code> is independent."},{"text":"It doesn’t compile, because array elements are constants.","why":"<code dir=\"ltr\">list</code> is a <code dir=\"ltr\">var</code>, and so is <code dir=\"ltr\">first</code>; nothing here is a constant."},{"text":"It crashes, because <code dir=\"ltr\">first</code> is a dangling reference.","why":"Structs have no references to dangle; <code dir=\"ltr\">first</code> holds its own complete value."}],"answer":0},{"q":"<p>What does this print?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">enum</span><span style=\"color:#953800;--shiki-dark:#FFA657\"> Sync</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    case</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> idle</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    case</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> syncing</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(progress: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">Double</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    case</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> failed</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">String</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> state: Sync </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">syncing</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">progress</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.4</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">switch</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> state {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">case</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> .idle</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Idle\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">case</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">syncing</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> p) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">where</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> p </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0.5</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Almost\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">case</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> .syncing</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Working\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">case</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> .</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">failed</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> message)</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(message)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">Almost</code>","why":"That case requires progress above 0.5, and 0.4 fails the <code dir=\"ltr\">where</code> condition."},{"text":"<code dir=\"ltr\">Idle</code>","why":"The value is <code dir=\"ltr\">.syncing</code>, so the <code dir=\"ltr\">.idle</code> case can’t match it."},{"text":"Nothing, because no case matches 0.4.","why":"The plain <code dir=\"ltr\">case .syncing:</code> matches any progress, so a case always matches."},{"text":"<code dir=\"ltr\">Working</code>","why":"Correct. The <code dir=\"ltr\">where</code> clause fails, so matching moves on to the next <code dir=\"ltr\">.syncing</code> case."}],"answer":3},{"q":"<p><code dir=\"ltr\">protocol Exportable { func csvRow() -&gt; String }</code> has five conforming types. Every one of them should also get <code dir=\"ltr\">csvLine</code>, which is <code dir=\"ltr\">csvRow()</code> plus a newline, without writing it five times. What do you add?</p>","options":[{"text":"A <code dir=\"ltr\">var csvLine: String { get }</code> requirement in the protocol.","why":"A requirement makes every type implement it, which is the duplication you wanted to avoid."},{"text":"<code dir=\"ltr\">extension Exportable { var csvLine: String { csvRow() + &quot;\\n&quot; } }</code>","why":"Correct. A protocol extension gives every conforming type the implementation for free."},{"text":"A base class <code dir=\"ltr\">ExportableBase</code> that all five types inherit from.","why":"Structs and enums can’t inherit, and inheritance is heavier than this problem needs."},{"text":"A global function <code dir=\"ltr\">csvLine(_ item: Exportable)</code> in each file.","why":"Writing it in each file is still duplication, and it doesn’t read as a property of the type."}],"answer":1},{"q":"<p>A <code dir=\"ltr\">final class ReminderScheduler</code> stores <code dir=\"ltr\">var onFire: (() -&gt; Void)?</code> and sets <code dir=\"ltr\">onFire = { self.notify() }</code>. Memory tools show schedulers are never freed. What’s the fix?</p>","options":[{"text":"Change <code dir=\"ltr\">onFire</code> from <code dir=\"ltr\">var</code> to <code dir=\"ltr\">let</code>.","why":"Mutability isn’t the issue; a <code dir=\"ltr\">let</code> closure would capture <code dir=\"ltr\">self</code> just as strongly."},{"text":"Set <code dir=\"ltr\">onFire = nil</code> inside <code dir=\"ltr\">deinit</code>.","why":"<code dir=\"ltr\">deinit</code> never runs while the cycle exists, so that line would never execute."},{"text":"Make <code dir=\"ltr\">ReminderScheduler</code> a subclass of <code dir=\"ltr\">NSObject</code>.","why":"Objective-C classes use reference counting too; the cycle stays."},{"text":"Capture weakly: <code dir=\"ltr\">onFire = { [weak self] in self?.notify() }</code>.","why":"Correct. The closure no longer owns the scheduler, so the reference count can reach zero."}],"answer":3},{"q":"<p><code dir=\"ltr\">load()</code> reads saved expenses and throws if the file is corrupted. What does the user see when that happens?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">try?</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> load</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">()) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">??</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> []</span></span></code></pre></div>\n","options":[{"text":"An empty list, with no hint that their data failed to load.","why":"Correct. <code dir=\"ltr\">try?</code> discarded the error and <code dir=\"ltr\">?? []</code> filled in a value. Catch it and tell the user."},{"text":"An alert describing the corruption.","why":"Nothing here shows an alert; <code dir=\"ltr\">try?</code> threw the error away."},{"text":"A crash with the error’s description.","why":"That’s <code dir=\"ltr\">try!</code>. <code dir=\"ltr\">try?</code> never crashes; it produces <code dir=\"ltr\">nil</code>."},{"text":"The expenses that loaded before the corrupted part.","why":"<code dir=\"ltr\">load()</code> either returns the whole array or throws; there’s no partial result."}],"answer":0}],"s-sw-3":[{"q":"<p>A child view <code dir=\"ltr\">AmountField</code> declares <code dir=\"ltr\">@State var amount: Decimal</code>, and its parent creates it with <code dir=\"ltr\">AmountField(amount: budget.limit)</code>. Typing in the field never changes the parent’s limit. Why?</p>","options":[{"text":"<code dir=\"ltr\">TextField</code> can’t edit <code dir=\"ltr\">Decimal</code> values.","why":"With a <code dir=\"ltr\">format:</code>, <code dir=\"ltr\">TextField</code> edits <code dir=\"ltr\">Decimal</code> happily; the type isn’t the problem."},{"text":"The parent must call <code dir=\"ltr\">objectWillChange.send()</code>.","why":"That belongs to the older <code dir=\"ltr\">ObservableObject</code> system and wouldn’t connect the two values anyway."},{"text":"SwiftUI only updates parents when the child disappears.","why":"SwiftUI updates as soon as a source of truth changes; there’s no delay rule like this."},{"text":"<code dir=\"ltr\">@State</code> gave the child its own copy; it should be <code dir=\"ltr\">@Binding</code>, with the parent passing a binding.","why":"Correct. The child must borrow the parent’s source of truth, not start a new one."}],"answer":3},{"q":"<p>Which code shows a spending total the way users in different countries expect to read money?</p>","options":[{"text":"<code dir=\"ltr\">Text(total, format: .currency(code: &quot;USD&quot;))</code>","why":"Correct. The format style applies the user’s locale for symbol position, separators and decimals."},{"text":"<code dir=\"ltr\">Text(&quot;$\\(total)&quot;)</code>","why":"This hard-codes the symbol and ignores the user’s separators, so “$1234.5” looks wrong almost everywhere."},{"text":"<code dir=\"ltr\">Text(String(describing: total))</code>","why":"That’s a debugging representation with no currency and no locale rules."},{"text":"<code dir=\"ltr\">Text(&quot;\\(total) USD&quot;)</code>","why":"Better than nothing, but still unformatted: no grouping, no fixed decimals, no locale."}],"answer":0},{"q":"<p>The list uses <code dir=\"ltr\">NavigationLink(value: expense)</code> and <code dir=\"ltr\">.navigationDestination(for: Expense.self)</code>. After saving a new expense, you want to open its detail screen from code. What do you add?</p>","options":[{"text":"A hidden <code dir=\"ltr\">NavigationLink</code> with <code dir=\"ltr\">isActive:</code> that you toggle.","why":"That’s an older, deprecated pattern; <code dir=\"ltr\">NavigationStack</code> replaced it with paths."},{"text":"Call <code dir=\"ltr\">navigationDestination</code> again with the new expense.","why":"The destination modifier is declared once; it doesn’t trigger navigation by itself."},{"text":"<code dir=\"ltr\">@State private var path: [Expense] = []</code>, <code dir=\"ltr\">NavigationStack(path: $path)</code>, then <code dir=\"ltr\">path.append(saved)</code>.","why":"Correct. The path is state, so appending a value pushes its destination screen."},{"text":"Present the detail screen with <code dir=\"ltr\">.sheet</code> instead.","why":"That changes the interaction to a modal; it doesn’t push onto the navigation stack."}],"answer":2},{"q":"<p>A <code dir=\"ltr\">BudgetStore</code> marked <code dir=\"ltr\">@Observable</code> is put into the environment at the app level. A deeply nested <code dir=\"ltr\">LimitSettings</code> view needs a <code dir=\"ltr\">TextField</code> bound to <code dir=\"ltr\">store.monthlyLimit</code>. What does that view write?</p>","options":[{"text":"<code dir=\"ltr\">@EnvironmentObject var store: BudgetStore</code>","why":"<code dir=\"ltr\">@EnvironmentObject</code> belongs to <code dir=\"ltr\">ObservableObject</code>; it doesn’t find objects added with <code dir=\"ltr\">.environment(_:)</code>."},{"text":"<code dir=\"ltr\">@State private var store = BudgetStore()</code>","why":"That creates a brand-new store owned by this view, disconnected from the app’s data."},{"text":"<code dir=\"ltr\">@Binding var store: BudgetStore</code>","why":"Bindings are passed in explicitly by a parent; they don’t come from the environment."},{"text":"<code dir=\"ltr\">@Environment(BudgetStore.self) private var store</code>, then <code dir=\"ltr\">@Bindable var store = store</code> in <code dir=\"ltr\">body</code>.","why":"Correct. The environment supplies the shared store, and <code dir=\"ltr\">@Bindable</code> produces <code dir=\"ltr\">$store.monthlyLimit</code>."}],"answer":3},{"q":"<p><code dir=\"ltr\">AddExpenseView</code> is presented as a sheet and must close itself when the user taps Save. What’s the standard way?</p>","options":[{"text":"Read <code dir=\"ltr\">@Environment(\\.dismiss) private var dismiss</code> and call <code dir=\"ltr\">dismiss()</code> after saving.","why":"Correct. <code dir=\"ltr\">dismiss</code> closes whatever presentation is showing this view, sheet or pushed screen."},{"text":"Call <code dir=\"ltr\">NavigationStack.pop()</code>.","why":"There’s no such API, and a sheet isn’t part of the list’s navigation stack."},{"text":"Set the view’s own <code dir=\"ltr\">isPresented</code> property to <code dir=\"ltr\">false</code>.","why":"The sheet’s flag belongs to the parent; the child has no such property unless it’s given a binding."},{"text":"Remove the view from its parent with <code dir=\"ltr\">removeFromSuperview()</code>.","why":"That’s UIKit; SwiftUI views are descriptions, not objects you can remove."}],"answer":0}],"s-sw-4":[{"q":"<p>Each fetch takes about a second. How do you make this take about one second in total?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">func</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> loadAll</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">() </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">async</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> throws</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> -></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (Decimal, Decimal) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> eur </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> try</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> service.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">fetchRate</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"USD\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">to</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"EUR\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> gbp </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> try</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> service.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">fetchRate</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"USD\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">to</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"GBP\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (eur, gbp)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n","options":[{"text":"Wrap each call in <code dir=\"ltr\">Task { }</code> and return right away.","why":"The function would return before the results exist, and the unstructured tasks escape cancellation."},{"text":"Mark the function <code dir=\"ltr\">@MainActor</code>.","why":"Changing the actor doesn’t make two sequential awaits overlap."},{"text":"Call <code dir=\"ltr\">fetchRate</code> from a <code dir=\"ltr\">DispatchQueue.main.async</code> block.","why":"That mixes old GCD code with async/await and still doesn’t run the requests in parallel."},{"text":"Use <code dir=\"ltr\">async let eur = …</code> and <code dir=\"ltr\">async let gbp = …</code>, then <code dir=\"ltr\">try await (eur, gbp)</code>.","why":"Correct. Both child tasks start immediately and run at the same time."}],"answer":3},{"q":"<p>A nonisolated helper function assigns to <code dir=\"ltr\">model.state</code> on a <code dir=\"ltr\">@MainActor</code> model, and Swift 6 reports “main actor-isolated property ‘state’ can not be mutated from a nonisolated context”. What’s a correct fix?</p>","options":[{"text":"Mark the helper <code dir=\"ltr\">@MainActor</code>, so it runs where the model’s state lives.","why":"Correct. Now the compiler can prove only main-actor code touches the state."},{"text":"Mark the model <code dir=\"ltr\">@unchecked Sendable</code>.","why":"That silences checks without making anything safe; the race is still there."},{"text":"Switch the target back to the Swift 5 language mode.","why":"That hides the diagnostic instead of fixing the data race it describes."},{"text":"Copy the model into a local variable before assigning.","why":"The model is a class, so the copy is the same object and the same race."}],"answer":0},{"q":"<p>The rates API returns HTTP 404 with an HTML page for an unknown currency. Your code decodes <code dir=\"ltr\">data</code> right after <code dir=\"ltr\">URLSession.shared.data(from:)</code>. What do users see?</p>","options":[{"text":"A <code dir=\"ltr\">URLError</code> saying the page wasn’t found.","why":"URLSession doesn’t throw for HTTP status codes; a 404 is a successful response at the network level."},{"text":"A decoding error, such as “data couldn’t be read because it isn’t in the correct format”.","why":"Correct. The HTML reaches <code dir=\"ltr\">JSONDecoder</code>. Check the status code first and throw a clearer error."},{"text":"An empty list of rates and no error.","why":"Decoding HTML as <code dir=\"ltr\">RatesResponse</code> fails loudly; it doesn’t produce an empty value."},{"text":"The HTML page rendered in the app.","why":"Nothing in the code displays the response body."}],"answer":1},{"q":"<p>An edit screen binds fields straight to a SwiftData model with <code dir=\"ltr\">@Bindable var expense: Expense</code>. Product wants a Cancel button that discards changes. What’s the cleanest design?</p>","options":[{"text":"Keep binding directly, and call <code dir=\"ltr\">context.insert(expense)</code> on Cancel.","why":"Inserting an existing model doesn’t undo edits; the changes are already on the object."},{"text":"Keep binding directly; edits only save when the screen closes.","why":"Edits change the model immediately, and the main context autosaves them."},{"text":"Turn <code dir=\"ltr\">Expense</code> into a struct so edits are copies.","why":"<code dir=\"ltr\">@Model</code> requires a class; you can’t make a SwiftData model a struct."},{"text":"Edit <code dir=\"ltr\">@State</code> draft copies of the fields, and write them to the model only on Save.","why":"Correct. It’s the same draft pattern as the add form: Cancel throws the drafts away."}],"answer":3},{"q":"<p>Which test verifies that <code dir=\"ltr\">record</code> throws <code dir=\"ltr\">BudgetError.overLimit(by: 7)</code>?</p>","options":[{"text":"<code dir=\"ltr\">#expect(throws: BudgetError.overLimit(by: 7)) { try food.record(title: &quot;Dinner&quot;, amount: 45) }</code>","why":"Correct. It passes only if that exact error is thrown, which works because <code dir=\"ltr\">BudgetError</code> is <code dir=\"ltr\">Equatable</code>."},{"text":"<code dir=\"ltr\">#expect(try food.record(title: &quot;Dinner&quot;, amount: 45) == .overLimit(by: 7))</code>","why":"<code dir=\"ltr\">record</code> returns nothing; errors are thrown, not returned, so there’s nothing to compare."},{"text":"<code dir=\"ltr\">do { try food.record(title: &quot;Dinner&quot;, amount: 45) } catch { }</code>","why":"With no assertion, this passes whether or not anything is thrown."},{"text":"<code dir=\"ltr\">try #require(food.spent == 57)</code>","why":"That checks the wrong thing; after a correct failure <code dir=\"ltr\">spent</code> should stay unchanged."}],"answer":0}]},"final":[{"q":"<p><code dir=\"ltr\">expenses</code> is an empty array. What is <code dir=\"ltr\">label</code>?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"6\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> label </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> expenses.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">first</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">?</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.title.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">uppercased</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">() </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">??</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"NONE\"</span></span></code></pre></div>\n","options":[{"text":"It crashes, because the array is empty.","why":"<code dir=\"ltr\">first</code> returns an optional instead of crashing, and <code dir=\"ltr\">?.</code> stops safely at <code dir=\"ltr\">nil</code>."},{"text":"<code dir=\"ltr\">nil</code>","why":"The optional chain is <code dir=\"ltr\">nil</code>, but <code dir=\"ltr\">?? &quot;NONE&quot;</code> replaces it with the default."},{"text":"An empty string.","why":"No title exists, so there’s nothing to uppercase; the default is used instead."},{"text":"<code dir=\"ltr\">&quot;NONE&quot;</code>","why":"Correct. <code dir=\"ltr\">first</code> is <code dir=\"ltr\">nil</code>, the chain short-circuits, and <code dir=\"ltr\">??</code> supplies the default."}],"answer":3},{"q":"<p>Pocket Budget needs a sort-order setting with exactly three choices (newest, oldest, largest) shown in a picker and saved to disk. Which type fits best?</p>","options":[{"text":"<code dir=\"ltr\">enum SortOrder: String, CaseIterable { case newest, oldest, largest }</code>","why":"Correct. Only valid values exist, <code dir=\"ltr\">allCases</code> feeds the picker, and the raw value saves cleanly."},{"text":"<code dir=\"ltr\">let sortOrder: String</code>","why":"Any string compiles, including typos, and the picker has no list of choices."},{"text":"<code dir=\"ltr\">struct SortOrder { var isNewest: Bool; var isLargest: Bool }</code>","why":"Booleans allow impossible combinations, such as both flags true at once."},{"text":"<code dir=\"ltr\">class SortOrder</code> with three subclasses.","why":"Inheritance is far heavier than a fixed set of choices needs, and harder to save."}],"answer":0},{"q":"<p>Why does the add-expense form keep <code dir=\"ltr\">title</code>, <code dir=\"ltr\">amount</code> and <code dir=\"ltr\">category</code> in its own <code dir=\"ltr\">@State</code> properties instead of writing to the store on every keystroke?</p>","options":[{"text":"Because <code dir=\"ltr\">@Observable</code> stores can’t be edited from forms.","why":"Forms edit observable objects through <code dir=\"ltr\">@Bindable</code> all the time; that’s not the reason."},{"text":"Because <code dir=\"ltr\">TextField</code> only works with <code dir=\"ltr\">@State</code>.","why":"<code dir=\"ltr\">TextField</code> accepts any binding, including one into an observable object."},{"text":"Because the store can only accept complete <code dir=\"ltr\">Expense</code> values.","why":"The store could accept partial updates; the real reason is about the user’s intent."},{"text":"So the form is a draft: Cancel discards it without touching saved data.","why":"Correct. Value-type drafts make cancelling free and keep half-typed data out of the store."}],"answer":3},{"q":"<p>You add <code dir=\"ltr\">case gifts</code> to <code dir=\"ltr\">Category</code>. The project has three <code dir=\"ltr\">switch</code> statements over <code dir=\"ltr\">Category</code>, yet the build passes with no errors. What’s the most likely explanation?</p>","options":[{"text":"Swift doesn’t check <code dir=\"ltr\">switch</code> exhaustiveness for enums with raw values.","why":"Raw values make no difference; every enum switch is checked for exhaustiveness."},{"text":"New enum cases are only checked when you run the app.","why":"Exhaustiveness is a compile-time check, never a runtime one."},{"text":"Those switches use <code dir=\"ltr\">default:</code>, which silently absorbs the new case.","why":"Correct. That’s why switches over your own enums should list cases explicitly."},{"text":"Xcode only checks switches in files you have open.","why":"The compiler checks every file it builds, open or not."}],"answer":2},{"q":"<p>Several tasks fetch rates in parallel and must all update one shared cache. Which declaration keeps the cache free of data races?</p>","options":[{"text":"<code dir=\"ltr\">actor RateCache { private var rates: [String: Decimal] = [:] }</code> with methods to read and save.","why":"Correct. The actor runs one call at a time on its state, and callers must <code dir=\"ltr\">await</code> it."},{"text":"<code dir=\"ltr\">final class RateCache { var rates: [String: Decimal] = [:] }</code>","why":"A plain class with mutable state isn’t <code dir=\"ltr\">Sendable</code>; Swift 6 won’t let tasks share it."},{"text":"<code dir=\"ltr\">struct RateCache { var rates: [String: Decimal] }</code> passed to each task.","why":"Each task gets its own copy, so their updates never reach a shared cache."},{"text":"A global <code dir=\"ltr\">var rates: [String: Decimal]</code>.","why":"Global mutable state is exactly what Swift 6 flags as unsafe across tasks."}],"answer":0},{"q":"<p>The JSON contains <code dir=\"ltr\">&quot;total_spent&quot;: 12.5</code> and your struct has <code dir=\"ltr\">let totalSpent: Decimal</code>. Decoding throws <code dir=\"ltr\">keyNotFound</code>. What’s the cleanest fix?</p>","options":[{"text":"Rename the property to <code dir=\"ltr\">total_spent</code>.","why":"It works, but it brings the server’s naming style into your Swift code."},{"text":"Change the type to <code dir=\"ltr\">Double</code>.","why":"The type isn’t the problem; the key name doesn’t match."},{"text":"Make the property optional.","why":"The error disappears, but the value is always <code dir=\"ltr\">nil</code> because the key still doesn’t match."},{"text":"Set <code dir=\"ltr\">decoder.keyDecodingStrategy = .convertFromSnakeCase</code>.","why":"Correct. Every snake_case key maps to its camelCase property automatically."}],"answer":3},{"q":"<p>Users want to pull down on the rates list to refresh it. Which modifier adds that?</p>","options":[{"text":"<code dir=\"ltr\">.task { await model.load() }</code>","why":"<code dir=\"ltr\">.task</code> runs when the view appears; it doesn’t add a pull gesture."},{"text":"<code dir=\"ltr\">.refreshable { await model.load() }</code>","why":"Correct. It adds pull-to-refresh and shows the spinner until the async function returns."},{"text":"<code dir=\"ltr\">.onTapGesture { Task { await model.load() } }</code>","why":"That refreshes on a tap, not a pull, and shows no system refresh indicator."},{"text":"<code dir=\"ltr\">.sheet(isPresented:)</code>","why":"A sheet presents another screen; it has nothing to do with refreshing."}],"answer":1},{"q":"<p>In which situation is <code dir=\"ltr\">try?</code> a good choice?</p>","options":[{"text":"Deleting a temporary export file that may already be gone, where failure changes nothing.","why":"Correct. The reason for failure truly doesn’t matter, so discarding it is honest."},{"text":"Saving the user’s new expense.","why":"If saving fails, the user must be told; <code dir=\"ltr\">try?</code> would hide it."},{"text":"Decoding the exchange-rate response.","why":"A failed decode should become a visible error state, not a silent <code dir=\"ltr\">nil</code>."},{"text":"Recording an expense against a budget limit.","why":"The specific error, such as over limit, drives the message the user sees."}],"answer":0},{"q":"<p>Which declaration shows saved expenses newest first and updates on its own when another screen inserts one?</p>","options":[{"text":"<code dir=\"ltr\">@State private var expenses: [Expense] = []</code>","why":"That’s an in-memory array you’d have to fill and refresh by hand."},{"text":"<code dir=\"ltr\">let expenses = try? context.fetch(FetchDescriptor&lt;Expense&gt;())</code>","why":"A one-off fetch doesn’t update when the data changes later."},{"text":"<code dir=\"ltr\">@Environment(\\.modelContext) private var expenses</code>","why":"That’s the context used for writes, not a list of expenses."},{"text":"<code dir=\"ltr\">@Query(sort: \\Expense.date, order: .reverse) private var expenses: [Expense]</code>","why":"Correct. <code dir=\"ltr\">@Query</code> fetches, sorts and keeps the result current as the store changes."}],"answer":3},{"q":"<p>What does <code dir=\"ltr\">some View</code> in <code dir=\"ltr\">var body: some View</code> promise?</p>","options":[{"text":"That <code dir=\"ltr\">body</code> can return a different view type each time it’s called.","why":"That’s what <code dir=\"ltr\">any View</code> would allow; <code dir=\"ltr\">some</code> fixes one type."},{"text":"That the view is a class.","why":"<code dir=\"ltr\">some</code> says nothing about classes; SwiftUI views are usually structs."},{"text":"That <code dir=\"ltr\">body</code> returns one specific type conforming to <code dir=\"ltr\">View</code>, which the compiler knows but you don’t have to write.","why":"Correct. It’s an opaque type that hides a long generic name."},{"text":"That the view will be rendered on a background thread.","why":"<code dir=\"ltr\">some</code> is about types, not threads; views render on the main actor."}],"answer":2},{"q":"<p>Uploading a new build to App Store Connect fails because that build number was already used for this version. What do you do?</p>","options":[{"text":"Increase the Build number in the target settings, archive again and upload.","why":"Correct. Each upload needs a new build number; the Version can stay the same."},{"text":"Delete the earlier build from TestFlight and retry.","why":"Build numbers stay used even after you expire a build."},{"text":"Change the bundle identifier.","why":"That creates a different app entirely, losing your App Store Connect record."},{"text":"Wait 90 days for the old build to expire.","why":"Expiry ends testing; it doesn’t free the build number."}],"answer":0},{"q":"<p>Does this compile?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"swift\" data-index=\"7\"><div class=\"code-head\"><span class=\"code-title\">Swift</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">@Observable</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">final</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> class</span><span style=\"color:#953800;--shiki-dark:#FFA657\"> Settings</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">    var</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> limit: Decimal </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">let</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> settings </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Settings</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">()</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">settings.limit </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 200</span></span></code></pre></div>\n","options":[{"text":"No, because <code dir=\"ltr\">settings</code> is a <code dir=\"ltr\">let</code> constant.","why":"For a class, <code dir=\"ltr\">let</code> fixes which object the name refers to, not the object’s properties."},{"text":"No, because <code dir=\"ltr\">@Observable</code> properties are read-only.","why":"Observable properties are ordinary <code dir=\"ltr\">var</code>s; the macro only adds tracking."},{"text":"Yes, but the change is lost because <code dir=\"ltr\">settings</code> was copied.","why":"Classes aren’t copied on assignment; there’s one object and it changed."},{"text":"Yes; the reference is constant, but the object’s <code dir=\"ltr\">var</code> property can still change.","why":"Correct. That’s reference semantics: <code dir=\"ltr\">let</code> freezes the reference only."}],"answer":3}],"glossary":[{"id":"type-inference","term":"Type inference","definition":"Swift’s ability to work out a value’s type from the value you assign, so <code dir=\"ltr\">let cups = 3</code> is an <code dir=\"ltr\">Int</code> without an annotation. The type is fixed from then on.","lesson":"l-sw-1-1"},{"id":"decimal","term":"Decimal","definition":"A Foundation number type that stores base-10 digits exactly, which makes it the right choice for money. Unlike <code dir=\"ltr\">Double</code>, adding 0.1 ten times gives exactly 1.","lesson":"l-sw-1-1"},{"id":"optional","term":"Optional","definition":"A type such as <code dir=\"ltr\">Decimal?</code> that holds either a value or <code dir=\"ltr\">nil</code>. Swift won’t let you use it as a plain value until you unwrap it safely.","lesson":"l-sw-1-2"},{"id":"guard-let","term":"guard let","definition":"A statement that unwraps an optional or checks a condition and must exit the scope in its <code dir=\"ltr\">else</code> branch. After it, the unwrapped value is available for the rest of the function.","lesson":"l-sw-1-2"},{"id":"nil-coalescing","term":"Nil-coalescing operator (??)","definition":"The <code dir=\"ltr\">??</code> operator, which returns the value inside an optional or a default when the optional is <code dir=\"ltr\">nil</code>, as in <code dir=\"ltr\">note ?? &quot;No note&quot;</code>.","lesson":"l-sw-1-2"},{"id":"force-unwrap","term":"Force unwrap (!)","definition":"Writing <code dir=\"ltr\">!</code> after an optional to take its value without checking. If the optional is <code dir=\"ltr\">nil</code>, the app crashes immediately, so use it only when <code dir=\"ltr\">nil</code> would be a programmer error.","lesson":"l-sw-1-2"},{"id":"exhaustive-switch","term":"Exhaustive switch","definition":"Swift’s rule that a <code dir=\"ltr\">switch</code> must handle every possible value. Over enums it makes the compiler list every switch you need to update when you add a case.","lesson":"l-sw-1-3"},{"id":"closure","term":"Closure","definition":"A block of code without a name that can be stored, passed to functions like <code dir=\"ltr\">filter</code> or <code dir=\"ltr\">map</code>, and called later. It captures the variables it uses from its surrounding scope.","lesson":"l-sw-1-4"},{"id":"value-semantics","term":"Value semantics","definition":"The behaviour of structs and enums: assigning or passing a value makes an independent copy, so changing the copy never affects the original.","lesson":"l-sw-2-1"},{"id":"reference-semantics","term":"Reference semantics","definition":"The behaviour of classes and actors: assigning an instance copies a reference, so several names can point at the same object and see each other’s changes.","lesson":"l-sw-2-1"},{"id":"mutating","term":"mutating","definition":"A keyword on struct and enum methods that change the value’s own properties. Mutating methods can only be called on a <code dir=\"ltr\">var</code>, never on a <code dir=\"ltr\">let</code>.","lesson":"l-sw-2-1"},{"id":"retain-cycle","term":"Retain cycle","definition":"Two objects, or an object and a closure, holding strong references to each other so neither can be freed by ARC. Capturing <code dir=\"ltr\">[weak self]</code> in the closure breaks the cycle.","lesson":"l-sw-2-1"},{"id":"associated-value","term":"Associated value","definition":"Data attached to a specific enum case for each instance, such as <code dir=\"ltr\">case card(lastFour: String)</code>. You read it back with pattern matching like <code dir=\"ltr\">case .card(let lastFour)</code>.","lesson":"l-sw-2-2"},{"id":"raw-value","term":"Raw value","definition":"A fixed <code dir=\"ltr\">String</code> or number stored for each case of an enum declared like <code dir=\"ltr\">enum Category: String</code>. <code dir=\"ltr\">init(rawValue:)</code> converts back and returns <code dir=\"ltr\">nil</code> for unknown values.","lesson":"l-sw-2-2"},{"id":"protocol","term":"Protocol","definition":"A named set of requirements, such as properties and methods, that structs, classes and enums can adopt. Code written against the protocol works with every conforming type.","lesson":"l-sw-2-3"},{"id":"protocol-extension","term":"Protocol extension","definition":"An extension on a protocol that provides default implementations, so every conforming type gains that behaviour without writing it again.","lesson":"l-sw-2-3"},{"id":"typed-throws","term":"Typed throws","definition":"Swift 6 syntax such as <code dir=\"ltr\">throws(BudgetError)</code> that names the exact error type a function can throw, so callers can switch over the error exhaustively without a catch-all.","lesson":"l-sw-2-4"},{"id":"modifier","term":"View modifier","definition":"A method like <code dir=\"ltr\">.padding()</code> or <code dir=\"ltr\">.font(.headline)</code> that wraps a SwiftUI view in a new view with a change applied. Modifiers apply in order, so their order matters.","lesson":"l-sw-3-1"},{"id":"state","term":"@State","definition":"A SwiftUI property wrapper that stores a value the view owns outside the view struct, so it survives re-renders and triggers an update when it changes.","lesson":"l-sw-3-2"},{"id":"binding","term":"Binding","definition":"A two-way connection to a value owned elsewhere, written with a <code dir=\"ltr\">$</code> prefix. Controls such as <code dir=\"ltr\">Toggle</code> and <code dir=\"ltr\">TextField</code> take bindings so they can read and write the source of truth.","lesson":"l-sw-3-2"},{"id":"observable","term":"@Observable","definition":"A macro from the Observation framework that makes a class’s properties trackable, so SwiftUI re-renders only the views whose body read a property that changed.","lesson":"l-sw-3-2"},{"id":"navigation-stack","term":"NavigationStack","definition":"A SwiftUI container that pushes and pops screens. <code dir=\"ltr\">NavigationLink(value:)</code> selects a value and <code dir=\"ltr\">.navigationDestination(for:)</code> decides which screen shows it.","lesson":"l-sw-3-3"},{"id":"structured-concurrency","term":"Structured concurrency","definition":"Running async work as child tasks, with <code dir=\"ltr\">async let</code> or task groups, that must finish before their parent returns. Cancelling the parent cancels every child automatically.","lesson":"l-sw-4-1"},{"id":"actor","term":"Actor","definition":"A reference type that protects its mutable state by running one call at a time. Code outside the actor must use <code dir=\"ltr\">await</code> to reach it, which prevents data races.","lesson":"l-sw-4-1"},{"id":"sendable","term":"Sendable","definition":"A protocol marking types that are safe to pass between concurrency domains. Structs made of Sendable values qualify automatically; plain classes with mutable properties don’t.","lesson":"l-sw-4-1"},{"id":"main-actor","term":"@MainActor","definition":"An attribute that isolates code or a type to the main actor, the main thread where UI runs. New Xcode app projects make it the default isolation.","lesson":"l-sw-4-1"},{"id":"codable","term":"Codable","definition":"The combination of <code dir=\"ltr\">Decodable</code> and <code dir=\"ltr\">Encodable</code>, which lets the compiler generate code to convert your types to and from formats such as JSON.","lesson":"l-sw-4-2"},{"id":"swiftdata-model","term":"@Model (SwiftData)","definition":"A macro that turns a class into persisted SwiftData data. You read models with <code dir=\"ltr\">@Query</code> and insert or delete them through the model context, which autosaves.","lesson":"l-sw-4-3"},{"id":"swift-testing","term":"Swift Testing","definition":"Apple’s testing framework where tests are functions marked <code dir=\"ltr\">@Test</code>, checked with <code dir=\"ltr\">#expect</code> and <code dir=\"ltr\">#require</code>, and parameterized with <code dir=\"ltr\">arguments:</code>.","lesson":"l-sw-4-4"},{"id":"testflight","term":"TestFlight","definition":"Apple’s beta distribution service. Builds uploaded to App Store Connect reach up to 100 internal testers immediately and up to 10,000 external testers after Beta App Review.","lesson":"l-sw-4-4"}]}