<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Fatbobman's Swift Weekly]]></title><description><![CDATA[Share excellent articles about Swift, SwiftUI, Core Data, SwiftData every week]]></description><link>https://weekly.fatbobman.com</link><image><url>https://substackcdn.com/image/fetch/$s_!n1kc!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bf31f26-d840-47e6-8ec9-0f656c1a96ca_1280x1280.png</url><title>Fatbobman&apos;s Swift Weekly</title><link>https://weekly.fatbobman.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 14 Apr 2026 20:04:03 GMT</lastBuildDate><atom:link href="https://weekly.fatbobman.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[fatbobman]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[fatbobman@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[fatbobman@substack.com]]></itunes:email><itunes:name><![CDATA[Fatbobman(东坡肘子)]]></itunes:name></itunes:owner><itunes:author><![CDATA[Fatbobman(东坡肘子)]]></itunes:author><googleplay:owner><![CDATA[fatbobman@substack.com]]></googleplay:owner><googleplay:email><![CDATA[fatbobman@substack.com]]></googleplay:email><googleplay:author><![CDATA[Fatbobman(东坡肘子)]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Fatbobman's Swift Weekly #131]]></title><description><![CDATA[Copyright Walls Demolished by Vibe Coding, and the Developer's New Moat]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-131</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-131</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 13 Apr 2026 12:03:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XVoV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XVoV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XVoV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 424w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 848w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 1272w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XVoV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp" width="1456" height="896" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:896,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14340,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/194017694?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XVoV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 424w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 848w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 1272w, https://substackcdn.com/image/fetch/$s_!XVoV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91e7d9ff-13f0-4ffc-9150-e0ece655730b_1920x1182.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@helloimnik?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Nik</a> on <a href="https://unsplash.com/photos/yellow-and-white-round-plastic-toy-zYdYz7JlevE?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Copyright Walls Demolished by Vibe Coding, and the Developer&#8217;s New Moat</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-131/">Read on web &#8594;</a></p><p>Anthropic recently announced that because its latest model, Mythos, has become &#8220;too powerful&#8221; at cybersecurity work and software vulnerability discovery&#8212;reaching a level the company finds unsettling&#8212;it has taken the unusually restrained step of not releasing the model publicly. Access is limited to a handful of critical infrastructure companies within Project Glasswing, and ordinary developers cannot reach it through the API either. (Some analysts have pointed out, of course, that this arrangement also conveniently helps prevent model distillation and locks in enterprise-tier customers.) But even with this &#8220;beast&#8221; kept on a leash for the moment, the coding capabilities of today&#8217;s mainstream AI models are already more than enough to make cloning a product trivially easy.</p><p>Last week, a developer on Reddit claimed that he had spent a year &#8220;reverse-engineering the SwiftUI API&#8221; to build an entirely new Swift web framework. The post was fluent and precise in its terminology, and it drew considerable attention. Paul Hudson soon appeared in the comments and called it out: the so-called &#8220;independent research&#8221; was in fact little more than a string replacement performed on his MIT-licensed open-source project <a href="https://github.com/twostraws/Ignite">Ignite</a>&#8212;down to the point that the original author&#8217;s personal, stylistically distinctive code comments had been preserved verbatim. The entire repository was then squashed into a single commit to erase its history, and the license was illicitly changed to the copyleft GPL. A number of developers in the community suspect that the &#8220;reverse-engineering SwiftUI&#8221; narrative itself was AI-generated as well. More intriguingly, the author in question was actually a major contributor to Ignite himself&#8212;when Vibe Coding has driven the cost of &#8220;repackaging a project&#8221; close to zero, &#8220;I was involved in this&#8221; can itself become a rhetorical device for blurring the lines of responsibility.</p><p>Around the same time, Vibe Island&#8212;a polished macOS menu-bar app for monitoring AI coding agents&#8212;was pixel-for-pixel cloned shortly after its release. Although the copycat published its code under the banner of an &#8220;open-source alternative,&#8221; the impact on the original author&#8217;s sales and creative motivation was real and significant. Yet even if the author wished to pursue legal action, he would run into a new problem of the times: in both establishing ownership and enforcing his rights, he might need to prove that his work possesses sufficient human originality and account for the extent of AI-generated content involved&#8212;otherwise, he would face considerably greater legal uncertainty.</p><p>Indeed, the legal walls protecting code are beginning to crumble on the &#8220;ownership side&#8221; first. Last month, China&#8217;s Copyright Protection Centre officially rolled out a new version of its software copyright registration application and accompanying review rules, which explicitly require the filer to make a notarized personal commitment that &#8220;no AI has been used to develop the code, author the documentation, or generate the registration materials,&#8221; and the review process now focuses on whether the human intellectual contribution clears the originality threshold required by copyright law. Content without substantive human involvement will struggle to obtain registration. Violators may also be placed on a registry of dishonest filers, with consequences tied to their personal credit records.</p><p>This trend is converging with the recent direction of case law in Europe and the United States: if a piece of code is primarily &#8220;rewritten or recombined&#8221; at high speed by an AI responding to prompts, its chances of obtaining copyright protection drop considerably.</p><p>We have to face a harsh truth: &#8220;I had a brilliant idea and vibe-coded it into existence&#8221; is no longer enough to constitute a business moat. The new paradigm we call Vibe Coding has not only reshaped development workflows and dramatically improved efficiency&#8212;it has simultaneously shaken the foundational logic of the software copyright system from three directions at once: the bar for ownership has risen, the burden of proof for infringement has grown heavier, and functional cloning has been quietly normalized.</p><p>What makes it all the more disheartening is that, controversial as these clone projects may be, they still rack up no small number of stars on GitHub. That suggests that when the cost of getting something is vanishingly low, moral appeals alone can no longer hold back the rush toward &#8220;free equivalents.&#8221;</p><p>Perhaps, as we noted in <a href="https://fatbobman.com/en/weekly/issue-120/">Issue 120&#8217;s discussion of Skip&#8217;s move to go open source</a>&#8212;in an era where the cost of implementing code is approaching zero and any app can be cloned at any moment by an AI, building behind closed doors and &#8220;selling the tool&#8221; will only get harder. Forging real connections with users, and turning &#8220;the credibility of the maker and the trust of the community&#8221; into brand equity that cannot be copied&#8212;this, perhaps, is the true core competency and moat for developers in the years ahead.</p><p><a href="https://fatbobman.com/en/weekly/issue-130/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0131-01">Swift Blog Carnival: Tiny Languages</a></strong></h3><p>The Swift community has launched its first <a href="https://swiftcarnival.github.io/">Blog Carnival</a>, with April&#8217;s theme being <strong>Tiny Languages</strong>. <a href="https://mastodon.social/@ctietze">Christian Tietze</a> invites developers to write about this topic&#8212;custom DSLs, result builders, scripting languages, routing rules&#8230; any perspective related to &#8220;tiny languages&#8221; is welcome. The submission deadline is May 1.</p><p>So far, three entries have been published:</p><ul><li><p><a href="https://mastodon.social/@mattiem">Matt Massicotte</a> reflects on his journey <a href="https://l.fatbobman.com/w0131-01a">from Rake to Make</a>, and then to various Swift-based task runners, noting that he still hasn&#8217;t found an ideal replacement</p></li><li><p><a href="https://x.com/liscio">Chris Liscio</a> shares the design of <a href="https://l.fatbobman.com/w0131-01b">Capo&#8217;s embedded DSL</a>, used to describe keyboard and MIDI bindings, built on Point-Free&#8217;s <code>swift-parsing</code> library</p></li><li><p><a href="https://x.com/krugazor">Nicolas Zinovieff</a> presents an experimental <a href="https://l.fatbobman.com/w0131-01c">symbolic math DSL</a>, leveraging protocols and operator overloading to make expressions like <code>(1 + 2 * "X") * (3 - "Y")</code> valid Swift code, with lazy evaluation when concrete values are provided&#8212;implemented in under 300 lines</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-02">Indicating Selection in macOS Menus Using SwiftUI</a></strong></h3><p>SwiftUI provides several components for representing selection, such as <code>Picker</code>, <code>Toggle</code>, and <code>Menu</code>. However, clearly guiding users through choices and accurately reflecting the current selection is not as straightforward as it may seem. <a href="https://x.com/gabtheodor">Gabriel Theodoropoulos</a> starts from basic <code>Button</code> implementations and gradually evolves toward <code>Picker</code> and <code>Toggle</code>, systematically outlining common approaches and their limitations.</p><p>The value of this article lies not in presenting a &#8220;single correct solution,&#8221; but in reminding developers that SwiftUI&#8217;s standard components do not automatically guarantee the best user experience. In practice, you still need to balance <strong>system consistency</strong> and <strong>implementation flexibility</strong>.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-03">Building List Replacement in SwiftUI</a></strong></h3><p>Choosing between <code>List</code> and <code>ScrollView + LazyStack</code> remains a common challenge for SwiftUI developers. In this article, <a href="https://x.com/mecid">Majid Jabrayilov</a> rebuilds parts of his CardioBot app using the SwiftUI Container View API (iOS 18+), creating three reusable components&#8212;ScrollingSurface, DividedCard, and SectionedSurface&#8212;as a replacement for <code>List</code>.</p><p>These components closely mirror the usage of <code>List</code> + <code>Section</code>, while eliminating constraints tied to <code>List</code>, such as <code>listRowBackground</code> and <code>listItemTint</code>.</p><blockquote><p><code>List</code> is not just a &#8220;styled LazyVStack&#8221;&#8212;the two differ fundamentally in architecture, scrolling behavior, integration with navigation containers, and performance on large datasets. For a deeper comparison, see this <a href="https://fatbobman.com/en/posts/list-or-lazyvstack/">previous article</a>.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-04">AppIntents meet MCP</a></strong></h3><p>While many still see AppIntents as a companion to Siri and Shortcuts, <a href="https://x.com/FloWritesCode">Florian Schweizer</a> explores a more forward-looking direction: exposing AppIntents as MCP (Model Context Protocol) tools, enabling LLMs to directly interact with your app&#8217;s capabilities.</p><p>Based on <a href="https://github.com/Cocoanetics/SwiftMCP.git">SwiftMCP</a>, Florian uses macros to build an MCP server and seamlessly maps AppIntents into MCP tools. This allows AI agents to invoke app functionality directly, enabling cross-app automation.</p><blockquote><p>Rumors have suggested since last year that Apple is bringing MCP support into its ecosystem. Perhaps we&#8217;ll get answers at WWDC 26 in a couple of months.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-05">Ride the Lightning Air: Building Interactive WidgetKit Widgets</a></strong></h3><p>Many developers are misled by WidgetKit documentation, mistakenly treating <code>AppIntentTimelineProvider</code> as the key to interactive widgets. In reality, it is designed for <strong>user-configurable widgets</strong> (e.g., editing options via long-press), not for interactivity.</p><p>The actual foundation for interactive widgets remains <code>TimelineProvider</code>. <a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> demonstrates the correct approach through a fictional airline widget: Using <code>TimelineProvider</code> + <code>Button(intent:)</code> + App Group shared storage to build interactive widgets.</p><p>The data flow forms a clean loop:  User action &#8594; Intent execution &#8594; State update &#8594; Widget reload &#8594; UI refresh</p><div><hr></div><h3><strong>File Storage and iCloud: A Complete View from Local to Cloud</strong></h3><p>In iOS and macOS development (and usage), file storage is often treated as a basic capability&#8212;but it actually defines the lifecycle and behavior of your data.</p><p>In <a href="https://l.fatbobman.com/w0131-06a">Working with files and directories in iOS</a>, <a href="https://x.com/tanaschita">Natascha Fadeeva</a> systematically explains the App Sandbox structure and the roles of <code>Documents</code>, <code>Library</code>, and <code>Caches</code>, helping developers understand where different types of data should reside&#8212;and how to avoid unnecessary iCloud backups.</p><p>Meanwhile, <a href="https://x.com/howardnoakley">Howard Oakley</a> in <a href="https://l.fatbobman.com/w0131-06b">Understanding and Testing iCloud</a> explores what happens next: iCloud is not a single service, but a collection of subsystems such as CloudKit, iCloud Drive, and system update services. Different types of data follow different synchronization and backup paths.</p><blockquote><p>File placement is not just an organizational concern&#8212;it defines whether data is backed up, synchronized, and how it flows across devices.</p></blockquote><p>As a result, iCloud issues are rarely just about &#8220;whether sync is enabled.&#8221; They often involve multiple layers, including client state, network conditions, caching behavior, and server-side throttling.</p><div><hr></div><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0131-07">Bad Dock: Animate Your Dock Icon</a></strong></h3><p>This is a &#8220;ridiculous yet serious&#8221; macOS experiment. <a href="https://ericmartz.com/">Eric Martz</a> uses the public <code>NSDockTile</code> / <code>NSDockTilePlugin</code> APIs to bypass the squircle constraints introduced in Big Sur and render a video stream directly inside a Dock icon.</p><p>The implementation is straightforward but well-structured: decoding video with <code>AVAssetReader</code>, reducing frame rate to ~12fps, and managing memory with a ring buffer. The result is a polished technical proof-of-concept built from what initially seems like a playful idea.</p><blockquote><p>The real value of projects like this lies not in their functionality, but in revealing that system API boundaries often extend far beyond what the documentation suggests.</p></blockquote><p>Note: This project implements <strong>runtime dynamic Dock icons</strong> (continuously rendered while the app is running). After the app exits, only a static custom icon can be preserved via <code>NSDockTilePlugin</code>.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-131?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-131?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#34987; Vibe &#25703;&#27585;&#30340;&#29256;&#26435;&#22721;&#22418;&#65292;&#19982;&#24320;&#21457;&#32773;&#30340;&#26032;&#25252;&#22478;&#27827;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-131/">&#32593;&#39029;&#29256;</a></strong></p><p>Anthropic &#19981;&#20037;&#21069;&#23459;&#24067;&#65292;&#30001;&#20110;&#20854;&#26368;&#26032;&#27169;&#22411; Mythos &#22312;&#32593;&#32476;&#23433;&#20840;&#19982;&#20195;&#30721;&#28431;&#27934;&#25366;&#25496;&#26041;&#38754;&#30340;&#33021;&#21147;&#8220;&#36807;&#20110;&#24378;&#22823;&#8221;&#65292;&#24050;&#36798;&#21040;&#20196;&#20154;&#19981;&#23433;&#30340;&#31243;&#24230;&#65292;&#22240;&#27492;&#37319;&#21462;&#20102;&#26497;&#20026;&#32597;&#35265;&#30340;&#20811;&#21046;&#25514;&#26045;&#65306;&#20165;&#21521; Project Glasswing &#20869;&#30340;&#23569;&#25968;&#20851;&#38190;&#22522;&#30784;&#35774;&#26045;&#20225;&#19994;&#24320;&#25918;&#65292;&#19981;&#38754;&#21521;&#20844;&#20247;&#21457;&#24067;&#65292;&#26222;&#36890;&#24320;&#21457;&#32773;&#20063;&#26080;&#27861;&#36890;&#36807; API &#35843;&#29992;&#65288;&#24403;&#28982;&#65292;&#20063;&#26377;&#20998;&#26512;&#32773;&#25351;&#20986;&#65292;&#36825;&#19968;&#23433;&#25490;&#21516;&#26679;&#26377;&#21161;&#20110;&#38450;&#27490;&#27169;&#22411;&#33976;&#39311;&#65292;&#24182;&#38145;&#23450;&#20225;&#19994;&#32423;&#23458;&#25143;&#65289;&#12290;&#20294;&#21363;&#20415;&#36825;&#22836;&#8220;&#29467;&#20861;&#8221;&#34987;&#26242;&#26102;&#25353;&#20303;&#65292;&#24403;&#21069;&#20027;&#27969; AI &#27169;&#22411;&#30340;&#20195;&#30721;&#33021;&#21147;&#65292;&#24050;&#32463;&#36275;&#20197;&#35753;&#22797;&#21046;&#19968;&#27454;&#20135;&#21697;&#21464;&#24471;&#36731;&#32780;&#26131;&#20030;&#12290;</p><p>&#19978;&#21608;&#65292;Reddit &#19978;&#19968;&#20301;&#24320;&#21457;&#32773;&#23459;&#31216;&#65292;&#33258;&#24049;&#33457;&#20102;&#19968;&#24180;&#26102;&#38388;&#8220;&#36870;&#21521; SwiftUI API&#8221;&#65292;&#25171;&#36896;&#20102;&#19968;&#20010;&#20840;&#26032;&#30340; Swift Web &#26694;&#26550;&#12290;&#24086;&#23376;&#34892;&#25991;&#27969;&#30021;&#12289;&#26415;&#35821;&#32771;&#31350;&#65292;&#19968;&#24230;&#21560;&#24341;&#20102;&#19981;&#23569;&#20851;&#27880;&#12290;&#20294; Paul Hudson &#24456;&#24555;&#29616;&#36523;&#35780;&#35770;&#21306;&#25171;&#20551;&#65306;&#25152;&#35859;&#8220;&#29420;&#31435;&#30740;&#21457;&#8221;&#65292;&#23454;&#38469;&#19978;&#21482;&#26159;&#23558;&#20182;&#30340; MIT &#24320;&#28304;&#39033;&#30446; <a href="https://github.com/twostraws/Ignite">Ignite</a> &#20570;&#20102;&#31616;&#21333;&#30340;&#23383;&#31526;&#20018;&#26367;&#25442;&#65292;&#29978;&#33267;&#36830;&#21407;&#20316;&#32773;&#24102;&#26377;&#20010;&#20154;&#39118;&#26684;&#30340;&#20195;&#30721;&#27880;&#37322;&#37117;&#21407;&#23553;&#19981;&#21160;&#20445;&#30041;&#65292;&#38543;&#21518;&#23558;&#25972;&#20010;&#20179;&#24211;&#21387;&#32553;&#20026;&#19968;&#27425;&#25552;&#20132;&#20197;&#25273;&#38500;&#21382;&#21490;&#65292;&#24182;&#36829;&#35268;&#25913;&#20026;&#20855;&#26377;&#20256;&#26579;&#24615;&#30340; GPL &#21327;&#35758;&#12290;&#31038;&#21306;&#20013;&#19981;&#23569;&#24320;&#21457;&#32773;&#37117;&#24576;&#30097;&#65292;&#36825;&#22871;&#8220;&#36870;&#21521; SwiftUI&#8221;&#30340;&#21465;&#20107;&#26412;&#36523;&#20063;&#26159;&#30001; AI &#29983;&#25104;&#12290;&#26356;&#32784;&#20154;&#23547;&#21619;&#30340;&#26159;&#65292;&#35813;&#20316;&#32773;&#26412;&#23601;&#26159; Ignite &#30340;&#20027;&#35201;&#36129;&#29486;&#32773;&#20043;&#19968;&#8212;&#8212;&#24403; Vibe Coding &#23558;&#8220;&#37325;&#26032;&#25171;&#21253;&#19968;&#20010;&#39033;&#30446;&#8221;&#30340;&#25104;&#26412;&#38477;&#33267;&#26497;&#20302;&#26102;&#65292;&#8220;&#25105;&#21442;&#19982;&#36807;&#8221;&#26412;&#36523;&#20063;&#21487;&#33021;&#25104;&#20026;&#19968;&#31181;&#27169;&#31946;&#36131;&#20219;&#36793;&#30028;&#30340;&#35805;&#26415;&#12290;</p><p>&#20960;&#20046;&#22312;&#21516;&#19968;&#26102;&#38388;&#65292;macOS &#19978;&#31934;&#33268;&#30340; AI &#24037;&#20316;&#29366;&#24577;&#30417;&#25511;&#24212;&#29992; Vibe Island &#22312;&#21457;&#24067;&#21518;&#19981;&#20037;&#20415;&#36973;&#36935;&#20102;&#20687;&#32032;&#32423;&#20223;&#21046;&#12290;&#23613;&#31649;&#20223;&#21046;&#32773;&#25171;&#30528;&#8220;&#24320;&#28304;&#26367;&#20195;&#21697;&#8221;&#30340;&#26071;&#21495;&#20844;&#24320;&#20102;&#20195;&#30721;&#65292;&#36825;&#20381;&#28982;&#23545;&#21407;&#20316;&#32773;&#30340;&#21830;&#19994;&#38144;&#21806;&#19982;&#21019;&#20316;&#28909;&#24773;&#36896;&#25104;&#20102;&#26126;&#26174;&#20914;&#20987;&#12290;&#28982;&#32780;&#65292;&#21363;&#20415;&#20316;&#32773;&#24076;&#26395;&#37319;&#21462;&#27861;&#24459;&#25163;&#27573;&#65292;&#20063;&#23558;&#38754;&#20020;&#19968;&#20010;&#26032;&#30340;&#26102;&#20195;&#38590;&#39064;&#65306;&#22312;&#30830;&#26435;&#19982;&#32500;&#26435;&#36807;&#31243;&#20013;&#65292;&#20182;&#21487;&#33021;&#38656;&#35201;&#35777;&#26126;&#20854;&#20316;&#21697;&#20855;&#22791;&#36275;&#22815;&#30340;&#20154;&#31867;&#29420;&#21019;&#24615;&#65292;&#24182;&#35828;&#26126; AI &#29983;&#25104;&#20869;&#23481;&#30340;&#21442;&#19982;&#31243;&#24230;&#65292;&#21542;&#21017;&#23558;&#38754;&#20020;&#26356;&#39640;&#30340;&#19981;&#30830;&#23450;&#24615;&#12290;</p><p>&#20107;&#23454;&#19978;&#65292;&#20195;&#30721;&#30340;&#27861;&#24459;&#22721;&#22418;&#27491;&#20174;&#8220;&#30830;&#26435;&#31471;&#8221;&#24320;&#22987;&#26494;&#21160;&#12290;&#19978;&#20010;&#26376;&#65292;&#20013;&#22269;&#29256;&#26435;&#20445;&#25252;&#20013;&#24515;&#27491;&#24335;&#21551;&#29992;&#26032;&#29256;&#12298;&#35745;&#31639;&#26426;&#36719;&#20214;&#33879;&#20316;&#26435;&#30331;&#35760;&#30003;&#35831;&#34920;&#12299;&#21450;&#30456;&#20851;&#23457;&#26597;&#26032;&#35268;&#65292;&#26126;&#30830;&#35201;&#27714;&#32463;&#21150;&#20154;&#23454;&#21517;&#25215;&#35834;&#8220;&#26410;&#20351;&#29992; AI &#24320;&#21457;&#32534;&#20889;&#20195;&#30721;&#12289;&#25776;&#20889;&#25991;&#26723;&#25110;&#29983;&#25104;&#30331;&#35760;&#26448;&#26009;&#8221;&#65292;&#24182;&#22312;&#23457;&#26597;&#20013;&#37325;&#28857;&#35780;&#20272;&#20154;&#31867;&#26234;&#21147;&#25237;&#20837;&#26159;&#21542;&#36798;&#21040;&#33879;&#20316;&#26435;&#27861;&#25152;&#35201;&#27714;&#30340;&#8220;&#29420;&#21019;&#24615;&#8221;&#38376;&#27099;&#65307;&#32570;&#20047;&#23454;&#36136;&#20154;&#31867;&#21442;&#19982;&#30340;&#20869;&#23481;&#65292;&#23558;&#38590;&#20197;&#33719;&#24471;&#30830;&#26435;&#12290;&#36829;&#35268;&#32773;&#36824;&#21487;&#33021;&#34987;&#32435;&#20837;&#22833;&#20449;&#21517;&#21333;&#65292;&#24182;&#19982;&#20010;&#20154;&#24449;&#20449;&#25346;&#38057;&#12290;</p><p>&#36825;&#19968;&#36235;&#21183;&#20063;&#19982;&#27431;&#32654;&#36817;&#26399;&#30340;&#21028;&#20363;&#26041;&#21521;&#36235;&#20110;&#19968;&#33268;&#65306;&#22914;&#26524;&#19968;&#27573;&#20195;&#30721;&#20027;&#35201;&#30001; AI &#26681;&#25454;&#25552;&#31034;&#35789;&#24555;&#36895;&#8220;&#25913;&#20889;&#25110;&#37325;&#32452;&#8221;&#29983;&#25104;&#65292;&#20854;&#33719;&#24471;&#33879;&#20316;&#26435;&#20445;&#25252;&#30340;&#21487;&#33021;&#24615;&#23558;&#26174;&#33879;&#38477;&#20302;&#12290;</p><p>&#25105;&#20204;&#24517;&#39035;&#25215;&#35748;&#19968;&#20010;&#27531;&#37239;&#30340;&#20107;&#23454;&#65306;&#8220;&#25105;&#26377;&#19968;&#20010;&#32477;&#22937;&#30340; Idea&#65292;&#24182;&#25226;&#23427; Vibe &#25104;&#20195;&#30721;&#8221;&#65292;&#24050;&#32463;&#19981;&#36275;&#20197;&#26500;&#25104;&#21830;&#19994;&#22721;&#22418;&#12290;&#36825;&#31181;&#21517;&#20026; Vibe Coding &#30340;&#26032;&#33539;&#24335;&#65292;&#19981;&#20165;&#25913;&#21464;&#20102;&#24320;&#21457;&#27969;&#31243;&#12289;&#26174;&#33879;&#25552;&#21319;&#20102;&#25928;&#29575;&#65292;&#20063;&#20174;&#19977;&#20010;&#26041;&#21521;&#21516;&#26102;&#21160;&#25671;&#20102;&#36719;&#20214;&#29256;&#26435;&#20307;&#31995;&#30340;&#22522;&#30784;&#36923;&#36753;&#65306;&#30830;&#26435;&#38376;&#27099;&#25552;&#39640;&#12289;&#20405;&#26435;&#20030;&#35777;&#21464;&#38590;&#12289;&#21151;&#33021;&#22797;&#21051;&#34987;&#40664;&#35768;&#12290;</p><p>&#20196;&#20154;&#36951;&#25022;&#30340;&#26159;&#65292;&#21363;&#20415;&#36825;&#20123;&#20811;&#38534;&#39033;&#30446;&#39281;&#21463;&#20105;&#35758;&#65292;&#23427;&#20204;&#20381;&#28982;&#22312; GitHub &#19978;&#25910;&#33719;&#20102;&#19981;&#33778;&#30340; Star&#12290;&#36825;&#35828;&#26126;&#65292;&#22312;&#33719;&#21462;&#25104;&#26412;&#26497;&#20302;&#30340;&#21069;&#25552;&#19979;&#65292;&#20165;&#38752;&#36947;&#24503;&#21628;&#21505;&#65292;&#24050;&#32463;&#24456;&#38590;&#38459;&#27490;&#20154;&#20204;&#23545;&#8220;&#20813;&#36153;&#24179;&#26367;&#8221;&#30340;&#36861;&#36880;&#12290;</p><p>&#25110;&#35768;&#65292;&#27491;&#22914;&#25105;&#20204;&#22312; <a href="https://fatbobman.com/zh/weekly/issue-120/">&#31532; 120 &#26399;&#21608;&#25253;&#20013;&#35752;&#35770; Skip &#30340;&#24320;&#28304;&#20030;&#25514;</a> &#26102;&#25152;&#25552;&#21040;&#30340;&#37027;&#26679;&#8212;&#8212;&#22312;&#20195;&#30721;&#23454;&#29616;&#25104;&#26412;&#36235;&#36817;&#20110;&#38646;&#12289;&#24212;&#29992;&#38543;&#26102;&#21487;&#33021;&#34987; AI &#19968;&#38190;&#20811;&#38534;&#30340;&#24403;&#19979;&#65292;&#38381;&#38376;&#36896;&#36710;&#8220;&#21334;&#24037;&#20855;&#8221;&#23558;&#21464;&#24471;&#24840;&#21457;&#22256;&#38590;&#12290;&#19982;&#29992;&#25143;&#24314;&#31435;&#30495;&#23454;&#36830;&#25509;&#65292;&#23558;&#8220;&#20986;&#21697;&#26041;&#30340;&#20449;&#35465;&#19982;&#31038;&#21306;&#30340;&#20449;&#20219;&#8221;&#36716;&#21270;&#20026;&#19981;&#21487;&#22797;&#21046;&#30340;&#21697;&#29260;&#36164;&#20135;&#65292;&#25110;&#35768;&#25165;&#26159;&#26410;&#26469;&#24320;&#21457;&#32773;&#30495;&#27491;&#30340;&#26680;&#24515;&#31454;&#20105;&#21147;&#19982;&#25252;&#22478;&#27827;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-130/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0131-01">Swift Blog Carnival: Tiny Languages</a></strong></h3><p>Swift &#31038;&#21306;&#27491;&#22312;&#21457;&#36215;&#31532;&#19968;&#23626; <a href="https://swiftcarnival.github.io/">Blog Carnival</a>&#65292;&#22235;&#26376;&#30340;&#20027;&#39064;&#26159; <strong>Tiny Languages</strong>&#12290;<a href="https://mastodon.social/@ctietze">Christian Tietze</a> &#36992;&#35831;&#24320;&#21457;&#32773;&#22260;&#32469;&#36825;&#19968;&#20027;&#39064;&#25776;&#20889;&#21338;&#23458;&#65306;&#33258;&#23450;&#20041; DSL&#12289;Result Builder&#12289;&#33050;&#26412;&#35299;&#26512;&#22120;&#12289;&#36335;&#30001;&#35268;&#21017;&#8230;&#8230;&#20219;&#20309;&#19982;&#8220;&#24494;&#22411;&#35821;&#35328;&#8221;&#30456;&#20851;&#30340;&#24605;&#32771;&#37117;&#21487;&#20197;&#20316;&#20026;&#20999;&#20837;&#28857;&#65292;&#25130;&#27490;&#26085;&#26399;&#20026; 5 &#26376; 1 &#26085;&#12290;</p><p>&#30446;&#21069;&#24050;&#26377;&#19977;&#31687;&#25237;&#31295;&#65306;</p><ul><li><p><a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#22238;&#39038;&#20102;&#20182; <a href="https://l.fatbobman.com/w0131-01a">&#20174; Rake &#21040; Make</a>&#65292;&#20877;&#21040;&#21508;&#31867; Swift &#20219;&#21153;&#36816;&#34892;&#22120;&#30340;&#25506;&#32034;&#21382;&#31243;&#65292;&#22374;&#35328;&#33267;&#20170;&#20173;&#26410;&#25214;&#21040;&#29702;&#24819;&#26367;&#20195;&#21697;</p></li><li><p><a href="https://x.com/liscio">Chris Liscio</a> &#20998;&#20139;&#20102; <a href="https://l.fatbobman.com/w0131-01b">Capo &#24212;&#29992;&#20869;&#32622; DSL</a> &#30340;&#35774;&#35745;&#65306;&#29992;&#20110;&#25551;&#36848;&#38190;&#30424;&#19982; MIDI &#32465;&#23450;&#65292;&#22522;&#20110; Point-Free &#30340; <code>swift-parsing</code> &#24211;&#26500;&#24314;</p></li><li><p><a href="https://x.com/krugazor">Nicolas Zinovieff</a> &#21017;&#23637;&#31034;&#20102;&#19968;&#20010; <a href="https://l.fatbobman.com/w0131-01c">&#31526;&#21495;&#25968;&#23398; DSL</a> &#30340;&#23454;&#39564;&#65306;&#36890;&#36807;&#21327;&#35758;&#19982;&#36816;&#31639;&#31526;&#37325;&#36733;&#65292;&#35753; <code>(1 + 2 * "X") * (3 - "Y")</code>&#25104;&#20026;&#21512;&#27861;&#30340; Swift &#34920;&#36798;&#24335;&#65292;&#24182;&#22312;&#25552;&#20379;&#20855;&#20307;&#20540;&#26102;&#24816;&#24615;&#27714;&#20540;&#65292;&#26680;&#24515;&#23454;&#29616;&#19981;&#36229;&#36807; 300 &#34892;</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-02">&#22312; macOS &#33756;&#21333;&#20013;&#28165;&#26224;&#26174;&#31034;&#24403;&#21069;&#36873;&#20013;&#29366;&#24577; (Indicating Selection in macOS Menus Using SwiftUI)</a></strong></h3><p>SwiftUI &#25552;&#20379;&#20102;&#19981;&#23569;&#29992;&#20110;&#34920;&#36798;&#36873;&#25321;&#30340;&#32452;&#20214;&#65292;&#20363;&#22914; <code>Picker</code>&#12289;<code>Toggle</code>&#12289;<code>Menu</code>&#65292;&#20294;&#22914;&#20309;&#28165;&#26224;&#22320;&#24341;&#23548;&#29992;&#25143;&#36827;&#34892;&#36873;&#25321;&#65292;&#24182;&#20934;&#30830;&#26631;&#35782;&#24403;&#21069;&#36873;&#20013;&#39033;&#65292;&#24182;&#27809;&#26377;&#24819;&#35937;&#20013;&#37027;&#26679;&#29702;&#25152;&#24403;&#28982;&#12290;<a href="https://x.com/gabtheodor">Gabriel Theodoropoulos</a> &#20174;&#26368;&#22522;&#30784;&#30340; <code>Button</code> &#20986;&#21457;&#65292;&#19968;&#27493;&#27493;&#28436;&#36827;&#21040; <code>Picker</code> &#19982; <code>Toggle</code>&#65292;&#31995;&#32479;&#26803;&#29702;&#20102;&#20960;&#31181;&#24120;&#35265;&#26041;&#26696;&#21450;&#20854;&#21508;&#33258;&#30340;&#23616;&#38480;&#12290;&#25991;&#31456;&#30340;&#20215;&#20540;&#19981;&#22312;&#20110;&#32473;&#20986;&#8220;&#21807;&#19968;&#27491;&#30830;&#35299;&#8221;&#65292;&#32780;&#22312;&#20110;&#25552;&#37266;&#24320;&#21457;&#32773;&#65306;SwiftUI &#25552;&#20379;&#30340;&#26631;&#20934;&#32452;&#20214;&#65292;&#24182;&#19981;&#20250;&#33258;&#21160;&#24102;&#26469;&#26368;&#20339;&#30340;&#29992;&#25143;&#21576;&#29616;&#25928;&#26524;&#12290;&#24456;&#22810;&#26102;&#20505;&#65292;&#20320;&#20173;&#38656;&#22312;&#8220;&#31995;&#32479;&#19968;&#33268;&#24615;&#8221;&#19982;&#8220;&#23454;&#29616;&#33258;&#30001;&#24230;&#8221;&#20043;&#38388;&#20570;&#20986;&#26435;&#34913;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-03">&#26500;&#24314; List &#30340;&#26367;&#20195;&#32452;&#20214; (Building List replacement in SwiftUI)</a></strong></h3><p>&#22914;&#20309;&#22312; <code>List</code> &#19982; <code>ScrollView + LazyStack</code> &#20043;&#38388;&#20570;&#20986;&#36873;&#25321;&#65292;&#19968;&#30452;&#26159;&#22256;&#25200;&#19981;&#23569; SwiftUI &#24320;&#21457;&#32773;&#30340;&#38382;&#39064;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/mecid">Majid Jabrayilov</a> &#22312;&#37325;&#26500;&#20854; CardioBot &#24212;&#29992;&#26102;&#65292;&#36873;&#25321;&#22522;&#20110; SwiftUI &#30340; Container View API&#65288;iOS 18+&#65289;&#26500;&#24314;&#20102;&#19977;&#20010;&#21487;&#22797;&#29992;&#30340; UI &#32452;&#20214;&#65306;ScrollingSurface&#12289;DividedCard&#12289;SectionedSurface&#65292;&#20197;&#26367;&#20195; <code>List</code>&#12290;&#36825;&#20123;&#32452;&#20214;&#22312;&#20351;&#29992;&#26041;&#24335;&#19978;&#19982; <code>List</code> + <code>Section</code> &#39640;&#24230;&#30456;&#20284;&#65292;&#20294;&#24443;&#24213;&#25670;&#33073;&#20102; <code>listRowBackground</code>&#12289;<code>listItemTint</code> &#31561;&#20165;&#22312; <code>List</code> &#20013;&#29983;&#25928;&#30340;&#38480;&#21046;&#12290;</p><blockquote><p><code>List</code> &#24182;&#38750;&#21482;&#26159;&#8220;&#26377;&#40664;&#35748;&#26679;&#24335;&#30340; <code>LazyVStack</code>&#8221;&#8212;&#8212;&#20004;&#32773;&#22312;&#24213;&#23618;&#26550;&#26500;&#12289;&#28378;&#21160;&#25511;&#21046;&#12289;&#19982;&#23548;&#33322;&#23481;&#22120;&#30340;&#21327;&#21516;&#12289;&#20197;&#21450;&#22823;&#25968;&#25454;&#38598;&#19979;&#30340;&#24615;&#33021;&#34920;&#29616;&#19978;&#22343;&#26377;&#26412;&#36136;&#24046;&#24322;&#12290;&#22914;&#20309;&#22312;&#20004;&#32773;&#20043;&#38388;&#20570;&#20986;<a href="https://fatbobman.com/zh/posts/list-or-lazyvstack/">&#32508;&#21512;&#21028;&#26029;</a>&#65292;&#21487;&#20197;&#21442;&#32771;&#36825;&#31687;&#26087;&#25991;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-04">AppIntents meet MCP</a></strong></h3><p>&#24403;&#22823;&#23478;&#36824;&#22312;&#23558; AppIntents &#35270;&#20026; Siri &#19982;&#24555;&#25463;&#25351;&#20196;&#30340;&#8220;&#37197;&#22871;&#24037;&#20855;&#8221;&#26102;&#65292;<a href="https://x.com/FloWritesCode">Florian Schweizer</a> &#32473;&#20986;&#20102;&#19968;&#20010;&#26356;&#20540;&#24471;&#20851;&#27880;&#30340;&#26041;&#21521;&#65306;&#23558; AppIntents &#30452;&#25509;&#26292;&#38706;&#20026; MCP&#65288;Model Context Protocol&#65289;&#24037;&#20855;&#65292;&#20174;&#32780;&#35753; LLM &#33021;&#22815;&#35843;&#29992;&#20320;&#30340;&#24212;&#29992;&#33021;&#21147;&#12290;Florian &#22522;&#20110; <a href="https://github.com/Cocoanetics/SwiftMCP.git">SwiftMCP</a>&#65292;&#36890;&#36807;&#23439;&#26500;&#24314; MCP Server&#65292;&#24182;&#23558; AppIntents &#26080;&#32541;&#26144;&#23556;&#20026; MCP Tools&#65292;&#20351; AI Agent &#33021;&#22815;&#30452;&#25509;&#35843;&#29992;&#24212;&#29992;&#20013;&#30340; Intent&#65292;&#23454;&#29616;&#36328;&#24212;&#29992;&#33258;&#21160;&#21270;&#12290;</p><blockquote><p>&#21435;&#24180;&#20415;&#26377;<a href="https://fatbobman.com/zh/weekly/issue-104/">&#20256;&#38395;</a>&#65292;&#33529;&#26524;&#27491;&#22312;&#20026;&#20854;&#29983;&#24577;&#31995;&#32479;&#24341;&#20837; MCP &#25903;&#25345;&#12290;&#25110;&#35768;&#20877;&#36807;&#20004;&#20010;&#26376;&#65292;&#22312; WWDC 26 &#19978;&#31572;&#26696;&#20415;&#20250;&#25581;&#26195;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0131-05">&#21019;&#24314;&#20132;&#20114;&#24335;&#23567;&#32452;&#20214; (Ride the Lightning Air: Building Interactive WidgetKit Widgets)</a></strong></h3><p>&#24456;&#22810;&#24320;&#21457;&#32773;&#37117;&#20250;&#34987; WidgetKit &#30340;&#25991;&#26723;&#35823;&#23548;&#65292;&#38169;&#23558; <code>AppIntentTimelineProvider</code> &#35270;&#20026;&#23454;&#29616;&#20132;&#20114;&#25353;&#38062;&#30340;&#20851;&#38190;&#8212;&#8212;&#23454;&#21017;&#19981;&#28982;&#12290;&#23427;&#26159;&#20026;&#8220;&#29992;&#25143;&#21487;&#37197;&#32622; Widget&#8221;&#65288;&#22914;&#38271;&#25353;&#21518;&#32534;&#36753;&#35774;&#32622;&#39033;&#65289;&#20934;&#22791;&#30340;&#65292;&#19982;&#20132;&#20114;&#34892;&#20026;&#24182;&#26080;&#30452;&#25509;&#20851;&#31995;&#12290;&#32780;&#30495;&#27491;&#29992;&#20110;&#23454;&#29616;&#20132;&#20114;&#65288;&#25353;&#38062;&#28857;&#20987;&#35302;&#21457;&#34892;&#20026;&#65289;&#30340;&#65292;&#20381;&#28982;&#26159;&#26368;&#22522;&#30784;&#30340; <code>TimelineProvider</code>&#12290;<a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> &#36890;&#36807;&#19968;&#20010;&#34394;&#26500;&#33322;&#31354;&#20844;&#21496;&#30340;&#30331;&#26426;&#29366;&#24577; Widget&#65292;&#23436;&#25972;&#28436;&#31034;&#20102;&#27491;&#30830;&#36335;&#24452;&#65306;&#20351;&#29992; <code>TimelineProvider</code></p><ul><li><p><code>Button(intent:)</code> + AppGroup &#20849;&#20139;&#23384;&#20648;&#26469;&#26500;&#24314;&#20132;&#20114;&#24335; Widget&#12290;</p><p>&#25972;&#20010;&#25968;&#25454;&#27969;&#24418;&#25104;&#19968;&#20010;&#28165;&#26224;&#30340;&#38381;&#29615;&#65306;&#29992;&#25143;&#25805;&#20316; &#8594; Intent &#25191;&#34892; &#8594; &#29366;&#24577;&#20889;&#20837; &#8594; Widget &#21047;&#26032; &#8594; UI &#26356;&#26032;&#12290;</p></li></ul><div><hr></div><h3><strong>&#25991;&#20214;&#23384;&#20648;&#19982; iCloud&#65306;&#20174;&#26412;&#22320;&#21040;&#20113;&#31471;&#30340;&#23436;&#25972;&#35748;&#30693;</strong></h3><p>&#22312; iOS / macOS &#24320;&#21457;&#21644;&#20351;&#29992;&#20013;&#65292;&#25991;&#20214;&#23384;&#20648;&#24448;&#24448;&#34987;&#24403;&#20316;&#8220;&#22522;&#30784;&#33021;&#21147;&#8221;&#65292;&#20294;&#23427;&#23454;&#38469;&#19978;&#30452;&#25509;&#20915;&#23450;&#20102;&#25968;&#25454;&#30340;&#29983;&#21629;&#21608;&#26399;&#19982;&#31995;&#32479;&#34892;&#20026;&#12290;</p><p>&#22312; <a href="https://l.fatbobman.com/w0131-06a">Working with files and directories in iOS</a> &#19968;&#25991;&#20013;&#65292;<a href="https://x.com/tanaschita">Natascha Fadeeva</a> &#31995;&#32479;&#26803;&#29702;&#20102; App Sandbox &#30340;&#32467;&#26500;&#65292;&#20197;&#21450; <code>Documents</code>&#12289;<code>Library</code>&#12289;<code>Caches</code> &#31561;&#30446;&#24405;&#30340;&#32844;&#36131;&#21010;&#20998;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#24314;&#31435;&#8220;&#20160;&#20040;&#25968;&#25454;&#35813;&#25918;&#22312;&#21738;&#37324;&#8221;&#30340;&#22522;&#26412;&#35748;&#30693;&#65292;&#24182;&#35828;&#26126;&#22914;&#20309;&#36991;&#20813;&#26080;&#20851;&#25991;&#20214;&#34987; iCloud &#22791;&#20221;&#12290;</p><p>&#32780; <a href="https://x.com/howardnoakley">Howard Oakley</a> &#25776;&#20889;&#30340; <a href="https://l.fatbobman.com/w0131-06b">Understanding and Testing iCloud</a> &#21017;&#20174;&#31995;&#32479;&#23618;&#38754;&#25581;&#31034;&#20102;&#36825;&#20123;&#25968;&#25454;&#30340;&#8220;&#21518;&#32493;&#21629;&#36816;&#8221;&#12290;iCloud &#24182;&#38750;&#21333;&#19968;&#26381;&#21153;&#65292;&#32780;&#26159;&#30001; CloudKit&#12289;iCloud Drive&#12289;&#31995;&#32479;&#26356;&#26032;&#31561;&#22810;&#20010;&#23376;&#31995;&#32479;&#32452;&#25104;&#65292;&#19981;&#21516;&#25968;&#25454;&#31867;&#22411;&#23545;&#24212;&#19981;&#21516;&#30340;&#21516;&#27493;&#19982;&#22791;&#20221;&#36335;&#24452;&#12290;</p><blockquote><p>&#25991;&#20214;&#30340;&#23384;&#20648;&#20301;&#32622;&#65292;&#24182;&#19981;&#20165;&#20165;&#26159;&#32452;&#32455;&#38382;&#39064;&#65292;&#26356;&#26159;&#22312;&#23450;&#20041;&#23427;&#26159;&#21542;&#20250;&#34987;&#22791;&#20221;&#12289;&#21516;&#27493;&#65292;&#20197;&#21450;&#22312;&#35774;&#22791;&#20043;&#38388;&#22914;&#20309;&#27969;&#36716;&#12290;</p></blockquote><p>&#22240;&#27492;&#65292;iCloud &#38382;&#39064;&#24448;&#24448;&#19981;&#26159;&#8220;&#26159;&#21542;&#24320;&#21551;&#21516;&#27493;&#8221;&#36825;&#20040;&#31616;&#21333;&#65292;&#32780;&#26159;&#28041;&#21450;&#23458;&#25143;&#31471;&#12289;&#32593;&#32476;&#12289;&#32531;&#23384;&#20197;&#21450;&#26381;&#21153;&#31471;&#38480;&#27969;&#31561;&#22810;&#20010;&#29615;&#33410;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0131-07">Bad Dock: &#35753;&#20320;&#30340; Dock &#22270;&#26631;&#21160;&#36215;&#26469;</a></strong></h3><p>&#36825;&#26159;&#19968;&#20010;&#8220;&#31163;&#35889;&#20294;&#20005;&#32899;&#8221;&#30340; macOS &#23454;&#39564;&#39033;&#30446;&#12290;<a href="https://ericmartz.com/">Eric Martz</a> &#21033;&#29992;&#20844;&#24320;&#30340; <code>NSDockTile</code> / <code>NSDockTilePlugin</code> API&#65292;&#32469;&#36807; Big Sur &#20043;&#21518; Dock &#22270;&#26631;&#30340; squircle &#38480;&#21046;&#65292;&#23558;&#35270;&#39057;&#27969;&#30452;&#25509;&#28210;&#26579;&#36827; Dock &#22270;&#26631;&#12290;&#23454;&#29616;&#24605;&#36335;&#24182;&#19981;&#22797;&#26434;&#65292;&#20294;&#38750;&#24120;&#23436;&#25972;&#65306;&#20351;&#29992; <code>AVAssetReader</code> &#35299;&#30721;&#35270;&#39057;&#12289;&#20027;&#21160;&#38477;&#24103;&#33267;&#32422; 12fps&#12289;&#36890;&#36807; ring buffer &#25511;&#21046;&#20869;&#23384;&#21344;&#29992;&#65292;&#26368;&#32456;&#23558;&#19968;&#20010;&#8220;&#25972;&#27963;&#24819;&#27861;&#8221;&#25171;&#30952;&#25104;&#20102;&#32467;&#26500;&#28165;&#26224;&#30340;&#25216;&#26415;&#39564;&#35777;&#12290;</p><blockquote><p>&#36825;&#31867;&#39033;&#30446;&#30340;&#20215;&#20540;&#19981;&#22312;&#21151;&#33021;&#26412;&#36523;&#65292;&#32780;&#22312;&#20110;&#23637;&#31034;&#65306;&#31995;&#32479; API &#30340;&#36793;&#30028;&#65292;&#24448;&#24448;&#27604;&#25991;&#26723;&#20889;&#24471;&#26356;&#36828;&#12290;</p></blockquote><p>&#34917;&#20805;&#35828;&#26126;&#65306;&#35813;&#39033;&#30446;&#23454;&#29616;&#30340;&#26159;<strong>&#36816;&#34892;&#26102;&#21160;&#24577; Dock &#22270;&#26631;</strong>&#65288;&#24212;&#29992;&#36816;&#34892;&#26102;&#25345;&#32493;&#32472;&#21046;&#65289;&#65307;&#24212;&#29992;&#36864;&#20986;&#21518;&#65292;&#20165;&#33021;&#36890;&#36807; <code>NSDockTilePlugin</code> &#20445;&#30041;&#38745;&#24577;&#33258;&#23450;&#20041;&#22270;&#26631;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #130]]></title><description><![CDATA[Apple's Rare Concession: When Critical Vulnerabilities Meet the "Update Refusal" Wave]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-130</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-130</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 06 Apr 2026 12:03:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!zIqb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zIqb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zIqb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zIqb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:35916,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/193306465?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zIqb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!zIqb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd416ea2f-3a44-48a6-b259-6fec7a0a2484_1920x1080.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@rmrdnl?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Daniel Romero</a> on <a href="https://unsplash.com/photos/a-person-is-holding-an-iphone-showcasing-apps--piUPY2-44A?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Apple&#8217;s Rare Concession: When Critical Vulnerabilities Meet the &#8220;Update Refusal&#8221; Wave</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-130/">Read on web &#8594;</a></p><p>Most iOS users have recently encountered news about two serious security threats: Coruna and DarkSword. Both exploit chains rely on watering hole attacks &#8212; no user interaction required. Simply visiting a legitimate website embedded with a malicious iframe, or loading a compromised advertisement in Safari, is enough to trigger the full attack chain. Once data is exfiltrated, the malware cleans up its own traces automatically. Because the vulnerabilities exploited span the vast majority of iOS versions from iOS 13 through iOS 18.7, hundreds of millions of devices have been affected to date.</p><p>Coruna primarily targets devices running iOS 13 through iOS 17. Apple has pushed multiple security updates to these systems over the past several months. DarkSword, meanwhile, targets iOS 18.4 through 18.7 &#8212; devices that are all perfectly capable of running iOS 26, yet for various reasons, a significant number of iOS 18 users have chosen to stay put.</p><p>For a long time, iOS users were notably eager to update &#8212; one of the defining characteristics of the Apple ecosystem. That changed last year. The sweeping visual overhaul introduced by Liquid Glass prompted an unprecedented wave of deliberate refusals to upgrade to iOS 26, something Apple had never seen at this scale before. Compounding the problem, Apple introduced a mandatory age verification system in iOS 26.4 for UK users, in compliance with the Online Safety Act. The verification requirements proved strict enough that many adults found themselves forcibly locked into a &#8220;child mode,&#8221; fueling a separate wave of UK users choosing to remain on iOS 18 or iOS 26.3. In both cases, the decision to avoid updating meant forgoing all subsequent security patches &#8212; leaving devices increasingly exposed.</p><p>Faced with this situation, Apple came under significant public pressure and reputational risk. The turning point came in late March, when DarkSword&#8217;s complete exploit code was leaked to GitHub, effectively democratizing what had been a nation-state-level hacking tool and forcing Apple&#8217;s hand. Apple ultimately took the rare step of releasing a dedicated security patch for iOS 18 &#8212; iOS 18.7.7 &#8212; backporting the same protections already present in iOS 26 to the older system. With that, Apple completed its official security response to this wave of critical vulnerabilities.</p><p>Both Apple and developers across the ecosystem generally want users to stay current with system updates &#8212; it reduces the burden of maintaining compatibility across multiple versions and lets users benefit from new APIs sooner. The reality, though, is that a portion of users will always choose to lock their devices to a particular version, whether for performance, battery life, habit, or privacy reasons.</p><p>This episode may leave two lasting marks. On one side, Apple &#8212; under pressure &#8212; broke from a long-held update policy and made a concession to users who had deliberately chosen to stay on older software. On the other, the widespread attention the attacks received may nudge more users to reconsider the &#8220;update only when necessary&#8221; mindset and return to a more proactive stance toward system updates. That shift in both directions might just be the unexpected upside of an otherwise alarming security event.</p><p><a href="https://fatbobman.com/en/weekly/issue-129/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-01">Animatable in SwiftUI Explained - Complete Guide with Examples &amp; Deep Dive</a></strong></h3><p>There is no shortage of articles exploring SwiftUI&#8217;s animation system, yet this piece by <a href="https://x.com/sagarunagar_">Sagar Unagar</a> offers a particularly insightful perspective. Rather than starting from implicit or explicit animations, it builds a systematic understanding around the <code>Animatable</code> protocol: from the role of <code>animatableData</code>, to how <code>AnimatablePair</code> carries multiple interpolated values, and finally to enabling more complex data structures to participate in animations via custom <code>VectorArithmetic</code>.</p><p>The most valuable takeaway is its core viewpoint: SwiftUI is not animating views directly&#8212;it is animating data.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-02">Localization in Swift Packages</a></strong></h3><p>Xcode can automatically generate type-safe Swift symbols for <code>.xcstrings</code> files, but these symbols are only visible within the module that owns the resources. Once localization is extracted into a standalone <code>Localization</code> package, other feature modules lose the benefit of compile-time checks.</p><p><a href="https://bsky.app/profile/khanwinter.com">Khan Winter</a> proposes a straightforward solution: use a bash script to parse the JSON structure of <code>.xcstrings</code> and generate a <code>public extension LocalizedStringResource</code>, allowing all modules to access keys via <code>.l10n.helloWorld</code>.</p><p>One particularly noteworthy detail is the use of <code>@dynamicMemberLookup</code> in Debug builds&#8212;missing keys log warnings instead of crashing, while Release builds retain full compile-time validation. Compared to approaches based on Swift executables, this solution is lightweight and easy to adopt&#8212;just copy the script.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-03">SwiftUI Coordinator Pattern: Navigation Without NavigationLink</a></strong></h3><p>Although SwiftUI continues to evolve its state-driven navigation APIs, managing global navigation remains a persistent challenge. <a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> demonstrates a Coordinator-based approach using a five-tab music collection app as an example.</p><p>The idea is to extract navigation decisions from views: define all destinations in a <code>Route</code> enum, let a single Coordinator own navigation state and perform transitions, and have views simply declare &#8220;where to go&#8221; without caring about &#8220;how to get there.&#8221;</p><p>The article does not shy away from real-world tradeoffs, such as the opacity of <code>NavigationPath</code> and the complications of making route-carrying model objects conform to <code>Hashable</code>. For most mid-sized SwiftUI applications, this is a pragmatic and implementable approach to regaining control over navigation.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-04">Teach your AI to write Swift the Hacking with Swift way</a></strong></h3><p><a href="https://x.com/twostraws">Paul Hudson</a> and his Hacking with Swift have helped many developers get started with Swift and SwiftUI. In the age of AI, Paul is not only releasing specialized skills for Apple platform development, but also experimenting with injecting his personal coding style into AI collaboration.</p><p>In this article, he shares a highly distinctive (and characteristically humorous) <code>AGENTS.md</code> configuration. These rules go beyond technical choices&#8212;they embed Paul&#8217;s personality into the AI: prioritize showing results before explanations, favor clarity over cleverness, and even encourage a well-timed &#8220;Boom!&#8221; when code turns out particularly satisfying.</p><p>Rather than a simple system prompt, this feels more like defining a coding philosophy for AI. In a sense, it pushes code generation beyond mechanical output toward something closer to style transfer.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-05">The Principles and Practices of AI Agents</a></strong></h3><p>At the recent <a href="https://letsvision.swiftgg.team/">Let&#8217;s Vision 2026</a>, <a href="https://x.com/onevcat">Wang Wei (Onevcat)</a> delivered a talk on applying AI agents within large development teams. The focus was not on specific tools, but on how development workflows should evolve when the cost of code generation drops dramatically&#8212;and how the role of engineers should be redefined.</p><p>As a member of the LINE development team, Onevcat&#8217;s own work has already shifted in recent months. In his words, he is transitioning from a traditional iOS engineer to someone exploring how AI can support large-scale product development. This perspective gives the talk a depth that goes beyond typical tool introductions.</p><p>The talk revolves around three key questions: how to control context pollution, how to turn individual experience into reusable team-level memory and skills, and how to evolve collaboration from &#8220;humans directing multiple agents&#8221; toward more automated workflows. It includes many practical suggestions, such as keeping AGENTS.md concise, providing architectural lookup scripts, encouraging multiple harnesses (Claude Code, Codex, OpenCode) to coexist, and integrating agents into workflows via webhooks, cron jobs, pipelines, and automated validation.</p><blockquote><p>The <a href="https://github.com/onevcat/2026-let-s-vision">presentation repository</a> includes not only the Slidev source but also supporting materials such as raw research and full AI collaboration traces&#8212;well worth exploring.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-06">From Zero: The Complete Guide to Building a Native iOS App with AI</a></strong></h3><p>I often see &#8220;non-developers&#8221; on social media building products entirely with AI. Even after using AI tools for quite some time, I still find myself wondering: is this path really as effective as it seems?</p><p><a href="https://www.linkedin.com/in/zacharyzhangee/">Zachary Zhang</a> shares a full end-to-end journey of building and shipping a native iOS app (SwiftUI + Cloudflare backend) entirely with AI. What stands out most is his disciplined engineering pipeline: before generating any code, he first produces a structured PRD and HTML-based visual references. For tooling, he strongly recommends terminal-based tools like Claude Code during the &#8220;0 to 1&#8221; phase, as they provide better visibility and control when constructing a multi-file project architecture.</p><blockquote><p>You might share the same skepticism about fully AI-driven development. But as code generation becomes increasingly cheap, the true leverage of developers is shifting toward precise requirement decomposition, architectural control, and the ability to orchestrate systems in response to errors.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-07">Slots: A Macro for Improving Custom SwiftUI Component Design</a></strong></h3><p>Composing multiple views into reusable components is a common need in SwiftUI&#8212;especially for teams and library authors. However, once a component introduces multiple generic slots (title, icon, image, action, etc.), initializer combinations can quickly explode.</p><p>The Slots macro by <a href="https://mastodon.social/@kylebshr">Kyle Bashour</a> addresses this problem by generating initializer combinations automatically based on declared slot properties, eliminating the need to manually write numerous <code>init</code> overloads. For text-friendly slots, <code>@Slot(.text)</code> can also generate <code>LocalizedStringKey</code> and <code>String</code> variants automatically.</p><p>Slots is particularly well-suited for building design system components such as Card, Row, Banner, and Toolbar&#8212;where both ease of use and flexibility are required.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-08">Explore SwiftUI: A Visual Reference for Native Components and Modifiers</a></strong></h3><p>Although Apple&#8217;s documentation has improved over the years, SwiftUI&#8212;being declarative and visually driven&#8212;still lacks intuitive side-by-side mappings between code and UI results, especially across platforms like iOS, macOS, and visionOS.</p><p>As a result, developers often resort to complex third-party libraries or verbose custom views for UI details that SwiftUI might already support natively.</p><p><a href="https://x.com/Typ0genius">Florian</a> created Explore SwiftUI as a &#8220;visual dictionary&#8221; to address this gap. It focuses entirely on native components, with no third-party abstractions. Code examples are stripped of unrelated logic and paired with high-quality previews&#8212;allowing developers to simply copy, paste, and run.</p><h2><strong>Book</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-09">SwiftUI Architecture: Patterns and Practices for Building Scalable Applications</a></strong></h3><p>This is a recently published book by <a href="https://x.com/azamsharp">Mohammad Azam</a>. It is not an introductory guide to <code>VStack</code> or animations, but a deep dive into SwiftUI architecture, data flow, and modern engineering practices.</p><p>The book addresses real production challenges, such as building global Sheets and Toasts, designing decoupled multi-tab routing with <code>NavigationPath</code>, and implementing elegant form validation using property wrappers. Importantly, it does not enforce a rigid architectural pattern, but instead helps you develop a true declarative mindset.</p><p>Some might wonder whether architecture-focused books still matter in the age of AI-assisted coding. As Azam puts it: AI makes code generation cheap&#8212;but precisely because of that, system design (clear boundaries and ownership of state) becomes more important than ever.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-130?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-130?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#33529;&#26524;&#30340;&#32597;&#35265;&#22949;&#21327;&#65306;&#24403;&#39640;&#21361;&#28431;&#27934;&#36935;&#19978;&#8220;&#25298;&#21319;&#8221;&#28526;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-130/">&#32593;&#39029;&#29256;</a></strong></p><p>&#23545;&#20110; iOS &#29992;&#25143;&#26469;&#35828;&#65292;&#26368;&#36817;&#25110;&#22810;&#25110;&#23569;&#37117;&#20250;&#30475;&#21040;&#19982; Coruna&#12289;DarkSword &#26377;&#20851;&#30340;&#39640;&#21361;&#28431;&#27934;&#28040;&#24687;&#12290;&#20004;&#20010;&#25915;&#20987;&#38142;&#22343;&#37319;&#29992;&#27700;&#22353;&#25915;&#20987;&#30340;&#26041;&#24335;&#65292;&#25915;&#20987;&#32773;&#26080;&#38656;&#21463;&#23475;&#32773;&#36827;&#34892;&#20219;&#20309;&#20132;&#20114;&#65292;&#20165;&#38656;&#35775;&#38382;&#19968;&#20010;&#34987;&#26893;&#20837;&#24694;&#24847; iframe &#30340;&#21512;&#27861;&#32593;&#31449;&#25110;&#21152;&#36733;&#24694;&#24847;&#24191;&#21578;&#65292;&#21363;&#21487;&#35302;&#21457;&#23436;&#25972;&#30340;&#25915;&#20987;&#38142;&#65292;&#22312;&#31363;&#21462;&#36164;&#26009;&#21518;&#33258;&#21160;&#28165;&#29702;&#25915;&#20987;&#30165;&#36857;&#12290;&#30001;&#20110;&#24037;&#20855;&#38142;&#21033;&#29992;&#30340;&#28431;&#27934;&#23384;&#22312;&#20110; iOS 13 &#33267; 18.7 &#30340;&#32477;&#22823;&#22810;&#25968;&#29256;&#26412;&#20013;&#65292;&#25130;&#27490;&#30446;&#21069;&#65292;&#24050;&#26377;&#19978;&#20159;&#29992;&#25143;&#21463;&#21040;&#24433;&#21709;&#12290;</p><p>Coruna &#20027;&#35201;&#38024;&#23545; iOS 13 &#33267; iOS 17 &#30340;&#35774;&#22791;&#65292;&#22312;&#36807;&#21435;&#20960;&#20010;&#26376;&#38388;&#65292;&#33529;&#26524;&#24050;&#20026;&#36825;&#20123;&#31995;&#32479;&#25512;&#36865;&#20102;&#22810;&#27425;&#23433;&#20840;&#26356;&#26032;&#12290;DarkSword &#21017;&#20027;&#35201;&#38024;&#23545; iOS 18.4 &#33267; 18.7 &#30340;&#35774;&#22791;&#12290;&#23613;&#31649;&#36825;&#37096;&#20998;&#35774;&#22791;&#22343;&#20855;&#22791;&#21319;&#32423;&#33267; iOS 26 &#30340;&#30828;&#20214;&#26465;&#20214;&#65292;&#20294;&#30001;&#20110;&#31181;&#31181;&#21407;&#22240;&#65292;&#20173;&#26377;&#19981;&#23569; iOS 18 &#29992;&#25143;&#36873;&#25321;&#25353;&#20853;&#19981;&#21160;&#12290;</p><p>&#22312;&#24456;&#38271;&#19968;&#27573;&#26102;&#38388;&#37324;&#65292;&#33529;&#26524;&#29992;&#25143;&#23545;&#20110;&#31995;&#32479;&#26356;&#26032;&#30340;&#24577;&#24230;&#37117;&#30456;&#24403;&#31215;&#26497;&#65292;&#36825;&#20063;&#26159;&#33529;&#26524;&#29983;&#24577;&#30340;&#19968;&#22823;&#29305;&#33394;&#12290;&#20294;&#36825;&#19968;&#36235;&#21183;&#22312;&#21435;&#24180;&#20986;&#29616;&#20102;&#21464;&#21270;&#8212;&#8212;Liquid Glass &#24102;&#26469;&#30340;&#24040;&#22823;&#35270;&#35273;&#20914;&#20987;&#65292;&#35753;&#33529;&#26524;&#29992;&#25143;&#20013;&#31532;&#19968;&#27425;&#20986;&#29616;&#20102;&#30456;&#24403;&#27604;&#20363;&#20027;&#21160;&#25298;&#32477;&#21319;&#32423;&#21040; iOS 26 &#30340;&#29616;&#35937;&#12290;&#19982;&#27492;&#21516;&#26102;&#65292;&#20026;&#36981;&#23432;&#33521;&#22269;&#12298;&#32593;&#32476;&#23433;&#20840;&#27861;&#12299;&#65288;Online Safety Act&#65289;&#30340;&#35201;&#27714;&#65292;&#33529;&#26524;&#22312; iOS 26.4 &#20013;&#20026;&#33521;&#22269;&#29992;&#25143;&#24341;&#20837;&#20102;&#24378;&#21046;&#24180;&#40836;&#39564;&#35777;&#26426;&#21046;&#65292;&#30001;&#20110;&#39564;&#35777;&#26465;&#20214;&#20005;&#33499;&#65292;&#19981;&#23569;&#25104;&#24180;&#29992;&#25143;&#29978;&#33267;&#34987;&#31995;&#32479;&#24378;&#34892;&#38145;&#20837;&#8216;&#20799;&#31461;&#27169;&#24335;&#8217;&#65292;&#36827;&#19968;&#27493;&#25512;&#21160;&#20102;&#33521;&#22269;&#29992;&#25143;&#20572;&#30041;&#22312; iOS 18 &#25110; iOS 26.3 &#30340;&#39118;&#28526;&#12290;&#32780;&#25298;&#32477;&#23433;&#35013;&#26032;&#29256;&#26412;&#65292;&#24847;&#21619;&#30528;&#36825;&#37096;&#20998;&#29992;&#25143;&#21516;&#26102;&#25918;&#24323;&#20102;&#21518;&#32493;&#25152;&#26377;&#23433;&#20840;&#34917;&#19969;&#65292;&#35753;&#35774;&#22791;&#36827;&#19968;&#27493;&#26292;&#38706;&#22312;&#28508;&#22312;&#39118;&#38505;&#20043;&#19979;&#12290;</p><p>&#38754;&#23545;&#36825;&#19968;&#23616;&#38754;&#65292;&#33529;&#26524;&#25215;&#21463;&#20102;&#26126;&#26174;&#30340;&#33286;&#35770;&#21387;&#21147;&#19982;&#21697;&#29260;&#39118;&#38505;&#12290;&#29305;&#21035;&#26159;&#22312; 3 &#26376;&#19979;&#26092;&#65292;DarkSword &#30340;&#23436;&#25972;&#25915;&#20987;&#20195;&#30721;&#34987;&#27844;&#38706;&#21040;&#20102; GitHub &#19978;&#65292;&#35753;&#36825;&#19968;&#22269;&#23478;&#32423;&#40657;&#23458;&#24037;&#20855;&#30636;&#38388;&#24179;&#27665;&#21270;&#65292;&#30452;&#25509;&#36843;&#20351;&#33529;&#26524;&#24517;&#39035;&#37319;&#21462;&#32039;&#24613;&#34892;&#21160;&#12290;&#26368;&#32456;&#65292;&#33529;&#26524;&#32597;&#35265;&#22320;&#20026; iOS 18 &#21333;&#29420;&#25512;&#20986;&#20102;&#23433;&#20840;&#34917;&#19969; iOS 18.7.7&#65292;&#23558;&#21407;&#26412;&#20165;&#29992;&#20110; iOS 26 &#30340;&#38450;&#25252;&#26426;&#21046;&#22238;&#31227;&#26893;&#21040;&#26087;&#31995;&#32479;&#12290;&#33267;&#27492;&#65292;&#33529;&#26524;&#23436;&#25104;&#20102;&#38024;&#23545;&#26412;&#27425;&#39640;&#21361;&#28431;&#27934;&#30340;&#20840;&#37096;&#23448;&#26041;&#23433;&#20840;&#21709;&#24212;&#12290;</p><p>&#26080;&#35770;&#26159;&#33529;&#26524;&#36824;&#26159;&#29983;&#24577;&#20013;&#30340;&#24320;&#21457;&#32773;&#65292;&#22823;&#22810;&#24076;&#26395;&#29992;&#25143;&#33021;&#31215;&#26497;&#36319;&#36827;&#31995;&#32479;&#26356;&#26032;&#8212;&#8212;&#26082;&#33021;&#20943;&#23569;&#22810;&#29256;&#26412;&#36866;&#37197;&#30340;&#32500;&#25252;&#36127;&#25285;&#65292;&#20063;&#33021;&#35753;&#29992;&#25143;&#23613;&#24555;&#20139;&#21463;&#21040;&#26032; API &#24102;&#26469;&#30340;&#20415;&#21033;&#12290;&#20294;&#29616;&#23454;&#26159;&#65292;&#22987;&#32456;&#26377;&#19968;&#37096;&#20998;&#29992;&#25143;&#20986;&#20110;&#24615;&#33021;&#12289;&#32493;&#33322;&#12289;&#20351;&#29992;&#20064;&#24815;&#20035;&#33267;&#38544;&#31169;&#31561;&#26041;&#38754;&#30340;&#32771;&#37327;&#65292;&#26377;&#24847;&#23558;&#35774;&#22791;&#38145;&#23450;&#22312;&#26576;&#20010;&#29256;&#26412;&#12290;</p><p>&#26412;&#27425;&#20107;&#20214;&#25110;&#35768;&#20250;&#24102;&#26469;&#20004;&#20010;&#26041;&#21521;&#19978;&#30340;&#21464;&#21270;&#65306;&#33529;&#26524;&#22312;&#21387;&#21147;&#19979;&#35843;&#25972;&#20102;&#38271;&#26399;&#22362;&#23432;&#30340;&#26356;&#26032;&#31574;&#30053;&#65292;&#20026;&#21051;&#24847;&#30041;&#23432;&#26087;&#31995;&#32479;&#30340;&#29992;&#25143;&#20570;&#20986;&#20102;&#22949;&#21327;&#65307;&#32780;&#20107;&#20214;&#26412;&#36523;&#30340;&#24191;&#27867;&#20256;&#25773;&#65292;&#20063;&#21487;&#33021;&#20419;&#20351;&#26356;&#22810;&#29992;&#25143;&#20174;&#23433;&#20840;&#35282;&#24230;&#37325;&#26032;&#23457;&#35270;&#8220;&#33021;&#19981;&#26356;&#26032;&#23601;&#19981;&#26356;&#26032;&#8221;&#30340;&#24815;&#24615;&#65292;&#22238;&#21040;&#31215;&#26497;&#26356;&#26032;&#30340;&#36712;&#36947;&#12290;&#36825;&#31181;&#21452;&#21521;&#30340;&#25913;&#21464;&#65292;&#25110;&#35768;&#27491;&#26159;&#36825;&#22330;&#39118;&#27874;&#24847;&#26009;&#20043;&#22806;&#30340;&#25910;&#33719;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-129/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-01">&#36890;&#36807; Animatable &#28145;&#20837; SwiftUI &#21160;&#30011; (Animatable in SwiftUI Explained - Complete Guide with Examples &amp; Deep Dive)</a></strong></h3><p>&#32593;&#32476;&#19978;&#24182;&#19981;&#32570;&#23569;&#25506;&#35752; SwiftUI &#21160;&#30011;&#26426;&#21046;&#30340;&#25991;&#31456;&#65292;&#20294; <a href="https://x.com/sagarunagar_">Sagar Unagar</a>&#65532;&#30340;&#36825;&#31687;&#20173;&#28982;&#25552;&#20379;&#20102;&#19968;&#20010;&#39047;&#20855;&#21551;&#21457;&#24615;&#30340;&#20999;&#20837;&#28857;&#12290;&#20182;&#27809;&#26377;&#20174;&#38544;&#24335;&#25110;&#26174;&#24335;&#21160;&#30011;&#20837;&#25163;&#65292;&#32780;&#26159;&#22260;&#32469; Animatable &#21327;&#35758;&#20570;&#20102;&#19968;&#27425;&#31995;&#32479;&#26803;&#29702;&#65306;&#20174; animatableData &#30340;&#20316;&#29992;&#65292;&#21040; AnimatablePair &#22914;&#20309;&#25215;&#36733;&#22810;&#20010;&#25554;&#20540;&#21442;&#25968;&#65292;&#20877;&#21040;&#36890;&#36807;&#33258;&#23450;&#20041; VectorArithmetic &#35753;&#26356;&#22797;&#26434;&#30340;&#25968;&#25454;&#32467;&#26500;&#21442;&#19982;&#21160;&#30011;&#12290;&#25991;&#31456;&#26368;&#20540;&#24471;&#27880;&#24847;&#30340;&#19968;&#28857;&#22312;&#20110;&#20854;&#26680;&#24515;&#35270;&#35282;&#65306;SwiftUI &#23454;&#38469;&#19978;&#26159;&#22312;&#8220;&#21160;&#30011;&#25968;&#25454;&#8221;&#65292;&#32780;&#38750;&#30452;&#25509;&#23545;&#35270;&#22270;&#36827;&#34892;&#21160;&#30011;&#22788;&#29702;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-02">&#22312; Swift Package &#20013;&#20849;&#20139;&#26412;&#22320;&#21270;&#36164;&#28304; (Localization in Swift Packages)</a></strong></h3><p>Xcode &#33021;&#20026; <code>.xcstrings</code> &#25991;&#20214;&#33258;&#21160;&#29983;&#25104;&#31867;&#22411;&#23433;&#20840;&#30340; Swift &#31526;&#21495;&#65292;&#20294;&#36825;&#20123;&#31526;&#21495;&#20165;&#22312;&#36164;&#28304;&#25152;&#22312;&#30340; module &#20869;&#21487;&#35265;&#8212;&#8212;&#19968;&#26086;&#23558;&#26412;&#22320;&#21270;&#36164;&#28304;&#25277;&#31163;&#20026;&#29420;&#31435;&#30340; <code>Localization</code> &#21253;&#65292;&#20854;&#20182; feature &#21253;&#20415;&#26080;&#27861;&#20139;&#21463;&#32534;&#35793;&#26399;&#26816;&#26597;&#30340;&#20248;&#21183;&#12290;<a href="https://bsky.app/profile/khanwinter.com">Khan Winter</a> &#30340;&#35299;&#20915;&#26041;&#26696;&#30456;&#24403;&#30452;&#25509;&#65306;&#36890;&#36807;&#19968;&#20010; bash &#33050;&#26412;&#35299;&#26512; <code>.xcstrings</code> &#30340; JSON &#32467;&#26500;&#65292;&#29983;&#25104; <code>public extension LocalizedStringResource</code> &#25193;&#23637;&#65292;&#20351;&#25152;&#26377;&#27169;&#22359;&#37117;&#33021;&#20197; <code>.l10n.helloWorld</code> &#30340;&#24418;&#24335;&#35775;&#38382;&#32763;&#35793;&#38190;&#12290;</p><p>&#20854;&#20013;&#19968;&#20010;&#39047;&#20855;&#21442;&#32771;&#20215;&#20540;&#30340;&#32454;&#33410;&#26159; Debug &#27169;&#24335;&#19979;&#30340; <code>@dynamicMemberLookup</code> &#35774;&#35745;&#8212;&#8212;&#35775;&#38382;&#19981;&#23384;&#22312;&#30340;&#38190;&#26102;&#20165;&#35760;&#24405;&#26085;&#24535;&#32780;&#19981;&#23849;&#28291;&#65292;&#32780;&#22312; Release &#26500;&#24314;&#20013;&#20173;&#20445;&#30041;&#23436;&#25972;&#30340;&#32534;&#35793;&#26399;&#26657;&#39564;&#12290;&#30456;&#27604;&#22522;&#20110; Swift &#21487;&#25191;&#34892;&#25991;&#20214;&#30340;&#26041;&#26696;&#65292;&#36825;&#31181;&#23454;&#29616;&#26356;&#21152;&#36731;&#37327;&#65292;&#22797;&#21046;&#33050;&#26412;&#21363;&#21487;&#20351;&#29992;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-03">Coordinator &#20840;&#23616;&#23548;&#33322;&#27169;&#24335; (SwiftUI Coordinator Pattern: Navigation Without NavigationLink)</a></strong></h3><p>&#23613;&#31649; SwiftUI &#19968;&#30452;&#22312;&#20016;&#23500;&#22522;&#20110;&#29366;&#24577;&#39537;&#21160;&#30340;&#23548;&#33322; API&#65292;&#20294;&#31649;&#29702;&#20840;&#23616;&#23548;&#33322;&#19968;&#30452;&#26159; SwiftUI &#20013;&#30340;&#19968;&#20010;&#8220;&#30171;&#28857;&#8221;&#12290;<a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> &#20197;&#19968;&#20010;&#20116; Tab &#30340;&#38899;&#20048;&#25910;&#34255;&#24212;&#29992;&#20026;&#20363;&#65292;&#23637;&#31034;&#20102;&#22914;&#20309;&#36890;&#36807; Coordinator &#27169;&#24335;&#23558;&#23548;&#33322;&#20915;&#31574;&#20174; View &#20013;&#25277;&#31163;&#65306;&#29992;&#19968;&#20010; Route &#26522;&#20030;&#32479;&#19968;&#25551;&#36848;&#25152;&#26377;&#30446;&#30340;&#22320;&#65292;&#30001;&#21333;&#19968;&#30340; Coordinator &#23545;&#35937;&#25345;&#26377;&#23548;&#33322;&#29366;&#24577;&#24182;&#25191;&#34892;&#36339;&#36716;&#65292;View &#21482;&#38656;&#22768;&#26126;&#8220;&#21435;&#21738;&#8221;&#32780;&#26080;&#38656;&#20851;&#24515;&#8220;&#24590;&#20040;&#21435;&#8221;&#12290;&#25991;&#31456;&#27809;&#26377;&#22238;&#36991; NavigationPath &#19981;&#36879;&#26126;&#12289;&#36335;&#30001;&#25658;&#24102;&#27169;&#22411;&#23545;&#35937;&#23548;&#33268;&#30340; Hashable &#22256;&#22659;&#31561;&#23454;&#38469;&#38382;&#39064;&#12290;&#23545;&#20110;&#22823;&#22810;&#25968;&#20013;&#31561;&#35268;&#27169;&#30340; SwiftUI &#24212;&#29992;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20010;&#21153;&#23454;&#19988;&#26131;&#20110;&#33853;&#22320;&#30340;&#23548;&#33322;&#27835;&#29702;&#26041;&#26696;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-04">&#25226; Hacking with Swift &#30340;&#32534;&#31243;&#39118;&#26684;&#20889;&#36827; AI (Teach your AI to write Swift the Hacking with Swift way)</a></strong></h3><p><a href="https://x.com/twostraws">Paul Hudson</a> &#21644;&#20182;&#30340; Hacking with Swift &#35753;&#24456;&#22810;&#24320;&#21457;&#32773;&#36208;&#19978;&#20102; Swift &#19982; SwiftUI &#30340;&#23398;&#20064;&#20043;&#36335;&#12290;&#22312; AI &#26102;&#20195;&#65292;Paul &#19981;&#20165;&#25512;&#20986;&#20102;&#38754;&#21521;&#33529;&#26524;&#24320;&#21457;&#29983;&#24577;&#30340;&#21508;&#31867;&#19987;&#19994; Skill&#65292;&#20063;&#24320;&#22987;&#23581;&#35797;&#22312;&#19982; AI &#30340;&#21327;&#20316;&#20013;&#27880;&#20837;&#26356;&#20855;&#20010;&#20154;&#29305;&#36136;&#30340;&#32534;&#31243;&#39118;&#26684;&#12290;</p><p>&#22312;&#26412;&#25991;&#20013;&#65292;&#20182;&#20998;&#20139;&#20102;&#19968;&#20221;&#26497;&#20855;&#36776;&#35782;&#24230;&#65288;&#19988;&#20805;&#28385;&#20182;&#26631;&#24535;&#24615;&#24189;&#40664;&#65289;&#30340; <code>AGENTS.md</code> &#37197;&#32622;&#12290;&#36825;&#22871;&#35268;&#21017;&#19981;&#20165;&#32422;&#26463;&#20102; AI &#30340;&#25216;&#26415;&#36873;&#22411;&#65292;&#36824;&#20026; AI &#27880;&#20837;&#20102; Paul &#30340;&#28789;&#39746;&#65306;&#24378;&#35843;&#20808;&#23637;&#31034;&#32467;&#26524;&#20877;&#35299;&#37322;&#21407;&#29702;&#12289;&#20559;&#22909;&#28165;&#26224;&#32780;&#38750;&#28843;&#25216;&#12289;&#29978;&#33267;&#21253;&#25324;&#22312;&#20195;&#30721;&#20889;&#24471;&#28418;&#20142;&#26102;&#36866;&#26102;&#22320;&#21898;&#20986;&#19968;&#21477; &#8220;Boom!&#8221;&#12290;&#19982;&#20854;&#35828;&#36825;&#26159;&#19968;&#20221;&#29992;&#20110; AI &#30340;&#8220;&#31995;&#32479;&#25552;&#31034;&#35789;&#8221;&#65292;&#19981;&#22914;&#35828;&#26159;&#22312;&#20026; AI &#23450;&#20041;&#19968;&#31181;&#32534;&#30721;&#21746;&#23398;&#8212;&#8212;&#26576;&#31181;&#31243;&#24230;&#19978;&#65292;&#36825;&#31181;&#26041;&#24335;&#27491;&#22312;&#23558;&#20919;&#20912;&#20912;&#30340;&#8220;&#20195;&#30721;&#29983;&#25104;&#8221;&#25512;&#21521;&#24102;&#26377;&#20154;&#24773;&#21619;&#30340;&#8220;&#39118;&#26684;&#36801;&#31227;&#8221;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-05">AI Agent &#30340;&#36947;&#19982;&#26415;</a></strong></h3><p>&#22312;&#21018;&#36807;&#21435;&#30340; <a href="https://letsvision.swiftgg.team/">Let&#8217;s Vision 2026</a> &#20013;&#65292;<a href="https://x.com/onevcat">&#29579;&#24013;&#65288;Onevcat&#65289;</a> &#21457;&#34920;&#20102;&#20851;&#20110;&#22312;&#22823;&#22411;&#24320;&#21457;&#22242;&#38431;&#20013;&#24212;&#29992; AI Agent &#30340;&#28436;&#35762;&#12290;&#25972;&#22330;&#20998;&#20139;&#35752;&#35770;&#30340;&#37325;&#28857;&#65292;&#24182;&#19981;&#26159;&#26576;&#20010;&#20855;&#20307;&#24037;&#20855;&#26377;&#22810;&#24378;&#65292;&#32780;&#26159;&#24403;&#20195;&#30721;&#23454;&#29616;&#25104;&#26412;&#34987;&#36805;&#36895;&#21387;&#20302;&#21518;&#65292;&#22242;&#38431;&#35813;&#22914;&#20309;&#37325;&#26032;&#32452;&#32455;&#24320;&#21457;&#27969;&#31243;&#65292;&#20197;&#21450;&#24037;&#31243;&#24072;&#30340;&#20215;&#20540;&#35813;&#22914;&#20309;&#37325;&#26032;&#23450;&#20301;&#12290;</p><p>&#20316;&#20026; LINE &#24212;&#29992;&#24320;&#21457;&#22242;&#38431;&#30340;&#19968;&#21592;&#65292;Onevcat &#22312;&#36807;&#21435;&#20960;&#20010;&#26376;&#20013;&#30340;&#24037;&#20316;&#37325;&#24515;&#20063;&#24050;&#26126;&#26174;&#21457;&#29983;&#21464;&#21270;&#12290;&#29992;&#20182;&#33258;&#24049;&#30340;&#35805;&#35828;&#65292;&#20182;&#27491;&#22312;&#36880;&#27493;&#20174;&#20256;&#32479;&#24847;&#20041;&#19978;&#30340; iOS &#24037;&#31243;&#24072;&#65292;&#36716;&#21521;&#25506;&#32034;&#22914;&#20309;&#23558; AI &#24212;&#29992;&#20110;&#26381;&#21153;&#22823;&#22411;&#20135;&#21697;&#30740;&#21457;&#22242;&#38431;&#30340;&#23454;&#36341;&#32773;&#12290;&#36825;&#31181;&#35282;&#33394;&#19978;&#30340;&#21464;&#21270;&#65292;&#20063;&#35753;&#36825;&#22330;&#20998;&#20139;&#27604;&#19968;&#33324;&#30340;&#24037;&#20855;&#20171;&#32461;&#26356;&#26377;&#35828;&#26381;&#21147;&#12290;</p><p>&#28436;&#35762;&#22260;&#32469;&#19977;&#20010;&#20851;&#38190;&#38382;&#39064;&#23637;&#24320;&#65306;&#22914;&#20309;&#25511;&#21046;&#19978;&#19979;&#25991;&#27745;&#26579;&#65292;&#22914;&#20309;&#25226;&#20010;&#20154;&#32463;&#39564;&#27785;&#28096;&#20026;&#22242;&#38431;&#21487;&#22797;&#29992;&#30340; memory &#19982; skill&#65292;&#20197;&#21450;&#22914;&#20309;&#35753;&#21327;&#20316;&#27169;&#24335;&#20174;&#8220;&#20154;&#25351;&#25381;&#22810;&#20010; Agent&#8221;&#36880;&#27493;&#36208;&#21521;&#26356;&#33258;&#21160;&#21270;&#30340;&#38381;&#29615;&#12290;&#37324;&#38754;&#26377;&#19981;&#23569;&#30456;&#24403;&#25509;&#22320;&#27668;&#30340;&#23454;&#36341;&#24314;&#35758;&#65292;&#20363;&#22914;&#23558; AGENTS.md &#25511;&#21046;&#22312;&#31934;&#31616;&#33539;&#22260;&#20869;&#12289;&#20026; Agent &#25552;&#20379;&#27169;&#22359;&#23450;&#20301;&#19982;&#26550;&#26500;&#36895;&#26597;&#33050;&#26412;&#12289;&#40723;&#21169; Claude Code&#12289;Codex&#12289;OpenCode &#31561;&#22810;&#31181; harness &#24182;&#23384;&#65292;&#20197;&#21450;&#36890;&#36807; webhook&#12289;cron&#12289;pipeline &#21644;&#33258;&#21160;&#39564;&#25910;&#26426;&#21046;&#35753; Agent &#30495;&#27491;&#36827;&#20837;&#22242;&#38431;&#27969;&#31243;&#12290;</p><blockquote><p><a href="https://github.com/onevcat/2026-let-s-vision">&#28436;&#35762;&#31295;&#20179;&#24211;</a> &#20013;&#19981;&#20165;&#21253;&#21547;&#23436;&#25972;&#30340; Slidev &#28304;&#30721;&#65292;&#20063;&#20445;&#30041;&#20102;&#19981;&#23569;&#28436;&#35762;&#37197;&#22871;&#26448;&#26009;&#65292;&#21253;&#25324;&#21407;&#22987;&#36164;&#26009;&#25910;&#38598;&#21644;&#19982; AI &#21327;&#20316;&#30340;&#23436;&#25972; trace&#65292;&#20540;&#24471;&#19968;&#24182;&#38405;&#35835;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-06">&#20174;&#38646;&#24320;&#22987;&#65306;&#29992; AI &#24320;&#21457;&#19968;&#20010; iOS &#21407;&#29983; APP &#23436;&#25972;&#25351;&#21335;</a></strong></h3><p>&#25105;&#32463;&#24120;&#20250;&#22312;&#31038;&#20132;&#23186;&#20307;&#19978;&#30475;&#21040;&#19968;&#20123;&#38646;&#22522;&#30784;&#30340;&#8220;&#24320;&#21457;&#32773;&#8221;&#36890;&#36807; AI &#26500;&#24314;&#20102;&#33258;&#24049;&#30340;&#20135;&#21697;&#25110;&#26381;&#21153;&#12290;&#23613;&#31649;&#25105;&#20351;&#29992; AI &#30340;&#26102;&#38388;&#20063;&#19981;&#30701;&#65292;&#20294;&#25105;&#20173;&#28982;&#27604;&#36739;&#22256;&#24785;&#65306;&#36825;&#26465;&#36335;&#24452;&#30495;&#30340;&#20687;&#22823;&#23478;&#25551;&#36848;&#30340;&#37027;&#26679;&#26377;&#25928;&#21527;&#65311;<a href="https://www.linkedin.com/in/zacharyzhangee/">Zachary Zhang</a> &#20998;&#20139;&#20102;&#20182;&#23436;&#20840;&#20511;&#21161; AI &#24037;&#20855;&#65292;&#20174;&#38646;&#26500;&#24314;&#24182;&#19978;&#26550;&#19968;&#27454;&#32431;&#21407;&#29983; iOS &#24212;&#29992;&#65288;SwiftUI + Cloudflare &#21518;&#31471;&#65289;&#30340;&#23454;&#25112;&#20840;&#36807;&#31243;&#12290;&#36825;&#31687;&#25991;&#31456;&#26368;&#35753;&#25105;&#21360;&#35937;&#28145;&#21051;&#30340;&#65292;&#26159;&#20182;&#20005;&#35880;&#30340;&#8220;&#24037;&#31243;&#21270;&#31649;&#32447;&#8221;&#65306;&#22312;&#35753; AI &#20889;&#20195;&#30721;&#21069;&#65292;&#24517;&#39035;&#20808;&#29983;&#25104;&#32467;&#26500;&#21270;&#30340; PRD &#21644; HTML &#26684;&#24335;&#30340;&#35270;&#35273;&#21442;&#32771;&#65307;&#32780;&#22312;&#24037;&#20855;&#36873;&#25321;&#19978;&#65292;&#20182;&#22312;&#39033;&#30446;&#8220;&#20174; 0 &#21040; 1&#8221;&#30340;&#20919;&#21551;&#21160;&#38454;&#27573;&#65292;&#26497;&#21147;&#25512;&#33616; Claude Code &#31561;&#32456;&#31471;&#24037;&#20855;&#65292;&#20197;&#20415;&#26356;&#22909;&#22320;&#32479;&#35272;&#20840;&#23616;&#65292;&#19968;&#27425;&#24615;&#26500;&#24314;&#20986;&#21512;&#29702;&#30340;&#22810;&#25991;&#20214;&#39033;&#30446;&#26550;&#26500;&#12290;</p><blockquote><p>&#25110;&#35768;&#20320;&#21644;&#25105;&#19968;&#26679;&#65292;&#23545;&#20110; 100% &#22522;&#20110; AI &#30340;&#24320;&#21457;&#26041;&#24335;&#20173;&#23384;&#30097;&#24785;&#12290;&#20294;&#22312;&#20195;&#30721;&#29983;&#25104;&#36234;&#26469;&#36234;&#24265;&#20215;&#30340;&#20170;&#22825;&#65292;&#24320;&#21457;&#32773;&#30340;&#26680;&#24515;&#22721;&#22418;&#65292;&#27491;&#22312;&#21152;&#36895;&#21521;&#8220;&#38656;&#27714;&#31934;&#20934;&#25286;&#35299;&#8221;&#12289;&#8220;&#31995;&#32479;&#26550;&#26500;&#25226;&#25511;&#8221;&#20197;&#21450;&#8220;&#38754;&#21521;&#25253;&#38169;&#30340;&#20840;&#23616;&#35843;&#24230;&#33021;&#21147;&#8221;&#36716;&#31227;&#12290;</p></blockquote><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-07">Slots&#65306;&#25552;&#39640;&#33258;&#23450;&#20041; SwiftUI &#32452;&#20214;&#35774;&#35745;&#25928;&#29575;&#30340;&#23439;</a></strong></h3><p>&#23558;&#22810;&#20010;&#35270;&#22270;&#32452;&#21512;&#23553;&#35013;&#25104;&#21487;&#22797;&#29992;&#32452;&#20214;&#65292;&#26159; SwiftUI &#24320;&#21457;&#20013;&#30340;&#24120;&#35265;&#38656;&#27714;&#65292;&#23545;&#22242;&#38431;&#20869;&#37096;&#24320;&#21457;&#32773;&#25110;&#31532;&#19977;&#26041;&#24211;&#20316;&#32773;&#26469;&#35828;&#26356;&#26159;&#22914;&#27492;&#12290;&#20294;&#24403;&#32452;&#20214;&#21253; title&#12289;icon&#12289;image&#12289;action &#31561;&#22810;&#20010;&#27867;&#22411; View &#25554;&#27133;&#21518;&#65292;&#21021;&#22987;&#21270;&#22120;&#30340;&#32452;&#21512;&#25968;&#37327;&#24448;&#24448;&#20250;&#36805;&#36895;&#33192;&#32960;&#12290;<a href="https://mastodon.social/@kylebshr">Kyle Bashour</a> &#21019;&#24314;&#30340; Slots &#23439;&#65292;&#27491;&#26159;&#20026;&#20102;&#35299;&#20915;&#36825;&#31867;&#22810; slot &#32452;&#20214;&#30340;&#26679;&#26495;&#20195;&#30721;&#38382;&#39064;&#12290;</p><p>&#24320;&#21457;&#32773;&#21482;&#38656;&#22768;&#26126;&#32452;&#20214;&#30340; slot &#23646;&#24615;&#65292;&#23439;&#20415;&#20250;&#25353;&#32452;&#21512;&#33258;&#21160;&#29983;&#25104;&#25152;&#38656;&#30340;&#21021;&#22987;&#21270;&#22120;&#65292;&#26080;&#38656;&#25163;&#20889;&#22823;&#37327; init &#37325;&#36733;&#12290;&#23545;&#20110;&#38656;&#35201;&#25903;&#25345;&#25991;&#26412;&#20415;&#25463;&#20889;&#27861;&#30340; slot&#65292;&#36824;&#21487;&#20197;&#36890;&#36807; <code>@Slot(.text)</code> &#33258;&#21160;&#33719;&#24471; <code>LocalizedStringKey</code> &#21644; <code>String</code> &#29256;&#26412;&#30340;&#21021;&#22987;&#21270;&#26041;&#24335;&#12290; Slots &#24456;&#36866;&#21512;&#29992;&#20110;&#26500;&#24314;&#35774;&#35745;&#31995;&#32479;&#20013;&#30340; Card&#12289;Row&#12289;Banner&#12289;Toolbar &#36825;&#31867;&#26082;&#35201;&#25903;&#25345;&#31616;&#21333;&#35843;&#29992;&#12289;&#21448;&#35201;&#20445;&#30041;&#39640;&#24230;&#23450;&#21046;&#33021;&#21147;&#30340;&#32452;&#20214;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0130-08">Explore SwiftUI&#65306;&#32431;&#21407;&#29983;&#32452;&#20214;&#19982;&#20462;&#39280;&#31526;&#30340;&#35270;&#35273;&#36895;&#26597;&#22270;&#24211;</a></strong></h3><p>&#23613;&#31649; Apple &#23448;&#26041;&#25991;&#26723;&#30340;&#36136;&#37327;&#22312;&#36880;&#24180;&#25913;&#21892;&#65292;&#20294;&#23545;&#20110;&#20197;&#22768;&#26126;&#24335;&#21644;&#35270;&#35273;&#39537;&#21160;&#20026;&#20027;&#30340; SwiftUI &#26469;&#35828;&#65292;&#23448;&#26041;&#25991;&#26723;&#20013;&#20381;&#28982;&#32570;&#20047;&#36275;&#22815;&#30452;&#35266;&#30340;&#20195;&#30721;&#19982; UI &#25928;&#26524;&#23545;&#29031;&#65292;&#23588;&#20854;&#26159;&#21516;&#19968;&#32452;&#20214;&#22312; iOS&#12289;macOS &#21644; visionOS &#31561;&#22810;&#24179;&#21488;&#19978;&#30340;&#34920;&#29616;&#24046;&#24322;&#12290;&#24456;&#22810;&#26102;&#20505;&#65292;&#24320;&#21457;&#32773;&#20026;&#20102;&#23454;&#29616;&#26576;&#20010;&#29305;&#23450;&#30340; UI &#32454;&#33410;&#65292;&#24448;&#24448;&#20250;&#21435;&#27714;&#21161;&#20110;&#22797;&#26434;&#30340;&#31532;&#19977;&#26041;&#24211;&#25110;&#25163;&#20889;&#20887;&#38271;&#30340;&#33258;&#23450;&#20041;&#35270;&#22270;&#65292;&#21364;&#24573;&#30053;&#20102; SwiftUI &#26412;&#36523;&#21487;&#33021;&#24050;&#32463;&#25552;&#20379;&#20102;&#32477;&#20339;&#30340;&#21407;&#29983;&#35299;&#20915;&#26041;&#26696;&#12290;<a href="https://x.com/Typ0genius">Florian</a> &#24314;&#31435;&#30340; Explore SwiftUI &#31449;&#28857;&#65292;&#27491;&#26159;&#19968;&#20010;&#20026;&#20102;&#35299;&#20915;&#36825;&#19968;&#30171;&#28857;&#32780;&#29983;&#30340;&#8220;&#35270;&#35273;&#36895;&#26597;&#23383;&#20856;&#8221;&#12290;&#23427;&#25682;&#24323;&#20102;&#20219;&#20309;&#31532;&#19977;&#26041;&#23553;&#35013;&#65292;&#32431;&#31929;&#20197;&#23637;&#31034; Apple &#23448;&#26041;&#20869;&#32622;&#32452;&#20214;&#30340;&#21407;&#29983;&#33021;&#21147;&#20026;&#26680;&#24515;&#12290;&#25152;&#26377;&#30340;&#20195;&#30721;&#31034;&#20363;&#37117;&#34987;&#21093;&#31163;&#20102;&#26080;&#20851;&#30340;&#19994;&#21153;&#36923;&#36753;&#65292;&#20445;&#25345;&#26497;&#31616;&#65292;&#37197;&#20197;&#39640;&#36136;&#37327;&#30340;&#35270;&#35273;&#39044;&#35272;&#65292;&#24320;&#21457;&#32773;&#21482;&#38656;&#8220;&#22797;&#21046;&#12289;&#31896;&#36148;&#12289;&#36816;&#34892;&#8221;&#21363;&#21487;&#30452;&#25509;&#39564;&#35777;&#25928;&#26524;&#12290;</p><h2><strong>&#20070;&#31821;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0130-09">SwiftUI Architecture: Patterns and Practices for Building Scalable Applications</a></strong></h3><p>&#36825;&#26159;&#19968;&#26412; <a href="https://x.com/azamsharp">Mohammad Azam</a> &#22312;&#19981;&#20037;&#21069;&#20986;&#29256;&#30340;&#26032;&#20070;&#12290;&#23427;&#19981;&#26159;&#19968;&#26412;&#25945;&#20320;&#22914;&#20309;&#20351;&#29992; <code>VStack</code> &#25110;&#32534;&#20889;&#21160;&#30011;&#30340;&#20837;&#38376;&#20070;&#65292;&#32780;&#26159;&#19968;&#26412;&#32431;&#31929;&#25506;&#35752; SwiftUI &#24212;&#29992;&#26550;&#26500;&#12289;&#25968;&#25454;&#27969;&#21644;&#29616;&#20195;&#24037;&#31243;&#21270;&#23454;&#36341;&#30340;&#36827;&#38454;&#35835;&#29289;&#12290;</p><p>&#20070;&#20013;&#25552;&#20379;&#20102;&#22823;&#37327;&#30452;&#20987;&#29983;&#20135;&#29615;&#22659;&#30171;&#28857;&#30340;&#35299;&#20915;&#26041;&#26696;&#65292;&#20363;&#22914;&#65306;&#22914;&#20309;&#26500;&#24314;&#20840;&#23616;&#30340; Sheets &#21644; Toasts&#12289;&#22914;&#20309;&#21033;&#29992; <code>NavigationPath</code> &#35774;&#35745;&#35299;&#32806;&#30340;&#22810; Tab &#32534;&#31243;&#24335;&#36335;&#30001;&#12289;&#20197;&#21450;&#22914;&#20309;&#20351;&#29992; Property Wrapper &#32534;&#20889;&#20248;&#38597;&#30340;&#34920;&#21333;&#39564;&#35777;&#12290;&#23588;&#20026;&#37325;&#35201;&#30340;&#26159;&#65292;&#20316;&#32773;&#24182;&#19981;&#26159;&#35201;&#21521;&#20320;&#28748;&#36755;&#26576;&#31181;&#27515;&#26495;&#30340;&#26550;&#26500;&#27169;&#24335;&#65292;&#32780;&#26159;&#26088;&#22312;&#24110;&#21161;&#20320;&#24314;&#31435;&#30495;&#27491;&#30340;&#22768;&#26126;&#24335;&#24515;&#26234;&#27169;&#22411;&#12290;</p><p>&#25110;&#35768;&#26377;&#20154;&#35273;&#24471;&#65292;&#22312; AI &#36741;&#21161;&#32534;&#31243;&#30427;&#34892;&#30340;&#26102;&#20195;&#65292;&#36825;&#31867;&#25506;&#35752;&#26550;&#26500;&#30340;&#20070;&#31821;&#36824;&#37325;&#35201;&#21527;&#65311;&#20511;&#29992; Mohammad Azam &#22312;&#20070;&#20013;&#30340;&#35266;&#28857;&#65306;AI &#35753;&#20195;&#30721;&#29983;&#25104;&#21464;&#24471;&#24265;&#20215;&#65292;&#20294;&#20063;&#27491;&#22240;&#22914;&#27492;&#65292;&#31995;&#32479;&#26550;&#26500;&#30340;&#35774;&#35745;&#65288;&#36793;&#30028;&#30340;&#21010;&#20998;&#21644;&#29366;&#24577;&#25152;&#26377;&#26435;&#30340;&#26126;&#30830;&#65289;&#21464;&#24471;&#27604;&#20197;&#24448;&#20219;&#20309;&#26102;&#20505;&#37117;&#26356;&#21152;&#37325;&#35201;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #129]]></title><description><![CDATA[A Wall Away, Worlds Apart]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-129</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-129</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 30 Mar 2026 12:03:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3XHm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3XHm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3XHm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 424w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 848w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 1272w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3XHm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp" width="1200" height="628" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54286,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/192584589?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3XHm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 424w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 848w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 1272w, https://substackcdn.com/image/fetch/$s_!3XHm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F325d15bb-84b2-4e4c-85fd-5c7c87f6491b_1200x628.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>A Wall Away, Worlds Apart</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-129/">Read on web &#8594;</a></p><p>The annual <a href="https://letsvision.swiftgg.team/">Let&#8217;s Vision</a> conference was held in Shanghai as scheduled, with this year&#8217;s theme being: &#8220;Born to Create, Powered by AI.&#8221; Therefore, alongside the regular sessions on Swift and spatial computing, the conference invited many developers to share their applications and insights regarding AI in their daily workflows. I benefited immensely from the speakers&#8217; introductions to their AI workflows. The AI-themed venue, originally designed to hold only 300 people, was packed inside and out with an enthusiastic crowd.</p><p>However, among the many excellent sessions, a talk prepared by <a href="https://www.linkedin.com/in/iamhands0me/">YuChe Cheng</a> titled &#8220;Let&#8217;s Create 1-liner Code in Swift&#8221; drew my attention to another room. What exactly was this topic about? Driven by curiosity, I walked in. As a developer with a LeetCode rating of 2200+, YuChe Cheng demonstrated how to use the extensive higher-order functions provided by <code>Foundation</code> and <code>Swift Algorithms</code> to transform plain, ordinary <code>for-loop</code> code into elegant, beautiful, and highly Swift-styled function chaining (1-liner code). In doing so, he achieved a brilliant balance between readability and performance.</p><p>Watching the function chaining on the slides being elegantly iterated over and over again, I felt a refreshing sense of clarity and enlightenment. For the entire 30-minute talk, I remained in a state of pure excitement&#8212;a feeling that typically only emerges after I&#8217;ve racked my brain to finally conquer a difficult problem, or when I&#8217;ve deeply grasped a new concept.</p><p>Even though it was only a wall away from the main venue, the overwhelming popularity of the AI topic meant the audience for this talk was noticeably sparse. Rather than feeling regret that so many missed out on a fantastic presentation, my real concern is this: <strong>As AI penetrates further into our industry, will that distinctive &#8220;character&#8221; developers once pursued and imbued into their code&#8212;beyond mere functionality&#8212;fade into oblivion?</strong></p><p>Developers shouldn&#8217;t only care about cold, compiled binaries. Code itself is a vessel for personal style. Just like writing an essay, beyond delivering logic and results, it carries aesthetic expression, reflecting the author&#8217;s personal taste and ingenuity.</p><p>At this year&#8217;s Let&#8217;s Vision, I felt as though we were standing at a crossroads: <strong>Should we relentlessly pursue the extreme efficiency brought by AI, or, while embracing change, can we ensure that the pride and craftsmanship belonging to developers are still preserved in the AI era?</strong></p><p><a href="https://fatbobman.com/en/weekly/issue-128/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0129-01">Swift 6.3 Released</a></strong></h3><p>Since Swift 6, the language has settled into a steady cadence of one minor release every six months. Swift 6.3 was released as expected last week. Compared to previous releases, this version does not introduce any major headline features, but instead focuses on refining the existing system: improvements in concurrency diagnostics, the introduction of the <code>@c</code> attribute to further strengthen C/C++ interoperability, and more granular control over compiler optimizations.</p><p>That said, this release still sends a clear signal: Swift is evolving from a language centered around Apple platforms into a more general-purpose language with cross-platform and system-level capabilities. The continued progress of Embedded Swift, Android support, and the unification of the SwiftPM build system all point in this direction. For most iOS developers, the short-term impact may feel limited, but in the long run, this is a foundational update paving the way for what comes next.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-02">Designing a type-driven JSON in Swift</a></strong></h3><p>When API contracts are unstable and the understanding of fields between frontend and backend frequently drifts, Swift&#8217;s strong type system can actually amplify the friction at the JSON boundary. <a href="https://www.linkedin.com/in/inekipelov/">Roman Niekipielov</a> introduces a deliberately minimal <code>JSONValue</code> type to handle such transitional data.</p><p>Compared to <code>[String: Any]</code>, it preserves clearer type structure; compared to fully defined <code>Codable</code> models, it better accommodates frequently changing contracts. This approach does not aim to replace formal models, but rather to contain uncertainty at the boundary layer.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-03">Swift Native AI Agent Development Series</a></strong></h3><p>While many developers build AI agents using Python or TypeScript, <a href="https://x.com/chris_karani">Chris Karani</a> argues that Swift&#8217;s concurrency model is naturally well-suited for agent isolation and scheduling, with its strong type system and macro capabilities adding extra safety guarantees.</p><p>Across six articles, he explores this idea from multiple angles&#8212;from a unified multi-provider LLM SDK <a href="https://github.com/christopherkarani/Conduit">Conduit</a>, to an agent runtime built on Apple Foundation Models <a href="https://github.com/christopherkarani/Colony">Colony</a>, and even Metal-accelerated context memory management. If you are considering building AI features on Apple platforms, this is one of the few comprehensive native approaches available today.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-04">Talking Liquid Glass with Apple</a></strong></h3><p><a href="https://x.com/dbolella">Danny Bolella</a> attended Apple&#8217;s Liquid Glass design workshop in New York, spending three days in close collaboration with design teams and SwiftUI engineers. The message from the event was clear: Liquid Glass is not a transitional experiment, but a long-term design direction that will become the default across future toolchains.</p><p>Apple also repeatedly emphasized the importance of hierarchy&#8212;interfaces should be built around content, with controls serving as supporting elements positioned toward the edges. Beyond that, Danny also shares practical advice and implementation insights from Apple engineers. The article offers an early look into the direction and philosophy behind this design evolution.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-05">Apple Dropped 100+ New Metrics. Your Competitors Are Already Using Them</a></strong></h3><p>Apple has rolled out one of the most significant updates to App Store Connect in recent years, introducing 100+ first-party metrics, cohort analysis by source, peer benchmarks (conversion rate and revenue per download), and subscription data export via API. <a href="https://www.linkedin.com/in/jessica-chung-197215220/">Jessica Chung</a> provides a structured overview of these changes.</p><p>Since all data now comes directly from Apple, developers can move away from third-party estimates and make decisions based on real user behavior. More importantly, this update fills a long-standing gap: you can now track user quality across channels and keywords, build a full funnel from impression to subscription and retention, and benchmark your performance against peers.</p><blockquote><p>This update is clearly beneficial for developers, but it also raises the bar for third-party App Store analytics tools, pushing them to deliver higher-value capabilities to remain competitive.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-06">Package Traits in Xcode</a></strong></h3><p>When building an SPM package, some dependencies may only be used by specific APIs. However, once the package is added, those dependencies are included regardless of whether those APIs are used. Package Traits were introduced to address this issue by allowing developers to define optional features that consumers can enable as needed, avoiding unnecessary dependencies.</p><p>Unfortunately, after its introduction, this feature was only available in community Swift toolchains. With the release of Xcode 26.4, Package Traits finally gained official support from Apple, making broader adoption more likely. <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> introduces the feature and demonstrates its usage in this article.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-07">Why your SwiftUI app feels slow even though Instruments says it&#8217;s fine?</a></strong></h3><p>When users complain about slow responsiveness, is it always a performance issue? <a href="https://www.linkedin.com/in/rafal-dubiel/">Rafa&#322; Dubiel</a> shifts the focus from actual performance to perceived performance, exploring how UI feedback and interaction timing can make apps feel faster.</p><p>Techniques such as skeleton views, delayed loading, and thoughtful animations can effectively mask waiting time. The key insight is that user experience is often less about reducing milliseconds and more about providing timely feedback. Compared to raw performance optimization, this perspective has a more direct impact on how users perceive fluidity.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-08">Adjusting line height in SwiftUI on iOS 26</a></strong></h3><p>iOS 26 introduces a new <code>lineHeight(_:)</code> modifier in SwiftUI for controlling the baseline distance between lines of text. <a href="https://x.com/natpanferova">Natalia Panferova</a> provides a detailed comparison of its configurations, including presets (<code>.loose</code>, <code>.tight</code>), proportional scaling (<code>.multiple(factor:)</code>), incremental adjustments (<code>.leading(increase:)</code>), and absolute control (<code>.exact(points:)</code>).</p><p>Unlike <code>lineSpacing(_:)</code>, which adjusts spacing between lines, <code>lineHeight(_:)</code> directly defines baseline distance, offering more consistent control. This addition further improves SwiftUI&#8217;s typography capabilities.</p><blockquote><p>Natalia Panferova, a former member of Apple&#8217;s SwiftUI core team, has recently published a new book <a href="https://books.nilcoalescing.com/the-swiftui-way">The SwiftUI Way</a>, aimed at experienced SwiftUI developers. The book focuses on production patterns, common anti-patterns, and how to work with the framework rather than against it.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0129-09">Cove: A Swift 6 Native macOS Open Source Database Client</a></strong></h3><p>Cove, developed by <a href="https://www.linkedin.com/in/emanuelemicheletti/">Emanuele Micheletti</a>, is a native macOS database client built entirely with Swift 6. It currently supports a wide range of backends including PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, Redis, ScyllaDB, Cassandra, and Elasticsearch. Built with SwiftUI and AppKit instead of Electron or web technologies, it delivers a lightweight experience aligned with macOS conventions.</p><p>What makes Cove particularly interesting is its architecture. All database capabilities are abstracted through a unified <code>DatabaseBackend</code> protocol, with no backend-specific logic in the UI layer. Whether dealing with SQL databases, key-value stores like Redis, or NoSQL systems like MongoDB and Elasticsearch, everything is normalized into a table model for rendering. Although still in an early v0.1.0 stage, it already supports querying, schema browsing, editing, SSH tunneling, and multi-tab workflows. Even if you don&#8217;t plan to use it as your daily database tool, it&#8217;s a valuable reference for Swift-based desktop app architecture.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-129?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-129?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#19968;&#22681;&#20043;&#38548;&#65292;&#19981;&#21516;&#30340;&#26102;&#31354;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-129/">&#32593;&#39029;&#29256;</a></strong></p><p>&#19968;&#24180;&#19968;&#24230;&#30340; <a href="https://letsvision.swiftgg.team/">Let&#8217;s Vision</a> &#22823;&#20250;&#22312;&#19978;&#28023;&#22914;&#26399;&#20030;&#34892;&#65292;&#20170;&#24180;&#30340;&#20027;&#39064;&#26159;&#65306;&#8220;Born to Create, Powered by AI&#8221;&#12290;&#38500;&#20102;&#19982; Swift&#12289;&#31354;&#38388;&#35745;&#31639;&#30456;&#20851;&#30340;&#24120;&#35268; Session&#65292;&#22823;&#20250;&#36824;&#36992;&#35831;&#20102;&#35768;&#22810;&#24320;&#21457;&#32773;&#20998;&#20139;&#20182;&#20204;&#22312;&#24037;&#20316;&#20013;&#23545; AI &#30340;&#24212;&#29992;&#19982;&#29702;&#35299;&#12290;&#36890;&#36807;&#36825;&#20123;&#35762;&#24072;&#23545; AI &#24037;&#20316;&#27969;&#30340;&#20171;&#32461;&#65292;&#25105;&#20063;&#21463;&#30410;&#21290;&#27973;&#12290;&#21407;&#26412;&#21482;&#33021;&#23481;&#32435; 300 &#20154;&#30340; AI &#20027;&#39064;&#20250;&#22330;&#65292;&#37324;&#19977;&#23618;&#22806;&#19977;&#23618;&#31449;&#28385;&#20102;&#28909;&#24773;&#39640;&#28072;&#30340;&#35266;&#20247;&#12290;</p><p>&#28982;&#32780;&#65292;&#22312;&#20247;&#22810;&#20248;&#31168;&#30340; Session &#20013;&#65292;&#19968;&#22330;&#30001; <a href="https://www.linkedin.com/in/iamhands0me/">YuChe Cheng</a> &#20934;&#22791;&#30340;&#12289;&#21517;&#20026;&#12298;Let&#8217;s Create 1-liner Code in Swift&#12299;&#30340;&#28436;&#35762;&#21364;&#23558;&#25105;&#30340;&#27880;&#24847;&#21147;&#24341;&#21521;&#20102;&#21478;&#19968;&#20010;&#20250;&#22330;&#12290;&#36825;&#31350;&#31455;&#26159;&#19968;&#20010;&#24590;&#26679;&#30340;&#35805;&#39064;&#65311;&#24102;&#30528;&#30097;&#38382;&#25105;&#36208;&#20102;&#36827;&#21435;&#12290;&#20316;&#20026;&#19968;&#20010; LeetCode &#31215;&#20998; 2200+ &#30340;&#24320;&#21457;&#32773;&#65292;YuChe Cheng &#22312;&#28436;&#35762;&#20013;&#23637;&#31034;&#20102;&#22914;&#20309;&#36890;&#36807; Foundation &#20197;&#21450; Swift Algorithms &#25552;&#20379;&#30340;&#22823;&#37327;&#39640;&#38454;&#20989;&#25968;&#65292;&#23558;&#21407;&#26412;&#24179;&#28129;&#26080;&#22855;&#30340; For-loop &#20195;&#30721;&#65292;&#36716;&#25442;&#25104;&#26356;&#21152;&#20248;&#38597;&#12289;&#32654;&#35266;&#12289;&#26497;&#20855; Swift &#39118;&#26684;&#30340; Function Chaining&#65288;1-liner code&#65289;&#65292;&#24182;&#22312;&#26131;&#35835;&#24615;&#19982;&#24615;&#33021;&#20043;&#38388;&#21462;&#24471;&#20102;&#24456;&#22909;&#30340;&#24179;&#34913;&#12290;</p><p>&#30475;&#30528;&#24187;&#28783;&#29255;&#19978;&#30340; Function Chaining &#34987;&#19968;&#27425;&#21448;&#19968;&#27425;&#22320;&#20248;&#38597;&#36845;&#20195;&#65292;&#25105;&#26377;&#31181;&#33541;&#22622;&#39039;&#24320;&#30340;&#30021;&#24555;&#12290;&#25972;&#25972; 30 &#20998;&#38047;&#30340;&#28436;&#35762;&#65292;&#35753;&#25105;&#22987;&#32456;&#22788;&#20110;&#19968;&#31181;&#32431;&#31929;&#30340;&#20852;&#22859;&#20043;&#20013;&#8212;&#8212;&#36825;&#31181;&#24863;&#35273;&#65292;&#36890;&#24120;&#21482;&#22312;&#25105;&#32478;&#23613;&#33041;&#27713;&#26368;&#32456;&#25915;&#20811;&#20102;&#19968;&#20010;&#38590;&#39064;&#65292;&#25110;&#26159;&#28145;&#21051;&#29702;&#35299;&#20102;&#19968;&#20010;&#26032;&#27010;&#24565;&#21518;&#25165;&#20250;&#28044;&#29616;&#12290;</p><p>&#23613;&#31649;&#19982;&#20027;&#20250;&#22330;&#21482;&#26377;&#19968;&#22681;&#20043;&#38548;&#65292;&#20294;&#30001;&#20110; AI &#35805;&#39064;&#30340;&#32477;&#23545;&#28909;&#24230;&#65292;&#26412;&#22330;&#28436;&#35762;&#30340;&#21548;&#20247;&#26126;&#26174;&#20559;&#23569;&#12290;&#19982;&#20854;&#35828;&#25105;&#20026;&#35768;&#22810;&#20154;&#38169;&#22833;&#20102;&#19968;&#22330;&#31934;&#24425;&#28436;&#35762;&#32780;&#24863;&#21040;&#36951;&#25022;&#65292;&#25105;&#30495;&#27491;&#25285;&#24515;&#30340;&#20854;&#23454;&#26159;&#65306;<strong>&#38543;&#30528; AI &#30340;&#36827;&#19968;&#27493;&#28183;&#36879;&#65292;&#35768;&#22810;&#24320;&#21457;&#32773;&#21407;&#26412;&#22312;&#36861;&#27714;&#21151;&#33021;&#20043;&#22806;&#25152;&#36171;&#20104;&#20195;&#30721;&#30340;&#37027;&#20221;&#8220;&#27668;&#36136;&#8221;&#65292;&#20250;&#19981;&#20250;&#23601;&#27492;&#28040;&#20129;&#65311;</strong></p><p>&#24320;&#21457;&#32773;&#19981;&#24212;&#35813;&#21482;&#20851;&#24515;&#32534;&#35793;&#21518;&#20919;&#20912;&#20912;&#30340;&#20108;&#36827;&#21046;&#21151;&#33021;&#65292;&#20195;&#30721;&#26412;&#36523;&#20063;&#26159;&#20010;&#20154;&#39118;&#26684;&#30340;&#36733;&#20307;&#12290;&#23427;&#23601;&#20687;&#25991;&#31456;&#19968;&#26679;&#65292;&#22312;&#36755;&#20986;&#36923;&#36753;&#19982;&#32467;&#26524;&#20043;&#22806;&#65292;&#36824;&#25215;&#36733;&#30528;&#32654;&#23398;&#34920;&#36798;&#65292;&#20307;&#29616;&#30528;&#32534;&#20889;&#32773;&#30340;&#20010;&#20154;&#21697;&#21619;&#19982;&#24039;&#24605;&#12290;</p><p>&#22312;&#20170;&#24180;&#30340; Let&#8217;s Vision &#19978;&#65292;&#25105;&#24863;&#35273;&#25105;&#20204;&#27491;&#31449;&#22312;&#19968;&#20010;&#26102;&#38388;&#30340;&#21313;&#23383;&#36335;&#21475;&#65306;<strong>&#25105;&#20204;&#26159;&#35813;&#19968;&#21619;&#36861;&#27714; AI &#24102;&#26469;&#30340;&#26497;&#33268;&#39640;&#25928;&#65292;&#36824;&#26159;&#22312;&#25317;&#25265;&#21464;&#21270;&#30340;&#21516;&#26102;&#65292;&#20381;&#28982;&#35753;&#23646;&#20110;&#24320;&#21457;&#32773;&#30340;&#37027;&#20221;&#39556;&#20658;&#19982;&#25163;&#33402;&#65292;&#22312; AI &#26102;&#20195;&#24471;&#20197;&#20445;&#30041;&#65311;</strong></p><p><a href="https://fatbobman.com/zh/weekly/issue-128/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#26412;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0129-01">Swift 6.3 Released</a></strong></h3><p>&#20174; Swift 6 &#24320;&#22987;&#65292;&#35821;&#35328;&#28436;&#36827;&#24050;&#32463;&#31283;&#23450;&#22312;&#21322;&#24180;&#19968;&#20010; minor &#29256;&#26412;&#30340;&#33410;&#22863;&#65292;&#19978;&#21608; Swift 6.3 &#22914;&#26399;&#21457;&#24067;&#12290;&#19982;&#21069;&#20960;&#20010;&#29256;&#26412;&#30456;&#27604;&#65292;&#36825;&#19968;&#29256;&#26412;&#24182;&#26410;&#24341;&#20837;&#26126;&#26174;&#30340;&#37325;&#30917;&#29305;&#24615;&#65292;&#26356;&#22810;&#26159;&#23545;&#26082;&#26377;&#20307;&#31995;&#30340;&#25171;&#30952;&#65306;&#24182;&#21457;&#27169;&#22411;&#22312;&#35786;&#26029;&#20934;&#30830;&#24615;&#26041;&#38754;&#26377;&#25152;&#25913;&#36827;&#65292;&#26032;&#22686;&#30340; <code>@c</code> &#29305;&#24615;&#65288;attribute&#65289;&#36827;&#19968;&#27493;&#24378;&#21270;&#20102; C/C++ &#20114;&#25805;&#20316;&#33021;&#21147;&#65292;&#21516;&#26102;&#32534;&#35793;&#20248;&#21270;&#30340;&#25511;&#21046;&#31890;&#24230;&#20063;&#21464;&#24471;&#26356;&#21152;&#32454;&#33268;&#12290;</p><p>&#23613;&#31649;&#22914;&#27492;&#65292;&#36825;&#19968;&#29256;&#26412;&#20063;&#37322;&#25918;&#20986;&#19968;&#20010;&#28165;&#26224;&#30340;&#20449;&#21495;&#65306;Swift &#27491;&#22312;&#20174;&#8220;&#20197; Apple &#24179;&#21488;&#20026;&#20013;&#24515;&#30340;&#24212;&#29992;&#24320;&#21457;&#35821;&#35328;&#8221;&#65292;&#36880;&#27493;&#21521;&#8220;&#20855;&#22791;&#36328;&#24179;&#21488;&#19982;&#31995;&#32479;&#32423;&#33021;&#21147;&#30340;&#36890;&#29992;&#35821;&#35328;&#8221;&#28436;&#36827;&#12290;Embedded Swift&#12289;Android &#25903;&#25345;&#30340;&#25345;&#32493;&#25512;&#36827;&#65292;&#20197;&#21450; SwiftPM &#26500;&#24314;&#20307;&#31995;&#30340;&#32479;&#19968;&#65292;&#37117;&#22312;&#25351;&#21521;&#36825;&#19968;&#26041;&#21521;&#12290;&#23545;&#22810;&#25968; iOS &#24320;&#21457;&#32773;&#32780;&#35328;&#65292;&#30701;&#26399;&#20307;&#24863;&#25110;&#35768;&#26377;&#38480;&#65292;&#20294;&#20174;&#26356;&#38271;&#30340;&#26102;&#38388;&#32500;&#24230;&#26469;&#30475;&#65292;&#36825;&#26356;&#20687;&#26159;&#19968;&#27425;&#20026;&#26410;&#26469;&#38138;&#36335;&#30340;&#22522;&#30784;&#24615;&#26356;&#26032;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-02">&#22914;&#20309;&#22312; Swift &#20013;&#25215;&#25509;&#23578;&#26410;&#31283;&#23450;&#30340; JSON (Designing a type-driven JSON in Swift)</a></strong></h3><p>&#24403; API &#22865;&#32422;&#23578;&#26410;&#31283;&#23450;&#12289;&#21069;&#21518;&#31471;&#23545;&#23383;&#27573;&#30340;&#29702;&#35299;&#21448;&#32463;&#24120;&#28418;&#31227;&#26102;&#65292;Swift &#30340;&#24378;&#31867;&#22411;&#31995;&#32479;&#21453;&#32780;&#20250;&#25918;&#22823;&#25968;&#25454;&#19982; JSON &#20043;&#38388;&#36716;&#25442;&#26102;&#30340;&#36793;&#30028;&#38382;&#39064;&#12290;<a href="https://www.linkedin.com/in/inekipelov/">Roman Niekipielov</a> &#22312;&#26412;&#25991;&#20013;&#20171;&#32461;&#20102;&#19968;&#20010;&#21051;&#24847;&#20570;&#23567;&#30340; <code>JSONValue</code> &#31867;&#22411;&#65292;&#29992;&#26469;&#25215;&#25509;&#36825;&#31867;&#36807;&#28193;&#38454;&#27573;&#30340; JSON &#25968;&#25454;&#12290;&#30456;&#27604; <code>[String: Any]</code>&#65292;&#23427;&#20445;&#30041;&#20102;&#26356;&#26126;&#30830;&#30340;&#31867;&#22411;&#32467;&#26500;&#65307;&#30456;&#27604;&#30452;&#25509;&#32534;&#20889; <code>Codable</code> &#27169;&#22411;&#65292;&#21448;&#26356;&#36866;&#21512;&#24212;&#23545;&#39057;&#32321;&#21464;&#21270;&#30340;&#22865;&#32422;&#12290;&#36825;&#20010;&#23454;&#29616;&#24182;&#19981;&#35797;&#22270;&#26367;&#20195;&#27491;&#24335;&#27169;&#22411;&#65292;&#32780;&#26159;&#23558;&#19981;&#30830;&#23450;&#24615;&#26242;&#26102;&#38480;&#21046;&#22312;&#36793;&#30028;&#23618;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-03">Swift &#21407;&#29983; AI Agent &#24320;&#21457;&#23454;&#36341;&#31995;&#21015;</a></strong></h3><p>&#24066;&#38754;&#19978;&#26377;&#22823;&#37327;&#24320;&#21457;&#32773;&#20351;&#29992; Python&#12289;TypeScript &#24320;&#21457; AI Agent&#65292;&#20294; <a href="https://x.com/chris_karani">Chris Karani</a> &#35748;&#20026;&#65292;Swift &#30340;&#24182;&#21457;&#27169;&#22411;&#22825;&#28982;&#26356;&#36866;&#21512; Agent &#30340;&#38548;&#31163;&#19982;&#35843;&#24230;&#65292;&#24378;&#31867;&#22411;&#31995;&#32479;&#21644;&#23439;&#21151;&#33021;&#20063;&#24102;&#26469;&#20102;&#39069;&#22806;&#30340;&#23433;&#20840;&#20445;&#35777;&#12290;&#20182;&#29992; 6 &#31687;&#25991;&#31456;&#12289;&#20174;&#22810;&#20010;&#35282;&#24230;&#23454;&#36341;&#20102;&#36825;&#19968;&#35266;&#28857;&#8212;&#8212;&#20174;&#32479;&#19968;&#22810;&#20010; LLM Provider &#30340; SDK <a href="https://github.com/christopherkarani/Conduit">Conduit</a>&#65292;&#21040;&#22522;&#20110; Apple Foundation Models &#30340; Agent &#36816;&#34892;&#26102; <a href="https://github.com/christopherkarani/Colony">Colony</a>&#65292;&#20877;&#21040;&#29992; Metal &#21152;&#36895;&#30340;&#19978;&#19979;&#25991;&#35760;&#24518;&#31649;&#29702;&#12290;&#22914;&#26524;&#20320;&#27491;&#22312;&#32771;&#34385;&#22312; Apple &#24179;&#21488;&#19978;&#26500;&#24314; AI &#21151;&#33021;&#65292;&#36825;&#20010;&#31995;&#21015;&#26159;&#30446;&#21069;&#23569;&#35265;&#30340;&#23436;&#25972;&#21407;&#29983;&#26041;&#26696;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-04">Liquid Glass &#35774;&#35745;&#24037;&#20316;&#22346; (Talking Liquid Glass with Apple)</a></strong></h3><p><a href="https://x.com/dbolella">Danny Bolella</a> &#22312;&#32445;&#32422;&#21442;&#21152;&#20102;&#33529;&#26524;&#20030;&#21150;&#30340; Liquid Glass &#35774;&#35745;&#24037;&#20316;&#22346;&#65292;&#19982;&#35774;&#35745;&#22242;&#38431;&#21644; SwiftUI &#24037;&#31243;&#24072;&#36827;&#34892;&#20102;&#20026;&#26399;&#19977;&#22825;&#30340;&#28145;&#20837;&#20132;&#27969;&#12290;&#26412;&#27425;&#27963;&#21160;&#20256;&#36882;&#20986;&#38750;&#24120;&#26126;&#30830;&#30340;&#20449;&#21495;&#65306;Liquid Glass &#24182;&#38750;&#36807;&#28193;&#24615;&#23581;&#35797;&#65292;&#32780;&#26159;&#33529;&#26524;&#26410;&#26469;&#25968;&#24180;&#30340;&#35774;&#35745;&#26041;&#21521;&#65292;&#19988;&#23558;&#22312;&#21518;&#32493;&#24037;&#20855;&#38142;&#20013;&#25104;&#20026;&#40664;&#35748;&#21069;&#25552;&#12290;&#19982;&#27492;&#21516;&#26102;&#65292;&#33529;&#26524;&#21453;&#22797;&#24378;&#35843;&#8220;&#23618;&#32423;&#65288;Hierarchy&#65289;&#8221;&#30340;&#37325;&#35201;&#24615;&#8212;&#8212;&#30028;&#38754;&#24212;&#22260;&#32469;&#20869;&#23481;&#26500;&#24314;&#65292;&#25511;&#20214;&#21482;&#26159;&#26381;&#21153;&#20110;&#20869;&#23481;&#30340;&#36741;&#21161;&#20803;&#32032;&#65292;&#24212;&#23613;&#37327;&#36864;&#23621;&#36793;&#32536;&#65292;&#35753;&#20449;&#24687;&#26412;&#36523;&#25104;&#20026;&#35270;&#35273;&#19982;&#20132;&#20114;&#30340;&#20013;&#24515;&#12290;&#38500;&#27492;&#20043;&#22806;&#65292;Danny &#36824;&#22312;&#26412;&#25991;&#20013;&#35760;&#24405;&#20102;&#20854;&#20182;&#19968;&#20123; SwiftUI &#24037;&#31243;&#24072;&#32473;&#20986;&#30340;&#24314;&#35758;&#21644;&#25216;&#24039;&#12290;&#26412;&#25991;&#35760;&#24405;&#30340;&#20869;&#23481;&#21487;&#20197;&#24110;&#21161;&#20320;&#26356;&#26089;&#29702;&#35299;&#36825;&#22330;&#35774;&#35745;&#28436;&#36827;&#30340;&#33410;&#22863;&#19982;&#26041;&#21521;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-05">App Store Connect &#22823;&#26356;&#26032; (Apple Dropped 100+ New Metrics. Your Competitors Are Already Using Them)</a></strong></h3><p>&#33529;&#26524;&#23545; App Store Connect &#36827;&#34892;&#20102;&#36817;&#24180;&#26469;&#26368;&#22823;&#30340;&#19968;&#27425;&#26356;&#26032;&#65292;&#19968;&#21475;&#27668;&#24341;&#20837;&#20102; 100+ &#23448;&#26041;&#25351;&#26631;&#12289;&#25353;&#26469;&#28304;&#21010;&#20998;&#30340; cohort &#20998;&#26512;&#12289;&#21516;&#34892;&#22522;&#20934;&#23545;&#27604;&#65288;&#36716;&#21270;&#29575;&#19982;&#21333;&#19979;&#36733;&#25910;&#30410;&#65289;&#20197;&#21450;&#21487;&#36890;&#36807; API &#23548;&#20986;&#30340;&#35746;&#38405;&#25968;&#25454;&#12290;<a href="https://www.linkedin.com/in/jessica-chung-197215220/">Jessica Chung</a> &#22312;&#26412;&#25991;&#20013;&#23545;&#36825;&#20123;&#20851;&#38190;&#21464;&#21270;&#36827;&#34892;&#20102;&#31995;&#32479;&#26803;&#29702;&#12290;&#30001;&#20110;&#25152;&#26377;&#25968;&#25454;&#22343;&#26469;&#33258;&#33529;&#26524;&#19968;&#25163;&#32479;&#35745;&#65292;&#36825;&#24847;&#21619;&#30528;&#24320;&#21457;&#32773;&#22312; ASO &#21644;&#22686;&#38271;&#20915;&#31574;&#20013;&#65292;&#23558;&#19981;&#20877;&#20381;&#36182;&#31532;&#19977;&#26041;&#20272;&#31639;&#65292;&#32780;&#21487;&#20197;&#30452;&#25509;&#22522;&#20110;&#30495;&#23454;&#29992;&#25143;&#34892;&#20026;&#36827;&#34892;&#20998;&#26512;&#19982;&#20248;&#21270;&#12290;&#26356;&#37325;&#35201;&#30340;&#26159;&#65292;&#36825;&#27425;&#26356;&#26032;&#34917;&#40784;&#20102;&#38271;&#26399;&#32570;&#22833;&#30340;&#20851;&#38190;&#33021;&#21147;&#65306;&#20320;&#21487;&#20197;&#36861;&#36394;&#19981;&#21516;&#20851;&#38190;&#35789;&#19982;&#28192;&#36947;&#24102;&#26469;&#30340;&#29992;&#25143;&#36136;&#37327;&#65292;&#24314;&#31435;&#20174;&#26333;&#20809;&#12289;&#19979;&#36733;&#21040;&#35746;&#38405;&#19982;&#32493;&#36153;&#30340;&#23436;&#25972;&#36716;&#21270;&#38142;&#36335;&#65292;&#24182;&#36890;&#36807;&#21516;&#34892;&#22522;&#20934;&#26126;&#30830;&#33258;&#36523;&#25152;&#22788;&#20301;&#32622;&#12290;</p><blockquote><p>&#26412;&#27425;&#26356;&#26032;&#23545;&#20110;&#24320;&#21457;&#32773;&#32780;&#35328;&#26080;&#30097;&#26159;&#21033;&#22909;&#65292;&#20294;&#23545;&#20110;&#37096;&#20998;&#31532;&#19977;&#26041; App Store &#20998;&#26512;&#26381;&#21153;&#26469;&#35828;&#65292;&#20063;&#22312;&#19968;&#23450;&#31243;&#24230;&#19978;&#25552;&#39640;&#20102;&#31454;&#20105;&#38376;&#27099;&#65292;&#20419;&#20351;&#20854;&#25552;&#20379;&#26356;&#20855;&#38468;&#21152;&#20540;&#30340;&#33021;&#21147;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-06">Package Traits in Xcode</a></strong></h3><p>&#22312;&#21019;&#24314; SPM &#26102;&#65292;&#26576;&#20123;&#20381;&#36182;&#21487;&#33021;&#21482;&#34987;&#29305;&#23450; API &#20351;&#29992;&#65292;&#20294;&#19968;&#26086;&#29992;&#25143;&#24341;&#20837;&#35813;&#21253;&#65292;&#21363;&#20415;&#19981;&#20351;&#29992;&#36825;&#20123; API&#65292;&#20063;&#38656;&#35201;&#19968;&#24182;&#24341;&#20837;&#30456;&#20851;&#20381;&#36182;&#12290;Package Traits &#27491;&#26159;&#20026;&#20102;&#35299;&#20915;&#36825;&#19968;&#38382;&#39064;&#32780;&#24341;&#20837;&#30340;&#65292;&#23427;&#20026; SPM &#25552;&#20379;&#20102;&#19968;&#31181;&#22768;&#26126;&#21487;&#36873;&#29305;&#24615;&#30340;&#26041;&#24335;&#65292;&#20351;&#20351;&#29992;&#32773;&#33021;&#22815;&#25353;&#38656;&#21551;&#29992;&#21151;&#33021;&#65292;&#20174;&#32780;&#36991;&#20813;&#24341;&#20837;&#19981;&#24517;&#35201;&#30340;&#20381;&#36182;&#12290;&#36951;&#25022;&#30340;&#26159;&#65292;&#22312;&#35813;&#21151;&#33021;&#25512;&#20986;&#21518;&#65292;&#19968;&#30452;&#21482;&#33021;&#22312;&#31038;&#21306;&#29256;&#26412;&#30340; Swift &#24037;&#20855;&#38142;&#20013;&#20351;&#29992;&#12290;&#38543;&#30528; Xcode 26.4 &#30340;&#21457;&#24067;&#65292;Package Traits &#32456;&#20110;&#33719;&#24471;&#20102;&#33529;&#26524;&#23448;&#26041;&#25903;&#25345;&#65292;&#26377;&#26395;&#36814;&#26469;&#26356;&#24191;&#27867;&#30340;&#24212;&#29992;&#12290;<a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#22312;&#26412;&#25991;&#20013;&#23545;&#35813;&#29305;&#24615;&#36827;&#34892;&#20102;&#20171;&#32461;&#65292;&#24182;&#23637;&#31034;&#20102;&#20854;&#22522;&#26412;&#29992;&#27861;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-07">&#20248;&#21270;&#24863;&#23448;&#24615;&#33021;&#65292;&#35753;&#29992;&#25143;&#24863;&#35273;&#26356;&#24555; (Why your SwiftUI app feels slow even though Instruments says it&#8217;s fine?)</a></strong></h3><p>&#29992;&#25143;&#25237;&#35785;&#21709;&#24212;&#24930;&#65292;&#19968;&#23450;&#26159;&#24212;&#29992;&#24615;&#33021;&#38382;&#39064;&#21527;&#65311;<a href="https://www.linkedin.com/in/rafal-dubiel/">Rafa&#322; Dubiel</a> &#23558;&#20851;&#27880;&#28857;&#20174;&#8220;&#23454;&#38469;&#24615;&#33021;&#8221;&#36716;&#21521;&#8220;&#24863;&#30693;&#24615;&#33021;&#65288;Perceived Performance)&#8221;&#65292;&#35752;&#35770;&#22914;&#20309;&#36890;&#36807;&#30028;&#38754;&#21453;&#39304;&#19982;&#20132;&#20114;&#33410;&#22863;&#65292;&#35753;&#29992;&#25143;&#24863;&#35273;&#24212;&#29992;&#8220;&#26356;&#24555;&#8221;&#12290;&#20363;&#22914;&#36890;&#36807; skeleton view&#12289;&#24310;&#36831;&#21152;&#36733;&#65292;&#20197;&#21450;&#21512;&#29702;&#30340;&#21160;&#30011;&#19982;&#29366;&#24577;&#36807;&#28193;&#26469;&#25513;&#30422;&#31561;&#24453;&#26102;&#38388;&#12290;&#20316;&#32773;&#25351;&#20986;&#65292;&#22312;&#35768;&#22810;&#22330;&#26223;&#19979;&#65292;&#29992;&#25143;&#20307;&#39564;&#30340;&#20851;&#38190;&#24182;&#19981;&#22312;&#20110;&#20943;&#23569;&#27627;&#31186;&#32423;&#30340;&#35745;&#31639;&#26102;&#38388;&#65292;&#32780;&#22312;&#20110;&#26159;&#21542;&#21450;&#26102;&#25552;&#20379;&#21453;&#39304;&#12290;&#30456;&#27604;&#21333;&#32431;&#20248;&#21270;&#24615;&#33021;&#25351;&#26631;&#65292;&#36825;&#31181;&#20174;&#29992;&#25143;&#24863;&#30693;&#20986;&#21457;&#30340;&#24605;&#36335;&#65292;&#24448;&#24448;&#26356;&#30452;&#25509;&#22320;&#24433;&#21709;&#29992;&#25143;&#23545;&#24212;&#29992;&#27969;&#30021;&#24230;&#30340;&#21028;&#26029;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0129-08">&#22312; SwiftUI &#20013;&#25511;&#21046;&#34892;&#39640; (Adjusting line height in SwiftUI on iOS 26)</a></strong></h3><p>iOS 26 &#20026; SwiftUI &#26032;&#22686;&#20102; <code>lineHeight(_:)</code> modifier&#65292;&#29992;&#20110;&#25511;&#21046;&#25991;&#26412;&#30456;&#37051;&#20004;&#34892;&#22522;&#32447;&#20043;&#38388;&#30340;&#36317;&#31163;&#12290;<a href="https://x.com/natpanferova">Natalia Panferova</a> &#22312;&#26412;&#25991;&#20013;&#23545;&#21508;&#31181;&#37197;&#32622;&#26041;&#24335;&#36827;&#34892;&#20102;&#35814;&#32454;&#23545;&#27604;&#65306;&#20869;&#32622;&#39044;&#35774;&#65288;<code>.loose</code>&#12289;<code>.tight</code>&#65289;&#12289;&#22522;&#20110;&#23383;&#21495;&#20493;&#25968;&#30340; <code>.multiple(factor:)</code>&#12289;&#22266;&#23450;&#22686;&#37327;&#30340; <code>.leading(increase:)</code>&#65292;&#20197;&#21450;&#32477;&#23545;&#20540;&#25511;&#21046;&#30340; <code>.exact(points:)</code>&#12290;&#27492;&#22806;&#65292;<code>lineHeight(_:)</code> &#19982;&#24050;&#26377;&#30340; <code>lineSpacing(_:)</code> &#24182;&#19981;&#30456;&#21516;&#65306;&#21069;&#32773;&#25511;&#21046;&#22522;&#32447;&#38388;&#36317;&#65292;&#21518;&#32773;&#25511;&#21046;&#34892;&#24213;&#21040;&#19979;&#19968;&#34892;&#34892;&#39030;&#30340;&#36317;&#31163;&#12290;</p><blockquote><p>Natalia Panferova &#26366;&#26159; Apple SwiftUI &#26680;&#24515;&#22242;&#38431;&#25104;&#21592;&#65292;&#21442;&#19982;&#36807;&#22810;&#20010;&#20851;&#38190; API &#30340;&#35774;&#35745;&#19982;&#24320;&#21457;&#12290;&#26412;&#26376;&#22905;&#21018;&#21018;&#20986;&#29256;&#20102;&#26032;&#20070; <a href="https://books.nilcoalescing.com/the-swiftui-way">The SwiftUI Way</a>&#65292;&#38754;&#21521;&#26377;&#19968;&#23450; SwiftUI &#32463;&#39564;&#30340;&#24320;&#21457;&#32773;&#65292;&#32858;&#28966;&#20110;&#29983;&#20135;&#29615;&#22659;&#20013;&#30340;&#27169;&#24335;&#36873;&#25321;&#12289;&#24120;&#35265;&#21453;&#27169;&#24335;&#35782;&#21035;&#65292;&#20197;&#21450;&#22914;&#20309;&#19982;&#26694;&#26550;&#8220;&#39034;&#21183;&#32780;&#20026;&#8221;&#32780;&#38750;&#23545;&#25239;&#12290;</p></blockquote><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0129-09">Cove&#65306;Swift 6 &#32534;&#20889;&#30340; macOS &#24320;&#28304;&#25968;&#25454;&#24211;&#23458;&#25143;&#31471;</a></strong></h3><p>Cove &#26159;&#30001; <a href="https://www.linkedin.com/in/emanuelemicheletti/">Emanuele Micheletti</a> &#24320;&#21457;&#30340;&#19968;&#27454;&#21407;&#29983; macOS &#25968;&#25454;&#24211;&#23458;&#25143;&#31471;&#65292;&#25972;&#20010;&#39033;&#30446;&#23436;&#20840;&#20351;&#29992; Swift 6 &#26500;&#24314;&#65292;&#30446;&#21069;&#24050;&#32463;&#25903;&#25345; PostgreSQL&#12289;MySQL&#12289;MariaDB&#12289;SQLite&#12289;MongoDB&#12289;Redis&#12289;ScyllaDB&#12289;Cassandra &#21644; Elasticsearch &#31561;&#22810;&#31181;&#21518;&#31471;&#12290;&#23427;&#37319;&#29992; SwiftUI &#25645;&#37197; AppKit &#21407;&#29983;&#25511;&#20214;&#23454;&#29616;&#65292;&#27809;&#26377;&#36208; Electron &#25110; Web &#25216;&#26415;&#26632;&#65292;&#22240;&#27492;&#25972;&#20307;&#26356;&#36731;&#37327;&#65292;&#20063;&#26356;&#31526;&#21512; macOS &#29992;&#25143;&#29087;&#24713;&#30340;&#20132;&#20114;&#20307;&#39564;&#12290;</p><p>&#30456;&#27604;&#8220;&#21448;&#19968;&#20010;&#25968;&#25454;&#24211; GUI&#8221;&#65292;Cove &#26356;&#20540;&#24471;&#20851;&#27880;&#30340;&#26159;&#23427;&#30340;&#23454;&#29616;&#24605;&#36335;&#12290;&#20316;&#32773;&#23558;&#25152;&#26377;&#25968;&#25454;&#24211;&#33021;&#21147;&#32479;&#19968;&#25277;&#35937;&#20026; DatabaseBackend &#21327;&#35758;&#65292;UI &#23618;&#19981;&#21253;&#21547;&#20219;&#20309;&#38024;&#23545;&#29305;&#23450;&#21518;&#31471;&#30340;&#20998;&#25903;&#36923;&#36753;&#12290;&#26080;&#35770;&#26159; SQL &#25968;&#25454;&#24211;&#12289;Redis &#36825;&#31867;&#38190;&#20540;&#25968;&#25454;&#24211;&#65292;&#36824;&#26159; MongoDB&#12289;Elasticsearch &#36825;&#31867;&#38750;&#20851;&#31995;&#22411;&#21518;&#31471;&#65292;&#26368;&#32456;&#37117;&#20250;&#34987;&#25972;&#29702;&#20026;&#32479;&#19968;&#30340;&#34920;&#26684;&#27169;&#22411;&#20132;&#30001;&#30028;&#38754;&#28210;&#26579;&#12290;&#39033;&#30446;&#30446;&#21069;&#20173;&#22788;&#20110; v0.1.0 &#30340;&#26089;&#26399;&#38454;&#27573;&#65292;&#20294;&#24050;&#32463;&#20855;&#22791;&#26597;&#35810;&#12289;&#32467;&#26500;&#27983;&#35272;&#12289;&#32534;&#36753;&#12289;SSH &#38567;&#36947;&#21644;&#22810;&#26631;&#31614;&#31561;&#22522;&#30784;&#33021;&#21147;&#12290;&#21363;&#20415;&#20320;&#24182;&#19981;&#25171;&#31639;&#25226;&#23427;&#20316;&#20026;&#26085;&#24120;&#25968;&#25454;&#24211;&#24037;&#20855;&#65292;Cove &#20381;&#28982;&#26159;&#19968;&#20010;&#24456;&#20540;&#24471; Swift &#24320;&#21457;&#32773;&#30740;&#31350;&#30340;&#26700;&#38754;&#24212;&#29992;&#26550;&#26500;&#26679;&#26412;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #128]]></title><description><![CDATA[Is My App Stuck in Review?]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-128</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-128</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 23 Mar 2026 12:02:22 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!TXb6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TXb6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TXb6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 424w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 848w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 1272w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TXb6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp" width="1261" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1261,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:6222,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/191741223?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TXb6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 424w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 848w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 1272w, https://substackcdn.com/image/fetch/$s_!TXb6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffba21959-24f6-45a2-b0eb-a05cabc62c97_1261x688.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Is My App Stuck in Review?</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-128/">Read on web &#8594;</a></p><p>Last Thursday, a user in my Discord community complained that their app had been submitted to App Store Connect for four or five days but still hadn&#8217;t entered the review process. While I was enthusiastically analyzing the possible reasons with everyone, my heart suddenly skipped a beat: it seemed that the app I submitted on Monday hadn&#8217;t received any review updates either.</p><p>Someone suggested I apply for an &#8220;Expedited Review&#8221;. However, when I clicked into the page, the system prompted that I had &#8220;no eligible apps&#8221;. Upon closer inspection, I realized I was just a bit rusty from not updating my apps for so long&#8212;although my app had completed all the prerequisite steps, I simply hadn&#8217;t clicked the &#8220;Submit for Review&#8221; button at all.</p><p>Just a few hours after I finally clicked the button, the app was successfully approved and published.</p><p>While my situation was a mere false alarm, discussions in the community about Apple&#8217;s app review process slowing down have indeed been increasing recently. Many speculate that this might be related to the recent rise of Vibe Coding. Although there is no official confirmation, Vibe Coding has undeniably lowered the barrier to entry for development. In doing so, it has simultaneously amplified the volume of app submissions and the frequency of iterations in a short period, thereby passing the pressure down to the review team.</p><p>In fact, Apple has recently been holding up the review process for apps like Replit, which allow everyday consumers to engage in Vibe Coding. Even when allowing them to remain on the store, Apple has demanded compromises on core features. In Michael Tsai&#8217;s <a href="https://mjtsai.com/blog/2026/03/20/updates-to-vibe-coding-apps-rejected-from-the-app-store/">blog post</a> covering this news, I came across a very sharp comment:</p><blockquote><p>I thought the implication was that the vibe coding apps were being used to make the vibecoded apps that get submitted.</p></blockquote><p>AI is not only reshaping the way we develop software but also posing new challenges to the app review and distribution systems. One might ask: if we fight magic with magic and let AI fully take over the review process, wouldn&#8217;t it be more efficient?</p><p>Apple&#8217;s review mechanism has never been entirely transparent. Sometimes, whether an app passes smoothly or not even depends on whether you &#8220;happen to&#8221; encounter a sympathetic reviewer. But looking at it from another angle, at least &#8220;humans&#8221; remain the most crucial part of this defense line. Human judgment can be flawed and biased, but it still retains a certain degree of flexibility when dealing with rigid rules.</p><p>I truly hope that the software ecosystem of the future does not devolve into a closed loop of &#8220;AI Development -&gt; AI Review&#8221;.</p><p><a href="https://fatbobman.com/en/weekly/issue-127/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Original</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/cde-an-attempt-to-make-core-data-feel-more-like-modern-swift/?utm_source=fatbobman%20weekly%20issue%20128&amp;utm_medium=web">CDE: An Attempt to Make Core Data Feel More Like Modern Swift</a></strong></h3><p>In <a href="https://fatbobman.com/en/posts/why-i-am-still-thinking-about-core-data-in-2026/">last week&#8217;s article</a>, I discussed the current reality of Core Data in modern projects: it hasn&#8217;t disappeared and still holds unique value, but the sense of misalignment between it and modern Swift development is becoming increasingly apparent. In this article, I continue along that line of thought and introduce an experimental project of mine: <a href="https://github.com/fatbobman/CoreDataEvolution">Core Data Evolution</a> (CDE).</p><p>It is not a new framework intended to replace Core Data, nor is it an attempt to pull developers back to older technologies. More accurately, it is my own response to this misalignment: <strong>if I still recognize the value of Core Data&#8217;s object graph model, migration system, and mature runtime, can it continue to exist in modern Swift projects in a more natural way?</strong></p><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0128-01">Expanding Animations in SwiftUI Lists</a></strong></h3><p>Developers often encounter a frustrating animation issue: when dynamically changing the height of a row inside a <code>List</code>, the content does not expand smoothly, but instead jumps abruptly. In this article, <a href="https://x.com/myridiphis">Pavel Zak</a> demonstrates through several experiments why common approaches such as conditional rendering with <code>if</code>, <code>withAnimation</code>, or even <code>.transition</code> fail to produce the desired effect inside <code>List</code>. While built-in solutions like <code>DisclosureGroup</code> can achieve smoother results, Pavel presents a more flexible approach: using <code>Animatable</code> combined with view size measurement to ensure that <code>List</code> receives continuously changing height values during the animation, resulting in a truly smooth expansion.</p><blockquote><p>A key characteristic of <code>List</code> (which is still backed by UIKit/AppKit) is that it requires a <em>definitive row height</em> during layout. Therefore, instead of letting <code>List</code> deal with structural changes, developers should, like <code>DisclosureGroup</code>, transform &#8220;discrete changes&#8221; into &#8220;continuous changes&#8221; by providing interpolatable height values. This is also why developers often resort to the <code>Animatable</code> protocol when dealing with animation anomalies. For a deeper understanding of this protocol and its use cases, you can refer to my previous <a href="https://fatbobman.com/en/posts/animatable-protocol-taming-unruly-swiftui-animation/">article</a>.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-02">SwiftUI iPad Adaptive Layout: Five Layers for Apps That Don&#8217;t Break in Split View</a></strong></h3><p>While Apple&#8217;s push toward multi-window capabilities in iPadOS is well-intentioned, it significantly increases the complexity of layout adaptation. Apps may appear in various forms, such as iPhone-like layouts, traditional full-screen iPad views, or Stage Manager windows. <a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> points out that relying solely on <code>horizontalSizeClass</code> is often insufficient in real-world scenarios. Developers need to combine container size with size classes to build a more fine-grained <code>LayoutEnvironment</code>, make layout branching decisions at the root view, and leverage mechanisms like <code>ViewThatFits</code> to let the system choose the most appropriate UI based on actual constraints, rather than assumptions about the device.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-03">Pitfalls and workarounds when dealing with RGB HDR Gain Map using ImageIO</a></strong></h3><p>The introduction of RGB HDR Gain Map based on the ISO 21496-1 standard in iOS 18 enables richer HDR image processing, but also introduces new pitfalls. Although the relevant APIs can return auxiliary data dictionaries, in the RGB Gain Map scenario the actual bitmap data (<code>kCGImageAuxiliaryDataInfoData</code>) is missing, preventing further processing. In other words, ImageIO is unable to fully read the content it generates in this case. <a href="https://x.com/JuniperPhoton">Weichao Deng</a> proposes a hybrid approach: use Core Image to read the Gain Map as a <code>CIImage</code>, manually render it into bitmap data, reconstruct the missing fields, and then write it back via ImageIO. For developers working on camera or image processing apps that involve HDR Gain Maps, this article can save a significant amount of debugging time.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-04">A Vision for Networking in Swift</a></strong></h3><p>The <a href="https://www.swift.org/ecosystem-steering-group/">Swift Ecosystem Steering Group</a> recently published a vision document on networking, discussing the current fragmentation in Swift&#8217;s networking ecosystem and its potential future direction.</p><p>The document highlights a clear divide: <code>URLSession</code>, SwiftNIO, and Network.framework coexist with overlapping functionality but incompatible abstractions. Developers often need to commit early to a specific stack, making later changes costly. Additionally, most existing networking APIs were designed before Swift Concurrency and rely on completion handlers, delegates, or reactive patterns, which feel increasingly out of place in modern Swift.</p><p>The proposed direction is a unified, layered networking architecture: shared I/O primitives and buffer types at the bottom, reusable protocol implementations (TLS, HTTP/1.1/2/3, QUIC, WebSocket) in the middle, and async/await-based client and server APIs at the top. The <code>swift-http-types</code> package (defining <code>HTTPRequest</code> / <code>HTTPResponse</code>) can be seen as an early step in this direction. The document also emphasizes that SwiftNIO and Network.framework will not be replaced, but will gradually converge toward shared underlying primitives.</p><blockquote><p>The vision is currently open for community feedback. You can <a href="https://forums.swift.org/t/prospective-vision-networking/">participate here</a>.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-05">Preparing Your iOS Codebase for AI Agents</a></strong></h3><p>As AI agents (such as Codex and Claude Code) become increasingly involved in real-world development workflows, the focus is shifting from &#8220;how to use AI to write code&#8221; to &#8220;how to make codebases suitable for AI collaboration&#8221;. <a href="https://hachyderm.io/@IronHam">Hesham Salman</a> explores this transition from an engineering perspective.</p><p>He argues that AI relies more on explicit contracts than on prompts. By structuring project conventions and behavioral rules through layered <code>AGENTS.md</code> documentation, using a Makefile to standardize build and test workflows, and encoding multi-step processes into reusable &#8220;skills,&#8221; implicit engineering knowledge can be transformed into structured, machine-readable systems.</p><blockquote><p>One particularly insightful detail: the author requires agents to update documentation whenever they encounter undocumented conventions, while enforcing a strict rule &#8212; <strong>every change must make the document shorter or more useful</strong>. This self-maintaining mechanism prevents both documentation decay and uncontrolled growth, striking a practical balance.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-06">iOS Conf SG 2026 Videos</a></strong></h3><p>iOS Conf SG 2026 was held from January 21 to 23 in Singapore, featuring dozens of developers and content creators from around the world sharing their insights and experiences in the Apple ecosystem. Last week, the full set of talks was released. I also had the opportunity to participate as a speaker, and you can explore the sessions as you&#8217;re interested.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0128-07">TaskGate: Managing Actor Reentrancy</a></strong></h3><p>While actors largely eliminate data races, their reentrant nature means that logic which appears sequential can lose its execution order after an <code>await</code>, leading to duplicate work or inconsistent state.</p><p>TaskGate, created by <a href="https://mastodon.social/@mattiem">Matt Massicotte</a>, addresses this scenario by introducing <code>AsyncGate</code> and <code>AsyncRecursiveGate</code>, which define critical sections for asynchronous code within actors. These ensure that only one task can enter a given section at a time. Unlike traditional locks, TaskGate allows safe asynchronous operations while holding the gate.</p><blockquote><p>Matt explicitly notes that this is not a replacement for well-designed actor models, but rather a supplementary tool when other approaches are insufficient. The gates are intentionally non-Sendable to reduce misuse across actors. If you&#8217;re dealing with reentrancy-related state issues or want to better understand this subtle aspect of Swift concurrency, both the library and the related <a href="https://www.reddit.com/r/swift/comments/1rx9aii/taskgate_library_for_managing_actor_reentrancy/">Reddit discussion</a> are worth exploring.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-08">pico-bare-swift</a></strong></h3><p>When Apple created Swift, the goal was clearly broader than just app development&#8212;it was meant to evolve into a general-purpose language across domains and abstraction levels. However, for a long time, Swift has struggled to gain traction in areas traditionally dominated by C/C++ or Rust. Through this example project, <a href="https://hachyderm.io/@kishikawakatsumi">kishikawa katsumi</a> demonstrates another possibility: with Embedded Swift, the language is beginning to enter the domain of embedded systems.</p><blockquote><p>What makes this project particularly appealing is that it turns something traditionally associated with low-level, C-centric development into a structured learning path. It goes far beyond &#8220;blinking an LED with Swift,&#8221; covering startup code, vector tables, memory initialization, register access, as well as drivers for UART, PWM, I2C, and SSD1306 OLED displays. In a sense, <strong>the value of such projects lies not in their practicality, but in how they redefine the boundaries of what Swift can do</strong>.</p></blockquote><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-128?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-128?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#25105;&#30340; App &#23457;&#26680;&#34987;&#21345;&#20102;&#65311;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-128/">&#32593;&#39029;&#29256;</a></strong></p><p>&#19978;&#21608;&#22235;&#65292;&#25105; Discord &#31038;&#21306;&#37324;&#30340;&#19968;&#20301;&#32593;&#21451;&#25265;&#24616;&#65292;&#35828;&#20182;&#30340;&#24212;&#29992;&#22312; App Store Connect &#19978;&#25552;&#20132;&#20102;&#22235;&#20116;&#22825;&#65292;&#21364;&#36831;&#36831;&#27809;&#26377;&#36827;&#20837;&#23457;&#26680;&#29366;&#24577;&#12290;&#23601;&#22312;&#25105;&#36824;&#27941;&#27941;&#26377;&#21619;&#22320;&#36319;&#22823;&#20249;&#20799;&#20998;&#26512;&#21407;&#22240;&#26102;&#65292;&#31361;&#28982;&#24515;&#37324;&#19968;&#32039;&#65306;&#25105;&#21608;&#19968;&#25552;&#20132;&#30340;&#24212;&#29992;&#65292;&#22909;&#20687;&#20063;&#19968;&#30452;&#27809;&#25910;&#21040;&#23457;&#26680;&#21160;&#24577;&#65311;</p><p>&#26377;&#32593;&#21451;&#24314;&#35758;&#25105;&#21435;&#30003;&#35831;&#19968;&#19979;&#8220;&#21152;&#24613;&#23457;&#26680;&#8221;&#12290;&#21487;&#24403;&#25105;&#28857;&#36827;&#39029;&#38754;&#26102;&#65292;&#31995;&#32479;&#21364;&#25552;&#31034;&#25105;&#8220;&#27809;&#26377;&#21487;&#21152;&#24613;&#30340;&#24212;&#29992;&#8221;&#12290;&#20180;&#32454;&#19968;&#26597;&#25165;&#21457;&#29616;&#65292;&#21407;&#26469;&#26159;&#22826;&#20037;&#27809;&#26356;&#26032; App&#65292;&#19994;&#21153;&#37117;&#29983;&#30095;&#20102;&#8212;&#8212;&#25105;&#30340;&#24212;&#29992;&#34429;&#28982;&#23436;&#25104;&#20102;&#25152;&#26377;&#21069;&#32622;&#27493;&#39588;&#65292;&#20294;&#25105;&#21387;&#26681;&#20799;&#23601;&#27809;&#28857;&#37027;&#20010;&#8220;&#25552;&#20132;&#20197;&#20379;&#23457;&#26680;&#8221;&#30340;&#25353;&#38062;&#12290;</p><p>&#34917;&#28857;&#25353;&#38062;&#27809;&#36807;&#20960;&#20010;&#23567;&#26102;&#65292;&#24212;&#29992;&#23601;&#39034;&#21033;&#19978;&#26550;&#20102;&#12290;</p><p>&#23613;&#31649;&#25105;&#36825;&#32431;&#23646;&#34394;&#24778;&#19968;&#22330;&#65292;&#20294;&#26368;&#36817;&#31038;&#21306;&#37324;&#20851;&#20110;&#8220;&#33529;&#26524;&#23457;&#26680;&#21464;&#24930;&#8221;&#30340;&#35752;&#35770;&#30830;&#23454;&#22810;&#20102;&#36215;&#26469;&#12290;&#24456;&#22810;&#20154;&#29468;&#27979;&#65292;&#36825;&#25110;&#35768;&#19982;&#36817;&#26399; Vibe Coding &#30340;&#30427;&#34892;&#26377;&#20851;&#12290;&#34429;&#28982;&#27809;&#26377;&#23448;&#26041;&#35777;&#23454;&#65292;&#20294; Vibe Coding &#30830;&#23454;&#22312;&#38477;&#20302;&#24320;&#21457;&#38376;&#27099;&#30340;&#21516;&#26102;&#65292;&#20063;&#22312;&#30701;&#26102;&#38388;&#20869;&#25918;&#22823;&#20102;&#24212;&#29992;&#25552;&#20132;&#30340;&#25968;&#37327;&#19982;&#36845;&#20195;&#39057;&#29575;&#65292;&#20174;&#32780;&#25226;&#21387;&#21147;&#20256;&#23548;&#21040;&#20102;&#23457;&#26680;&#29615;&#33410;&#12290;</p><p>&#20107;&#23454;&#19978;&#65292;&#33529;&#26524;&#26368;&#36817;&#20063;&#30830;&#23454;&#23545; Replit &#36825;&#31867;&#20801;&#35768;&#26222;&#36890;&#29992;&#25143;&#36827;&#34892; Vibe Coding &#30340;&#24212;&#29992;&#22312;&#23457;&#26680;&#19978;&#36827;&#34892;&#20102;&#21345;&#20851;&#12290;&#21363;&#20415;&#20801;&#35768;&#20854;&#19978;&#26550;&#65292;&#20063;&#35201;&#27714;&#22312;&#26680;&#24515;&#21151;&#33021;&#19978;&#20570;&#20986;&#22949;&#21327;&#12290;&#22312; Michael Tsai &#20851;&#20110;&#27492;&#20107;&#30340;<a href="https://mjtsai.com/blog/2026/03/20/updates-to-vibe-coding-apps-rejected-from-the-app-store/">&#21338;&#23458;&#20171;&#32461;</a>&#20013;&#65292;&#25105;&#30475;&#21040;&#20102;&#19968;&#26465;&#38750;&#24120;&#25935;&#38160;&#30340;&#30041;&#35328;&#65306;</p><blockquote><p>I thought the implication was that the vibe coding apps were being used to make the vibecoded apps that get submitted.</p><p>&#36825;&#20123; Vibe Coding &#24212;&#29992;&#27491;&#34987;&#29992;&#26469;&#25209;&#37327;&#21046;&#36896;&#37027;&#20123;&#25552;&#20132;&#19978;&#26550;&#30340;&#24212;&#29992;&#12290;</p></blockquote><p>AI &#19981;&#20165;&#22312;&#37325;&#22609;&#24320;&#21457;&#26041;&#24335;&#65292;&#20063;&#27491;&#22312;&#23545;&#24212;&#29992;&#23457;&#26680;&#19982;&#21457;&#34892;&#20307;&#31995;&#25552;&#20986;&#26032;&#30340;&#25361;&#25112;&#12290;&#26377;&#20154;&#25110;&#35768;&#20250;&#38382;&#65306;&#22914;&#26524;&#29992;&#39764;&#27861;&#25171;&#36133;&#39764;&#27861;&#65292;&#35753; AI &#20063;&#20840;&#38754;&#25509;&#31649;&#23457;&#26680;&#27969;&#31243;&#65292;&#20250;&#19981;&#20250;&#26356;&#39640;&#25928;&#65311;</p><p>&#33529;&#26524;&#30340;&#23457;&#26680;&#26426;&#21046;&#21521;&#26469;&#19981;&#22815;&#36879;&#26126;&#65292;&#26377;&#26102;&#20505;&#24212;&#29992;&#33021;&#21542;&#39034;&#21033;&#36807;&#23457;&#65292;&#29978;&#33267;&#21462;&#20915;&#20110;&#26159;&#21542;&#8220;&#30896;&#24039;&#8221;&#36935;&#21040;&#19968;&#20301;&#27668;&#21619;&#30456;&#25237;&#30340;&#23457;&#26680;&#21592;&#12290;&#20294;&#25442;&#20010;&#35282;&#24230;&#30475;&#65292;&#33267;&#23569;&#8220;&#20154;&#8221;&#20173;&#28982;&#26159;&#36825;&#36947;&#38450;&#32447;&#20013;&#26368;&#37325;&#35201;&#30340;&#19968;&#29615;&#12290;&#20154;&#30340;&#21028;&#26029;&#20250;&#20986;&#38169;&#65292;&#20063;&#20250;&#24102;&#26377;&#20559;&#24046;&#65292;&#20294;&#22312;&#38754;&#23545;&#35268;&#21017;&#26102;&#20173;&#20445;&#26377;&#19968;&#23450;&#30340;&#24377;&#24615;&#12290;</p><p>&#25105;&#19981;&#24076;&#26395;&#65292;&#26410;&#26469;&#30340;&#36719;&#20214;&#29983;&#24577;&#65292;&#36208;&#21521;&#8220;AI &#24320;&#21457; -&gt; AI &#23457;&#26680;&#8221;&#30340;&#38381;&#29615;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-127/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#21407;&#21019;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/cde-an-attempt-to-make-core-data-feel-more-like-modern-swift/?utm_source=fatbobman%20weekly%20issue%20128&amp;utm_medium=web">CDE&#65306;&#19968;&#27425;&#35753; Core Data &#26356;&#20687;&#29616;&#20195; Swift &#30340;&#23581;&#35797;</a></strong></h3><p>&#22312; <a href="https://fatbobman.com/zh/posts/why-i-am-still-thinking-about-core-data-in-2026/">&#19978;&#21608;&#30340;&#25991;&#31456;</a> &#20013;&#65292;&#25105;&#32842;&#20102;&#32842; Core Data &#22312;&#24403;&#19979;&#39033;&#30446;&#20013;&#30340;&#19968;&#20123;&#29616;&#23454;&#22788;&#22659;&#65306;&#23427;&#24182;&#27809;&#26377;&#28040;&#22833;&#65292;&#20063;&#20173;&#28982;&#26377;&#20854;&#29420;&#29305;&#20215;&#20540;&#65292;&#20294;&#23427;&#21644;&#29616;&#20195; Swift &#39033;&#30446;&#20043;&#38388;&#30340;&#38169;&#20301;&#24863;&#21364;&#36234;&#26469;&#36234;&#26126;&#26174;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;&#25105;&#24819;&#32487;&#32493;&#39034;&#30528;&#36825;&#20010;&#38382;&#39064;&#24448;&#19979;&#36208;&#65292;&#20171;&#32461;&#25105;&#30340;&#19968;&#20010;&#23454;&#39564;&#24615;&#39033;&#30446;&#65306;<a href="https://github.com/fatbobman/CoreDataEvolution">Core Data Evolution</a>&#65288;CDE&#65289;&#12290;</p><p>&#23427;&#19981;&#26159;&#19968;&#20010;&#21462;&#20195; Core Data &#30340;&#26032;&#26694;&#26550;&#65292;&#20063;&#19981;&#26159;&#35201;&#25226;&#24320;&#21457;&#32773;&#37325;&#26032;&#25289;&#22238;&#26087;&#25216;&#26415;&#12290;&#26356;&#20934;&#30830;&#22320;&#35828;&#65292;&#23427;&#26159;&#25105;&#38754;&#23545;&#36825;&#20123;&#38169;&#20301;&#26102;&#65292;&#32473;&#33258;&#24049;&#30340;&#19968;&#31181;&#22238;&#31572;&#65306;<strong>&#22914;&#26524;&#25105;&#20173;&#28982;&#35748;&#21487; Core Data &#30340;&#23545;&#35937;&#22270;&#27169;&#22411;&#12289;&#36801;&#31227;&#20307;&#31995;&#21644;&#25104;&#29087;&#36816;&#34892;&#26102;&#33021;&#21147;&#65292;&#37027;&#20040;&#33021;&#19981;&#33021;&#35753;&#23427;&#22312;&#29616;&#20195; Swift &#39033;&#30446;&#20013;&#20197;&#19968;&#31181;&#26356;&#33258;&#28982;&#30340;&#26041;&#24335;&#32487;&#32493;&#23384;&#22312;&#19979;&#21435;&#65311;</strong></p><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0128-01">&#23454;&#29616;&#24179;&#28369;&#30340; SwiftUI List &#23637;&#24320;&#21160;&#30011; (Expanding Animations in SwiftUI Lists)</a></strong></h3><p>&#24320;&#21457;&#32773;&#32463;&#24120;&#20250;&#36935;&#21040;&#19968;&#20010;&#21160;&#30011;&#31384;&#22659;&#65306;&#22312;&#21160;&#24577;&#35843;&#25972; <code>List</code> &#20013;&#26576;&#19968;&#34892;&#39640;&#24230;&#26102;&#65292;&#20869;&#23481;&#24182;&#19981;&#26159;&#24179;&#28369;&#23637;&#24320;&#65292;&#32780;&#26159;&#20276;&#38543;&#30528;&#26126;&#26174;&#30340;&#39640;&#24230;&#36339;&#21464;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/myridiphis">Pavel Zak</a> &#36890;&#36807;&#20960;&#20010;&#23454;&#39564;&#65292;&#23637;&#31034;&#20102;&#20026;&#20160;&#20040;&#24120;&#35265;&#30340; <code>if</code> &#26465;&#20214;&#28210;&#26579;&#12289;<code>withAnimation</code> &#29978;&#33267; <code>.transition</code> &#22312; <code>List</code> &#20013;&#37117;&#38590;&#20197;&#36798;&#21040;&#29702;&#24819;&#25928;&#26524;&#12290;&#23613;&#31649; <code>DisclosureGroup</code> &#36825;&#31181;&#20869;&#24314;&#26041;&#26696;&#21487;&#20197;&#36798;&#21040;&#39044;&#26399;&#65292;&#20294; Pavel &#36824;&#26159;&#32473;&#20986;&#20102;&#19968;&#20010;&#26356;&#28789;&#27963;&#30340;&#26041;&#26696;&#65306;&#22522;&#20110; <code>Animatable</code> &#19982;&#35270;&#22270;&#23610;&#23544;&#27979;&#37327;&#30340;&#23454;&#29616;&#26041;&#24335;&#65292;&#35753; <code>List</code> &#22312;&#21160;&#30011;&#36807;&#31243;&#20013;&#22987;&#32456;&#33719;&#24471;&#36830;&#32493;&#21464;&#21270;&#30340;&#39640;&#24230;&#65292;&#20174;&#32780;&#23454;&#29616;&#24179;&#28369;&#30340;&#23637;&#24320;&#21160;&#30011;&#12290;</p><blockquote><p><code>List</code>&#65288;&#24213;&#23618;&#20173;&#28982;&#26159; UIKit/AppKit &#30340;&#21015;&#34920;&#23454;&#29616;&#65289;&#26377;&#19968;&#20010;&#26680;&#24515;&#29305;&#28857;&#65306;&#23427;&#38656;&#35201;&#22312;&#24067;&#23616;&#38454;&#27573;&#23601;&#25343;&#21040;&#27599;&#19968;&#34892;&#30340;&#8220;&#30830;&#23450;&#39640;&#24230;&#8221;&#12290;&#22240;&#27492;&#65292;&#23545;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#19981;&#35201;&#35753; <code>List</code> &#38754;&#23545;&#32467;&#26500;&#21464;&#21270;&#65292;&#32780;&#26159;&#20687; <code>DisclosureGroup</code> &#37027;&#26679;&#65292;&#23558;&#8220;&#31163;&#25955;&#21464;&#21270;&#8221;&#36716;&#21270;&#20026;&#8220;&#36830;&#32493;&#21464;&#21270;&#8221;&#65292;&#25345;&#32493;&#25552;&#20379;&#21487;&#25554;&#20540;&#30340;&#39640;&#24230;&#20540;&#12290;&#36825;&#20063;&#26159;&#22312;&#22788;&#29702;&#21160;&#30011;&#24322;&#24120;&#26102;&#65292;&#24320;&#21457;&#32773;&#24120;&#24120;&#20511;&#21161; <code>Animatable</code> &#21327;&#35758;&#30340;&#21407;&#22240;&#12290;&#24819;&#36827;&#19968;&#27493;&#20102;&#35299;&#35813;&#21327;&#35758;&#30340;&#21407;&#29702;&#19982;&#36866;&#29992;&#22330;&#26223;&#65292;&#21487;&#20197;&#38405;&#35835;&#25105;&#20043;&#21069;&#30340;&#19968;&#31687;<a href="https://fatbobman.com/zh/posts/animatable-protocol-taming-unruly-swiftui-animation/">&#25991;&#31456;</a>&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-02">&#22914;&#20309;&#26356;&#22909;&#30340;&#36866;&#37197; iPadOS &#30340;&#24067;&#23616; (SwiftUI iPad Adaptive Layout: Five Layers for Apps That Don&#8217;t Break in Split View)</a></strong></h3><p>&#23613;&#31649;&#33529;&#26524;&#24378;&#21270; iPadOS &#22810;&#31383;&#21475;&#33021;&#21147;&#30340;&#21021;&#34935;&#26159;&#22909;&#30340;&#65292;&#20294;&#36825;&#20063;&#26174;&#33879;&#25552;&#21319;&#20102;&#24320;&#21457;&#32773;&#22312;&#24067;&#23616;&#36866;&#37197;&#19978;&#30340;&#22797;&#26434;&#24230;&#12290;&#24212;&#29992;&#21487;&#33021;&#20197;&#31867; iPhone&#12289;&#20256;&#32479; iPad &#20840;&#23631;&#12289;Stage Manager &#31383;&#21475;&#31561;&#22810;&#31181;&#27169;&#24335;&#21576;&#29616;&#12290;<a href="https://www.linkedin.com/in/wesmatlock/">Wesley Matlock</a> &#25351;&#20986;&#65292;&#20165;&#20381;&#36182; <code>horizontalSizeClass</code> &#36827;&#34892;&#24067;&#23616;&#21028;&#26029;&#22312;&#23454;&#38469;&#29615;&#22659;&#20013;&#24448;&#24448;&#26159;&#19981;&#22815;&#30340;&#12290;&#24320;&#21457;&#32773;&#38656;&#35201;&#32467;&#21512;&#23481;&#22120;&#23610;&#23544;&#19982; size class &#26500;&#24314;&#26356;&#32454;&#31890;&#24230;&#30340; <code>LayoutEnvironment</code>&#65292;&#24182;&#22312;&#26681;&#35270;&#22270;&#20013;&#32479;&#19968;&#23436;&#25104;&#24067;&#23616;&#20998;&#25903;&#20915;&#31574;&#65307;&#21516;&#26102;&#20511;&#21161; <code>ViewThatFits</code> &#31561;&#26426;&#21046;&#65292;&#35753;&#31995;&#32479;&#22522;&#20110;&#30495;&#23454;&#32422;&#26463;&#36873;&#25321;&#26368;&#21512;&#36866;&#30340;&#30028;&#38754;&#24418;&#24335;&#65292;&#32780;&#19981;&#26159;&#30001;&#24320;&#21457;&#32773;&#39044;&#20808;&#20551;&#35774;&#35774;&#22791;&#31867;&#22411;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-03">RGB HDR Gain Map + ImageIO &#20013;&#30340;&#20351;&#29992;&#38519;&#38449; (Pitfalls and workarounds when dealing with RGB HDR Gain Map using ImageIO)</a></strong></h3><p>iOS 18 &#20013;&#24341;&#20837;&#30340;&#22522;&#20110; ISO 21496-1 &#26631;&#20934;&#30340; RGB HDR Gain Map&#65292;&#35753;&#24320;&#21457;&#32773;&#22312;&#22788;&#29702; HDR &#22270;&#20687;&#26102;&#33719;&#24471;&#20102;&#26356;&#39640;&#30340;&#34920;&#29616;&#21147;&#65292;&#20294;&#22312;&#23454;&#38469;&#24212;&#29992;&#20013;&#20063;&#26356;&#23481;&#26131;&#36393;&#22353;&#65306;&#23613;&#31649;&#30456;&#20851;&#25509;&#21475;&#33021;&#22815;&#36820;&#22238;&#36741;&#21161;&#25968;&#25454;&#23383;&#20856;&#65292;&#20294;&#22312; RGB Gain Map &#22330;&#26223;&#19979;&#21364;&#32570;&#22833;&#20102;&#23454;&#38469;&#30340;&#20301;&#22270;&#25968;&#25454;&#65288;<code>kCGImageAuxiliaryDataInfoData</code>&#65289;&#65292;&#23548;&#33268;&#21518;&#32493;&#22788;&#29702;&#26080;&#27861;&#32487;&#32493;&#12290;&#25442;&#21477;&#35805;&#35828;&#65292;ImageIO &#22312;&#36825;&#19968;&#22330;&#26223;&#19979;&#29978;&#33267;&#26080;&#27861;&#23436;&#25972;&#35835;&#21462;&#33258;&#36523;&#29983;&#25104;&#30340;&#20869;&#23481;&#12290;<a href="https://x.com/JuniperPhoton">Weichao Deng</a> &#25552;&#20986;&#20102;&#19968;&#31181;&#28151;&#21512;&#26041;&#26696;&#65306;&#20351;&#29992; Core Image &#35835;&#21462; Gain Map &#30340; <code>CIImage</code>&#65292;&#25163;&#21160;&#28210;&#26579;&#20026; Bitmap Data&#65292;&#34917;&#40784;&#32570;&#22833;&#23383;&#27573;&#21518;&#65292;&#20877;&#36890;&#36807; ImageIO &#20889;&#22238;&#25991;&#20214;&#12290;&#23545;&#20110;&#27491;&#22312;&#24320;&#21457;&#30456;&#26426;&#25110;&#22270;&#20687;&#22788;&#29702;&#31867;&#24212;&#29992;&#12289;&#38656;&#35201;&#22788;&#29702; HDR Gain Map &#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#31687;&#25991;&#31456;&#25110;&#35768;&#33021;&#24110;&#20320;&#30465;&#19979;&#19981;&#23569;&#35843;&#35797;&#26102;&#38388;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-04">Swift &#31038;&#21306;&#30340;&#32593;&#32476;&#24895;&#26223; (A Vision for Networking in Swift)</a></strong></h3><p><a href="https://www.swift.org/ecosystem-steering-group/">Swift Ecosystem Steering Group</a> &#19978;&#21608;&#21457;&#24067;&#20102;&#19968;&#20221;&#20851;&#20110;&#32593;&#32476;&#32534;&#31243;&#30340;&#24895;&#26223;&#25991;&#26723;&#65292;&#35752;&#35770;&#20102; Swift &#32593;&#32476;&#29983;&#24577;&#24403;&#21069;&#30340;&#22256;&#22659;&#20197;&#21450;&#26410;&#26469;&#21487;&#33021;&#30340;&#21457;&#23637;&#26041;&#21521;&#12290;</p><p>&#25991;&#26723;&#25351;&#20986;&#65292;Swift &#22312;&#32593;&#32476;&#39046;&#22495;&#23384;&#22312;&#26126;&#26174;&#30340;&#20998;&#35010;&#65306;<code>URLSession</code>&#12289;SwiftNIO &#19982; Network.framework &#24182;&#23384;&#65292;&#21151;&#33021;&#37325;&#21472;&#21364;&#20114;&#19981;&#20860;&#23481;&#65292;&#24320;&#21457;&#32773;&#24448;&#24448;&#38656;&#35201;&#22312;&#39033;&#30446;&#26089;&#26399;&#23601;&#25276;&#27880;&#26576;&#19968;&#22871;&#25216;&#26415;&#26632;&#65292;&#19988;&#20999;&#25442;&#25104;&#26412;&#26497;&#39640;&#12290;&#19982;&#27492;&#21516;&#26102;&#65292;&#29616;&#26377;&#30340;&#22823;&#22810;&#25968;&#32593;&#32476; API &#37117;&#35806;&#29983;&#20110; Swift Concurrency &#20043;&#21069;&#65292;&#20381;&#36182; completion handler&#12289;delegate &#25110;&#21709;&#24212;&#24335;&#27169;&#24335;&#65292;&#19982;&#29616;&#20195; Swift &#30340;&#35821;&#35328;&#29305;&#24615;&#23384;&#22312;&#26126;&#26174;&#33073;&#33410;&#12290;</p><p>&#25991;&#26723;&#25552;&#20986;&#30340;&#26041;&#21521;&#26159;&#26500;&#24314;&#19968;&#22871;&#20998;&#23618;&#32479;&#19968;&#30340;&#32593;&#32476;&#26550;&#26500;&#65306;&#24213;&#23618;&#20849;&#20139; I/O &#21407;&#35821;&#19982;&#32531;&#20914;&#31867;&#22411;&#65292;&#20013;&#38388;&#23618;&#22797;&#29992; TLS&#12289;HTTP/1.1/2/3&#12289;QUIC&#12289;WebSocket &#31561;&#21327;&#35758;&#23454;&#29616;&#65292;&#39030;&#23618;&#25552;&#20379;&#20197; async/await &#21644;&#32467;&#26500;&#21270;&#24182;&#21457;&#20026;&#22522;&#30784;&#30340;&#23458;&#25143;&#31471;&#19982;&#26381;&#21153;&#31471; API&#12290;&#24050;&#26377;&#30340; <code>swift-http-types</code>&#65288;&#23450;&#20041;&#20102; <code>HTTPRequest</code> / <code>HTTPResponse</code>&#65289;&#21487;&#20197;&#35270;&#20026;&#36825;&#19968;&#24605;&#36335;&#30340;&#26089;&#26399;&#23454;&#36341;&#12290;&#25991;&#26723;&#21516;&#26102;&#24378;&#35843;&#65292;SwiftNIO &#21644; Network.framework &#19981;&#20250;&#34987;&#24223;&#24323;&#65292;&#32780;&#26159;&#23558;&#36880;&#27493;&#21521;&#32479;&#19968;&#30340;&#24213;&#23618;&#21407;&#35821;&#25910;&#25947;&#12290;</p><blockquote><p>&#35813;&#24895;&#26223;&#30446;&#21069;&#27491;&#22312;&#24449;&#38598;&#31038;&#21306;&#21453;&#39304;&#65292;&#21487;&#20197;<a href="https://forums.swift.org/t/prospective-vision-networking/">&#22312;&#27492;&#21442;&#19982;</a>&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-05">&#35753;&#20320;&#30340; iOS &#39033;&#30446;&#26356;&#36866;&#21512; AI &#21327;&#20316; (Preparing Your iOS Codebase for AI Agents)</a></strong></h3><p>&#38543;&#30528; AI agent&#65288;&#22914; Codex&#12289;Claude Code &#31561;&#65289;&#36880;&#28176;&#21442;&#19982;&#21040;&#23454;&#38469;&#24320;&#21457;&#27969;&#31243;&#20013;&#65292;&#38382;&#39064;&#24320;&#22987;&#20174;&#8220;&#22914;&#20309;&#20351;&#29992; AI &#20889;&#20195;&#30721;&#8221;&#36716;&#21521;&#8220;&#22914;&#20309;&#35753;&#20195;&#30721;&#24211;&#26412;&#36523;&#36866;&#21512; AI &#21327;&#20316;&#8221;&#12290;<a href="https://hachyderm.io/@IronHam">Hesham Salman</a> &#20174;&#24037;&#31243;&#23454;&#36341;&#30340;&#35282;&#24230;&#65292;&#31995;&#32479;&#24615;&#22320;&#25506;&#35752;&#20102;&#36825;&#19968;&#36716;&#21464;&#12290;</p><p>Hesham &#25351;&#20986;&#65292;&#30456;&#36739;&#20110;&#25552;&#31034;&#35789;&#65292;AI &#26356;&#20381;&#36182;&#26174;&#24335;&#22865;&#32422;&#12290;&#36890;&#36807;&#20998;&#23618;&#30340; <code>AGENTS.md</code> &#25991;&#26723;&#26126;&#30830;&#39033;&#30446;&#32422;&#23450;&#19982;&#34892;&#20026;&#35268;&#21017;&#65292;&#20351;&#29992; Makefile &#23558;&#26500;&#24314;&#12289;&#27979;&#35797;&#31561;&#25805;&#20316;&#32479;&#19968;&#20026;&#21487;&#25191;&#34892;&#20837;&#21475;&#65292;&#24182;&#36890;&#36807;&#8220;skills&#8221;&#23558;&#22810;&#27493;&#39588;&#27969;&#31243;&#32534;&#30721;&#20026;&#21487;&#22797;&#29992;&#30340;&#25191;&#34892;&#26041;&#27861;&#65292;&#20174;&#32780;&#23558;&#21407;&#26412;&#38544;&#24615;&#30340;&#24037;&#31243;&#30693;&#35782;&#32467;&#26500;&#21270;&#22320;&#23884;&#20837;&#21040;&#20195;&#30721;&#24211;&#20013;&#12290;</p><blockquote><p>&#25991;&#31456;&#20013;&#26377;&#19968;&#20010;&#32454;&#33410;&#20196;&#20154;&#21360;&#35937;&#28145;&#21051;&#65306;&#20316;&#32773;&#35201;&#27714; agent &#22312;&#21457;&#29616;&#26410;&#35760;&#24405;&#30340;&#32422;&#23450;&#26102;&#20027;&#21160;&#26356;&#26032;&#25991;&#26723;&#65292;&#21516;&#26102;&#21152;&#20837;&#20102;&#19968;&#26465;&#24378;&#32422;&#26463;&#8212;&#8212;<strong>&#27599;&#27425;&#20462;&#25913;&#37117;&#24517;&#39035;&#35753;&#25991;&#26723;&#26356;&#30701;&#25110;&#26356;&#26377;&#29992;</strong>&#12290;&#36825;&#19968;&#33258;&#32500;&#25252;&#26426;&#21046;&#26082;&#38450;&#27490;&#25991;&#26723;&#33104;&#21270;&#65292;&#20063;&#36991;&#20813;&#25991;&#26723;&#33192;&#32960;&#65292;&#26159;&#19968;&#20010;&#20540;&#24471;&#20511;&#37492;&#30340;&#24179;&#34913;&#31574;&#30053;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-06">iOS Conf SG 2026 &#35270;&#39057;</a></strong></h3><p>2026 &#24180; iOS Conf SG &#20110; 1 &#26376; 21 &#26085;&#33267; 23 &#26085;&#22312;&#26032;&#21152;&#22369;&#20030;&#34892;&#65292;&#26469;&#33258;&#20840;&#29699;&#30340;&#25968;&#21313;&#20301;&#24320;&#21457;&#32773;&#19982;&#20869;&#23481;&#21019;&#20316;&#32773;&#20998;&#20139;&#20102;&#21508;&#33258;&#22312;&#33529;&#26524;&#29983;&#24577;&#24320;&#21457;&#20013;&#30340;&#32463;&#39564;&#19982;&#24605;&#32771;&#12290;&#19978;&#21608;&#65292;&#23448;&#26041;&#25918;&#20986;&#20102;&#26412;&#23626;&#30340;&#20840;&#37096;&#28436;&#35762;&#35270;&#39057;&#12290;&#25105;&#20063;&#26377;&#24184;&#21442;&#19982;&#20102;&#20854;&#20013;&#30340;&#19968;&#22330;&#20998;&#20139;&#65292;&#24863;&#20852;&#36259;&#30340;&#35835;&#32773;&#21487;&#20197;&#25353;&#38656;&#25361;&#36873;&#35266;&#30475;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0128-07">TaskGate&#65306;&#35299;&#20915; Actor &#37325;&#20837;&#30340;&#24037;&#20855;</a></strong></h3><p>&#23613;&#31649; actor &#22312;&#24456;&#22823;&#31243;&#24230;&#19978;&#36991;&#20813;&#20102;&#25968;&#25454;&#31454;&#20105;&#65292;&#20294;&#20854;&#21487;&#37325;&#20837;&#65288;reentrancy&#65289;&#29305;&#24615;&#20063;&#24847;&#21619;&#30528;&#65292;&#19968;&#20123;&#30475;&#20284;&#20018;&#34892;&#30340;&#36923;&#36753;&#22312; <code>await</code> &#20043;&#21518;&#21487;&#33021;&#22833;&#21435;&#21407;&#26377;&#30340;&#25191;&#34892;&#39034;&#24207;&#65292;&#36827;&#32780;&#36896;&#25104;&#37325;&#22797;&#25191;&#34892;&#25110;&#29366;&#24577;&#19981;&#19968;&#33268;&#12290;</p><p><a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#32534;&#20889;&#30340; TaskGate &#27491;&#26159;&#20026;&#36825;&#31867;&#22330;&#26223;&#20934;&#22791;&#30340;&#12290;&#23427;&#25552;&#20379;&#20102; <code>AsyncGate</code> &#21644; <code>AsyncRecursiveGate</code> &#20004;&#31181;&#26426;&#21046;&#65292;&#29992;&#26469;&#20026; actor &#20869;&#37096;&#30340;&#24322;&#27493;&#20195;&#30721;&#23450;&#20041;&#8220;&#20020;&#30028;&#21306;&#8221;&#65292;&#30830;&#20445;&#21516;&#19968;&#26102;&#38388;&#21482;&#26377;&#19968;&#20010;&#20219;&#21153;&#33021;&#22815;&#36827;&#20837;&#30456;&#20851;&#36923;&#36753;&#12290;&#19982;&#20256;&#32479;&#38145;&#19981;&#21516;&#30340;&#26159;&#65292;&#23427;&#20801;&#35768;&#22312;&#25345;&#26377; gate &#30340;&#21516;&#26102;&#23433;&#20840;&#22320;&#25191;&#34892;&#24322;&#27493;&#35843;&#29992;&#12290;</p><blockquote><p>Matt &#26126;&#30830;&#25351;&#20986;&#65306;&#35813;&#24211;&#24182;&#19981;&#26159;&#29992;&#26469;&#26367;&#20195;&#33391;&#22909;&#30340; actor &#35774;&#35745;&#65292;&#32780;&#26356;&#20687;&#26159;&#19968;&#31181;&#22312;&#20854;&#20182;&#25163;&#27573;&#19981;&#22815;&#21512;&#36866;&#26102;&#30340;&#34917;&#20805;&#24037;&#20855;&#12290;&#24211;&#20013;&#23558; gate &#21051;&#24847;&#35774;&#35745;&#20026; non-Sendable&#65292;&#20197;&#38477;&#20302;&#36328; actor &#35823;&#29992;&#30340;&#39118;&#38505;&#12290;&#22914;&#26524;&#20320;&#27491;&#22312;&#22788;&#29702; actor &#37325;&#20837;&#23548;&#33268;&#30340;&#29366;&#24577;&#19968;&#33268;&#24615;&#38382;&#39064;&#65292;&#25110;&#24076;&#26395;&#26356;&#28145;&#20837;&#29702;&#35299; Swift &#24182;&#21457;&#20013;&#30340;&#36825;&#19968;&#34180;&#24369;&#29615;&#33410;&#65292;&#36825;&#20010;&#24211;&#20197;&#21450; Matt &#22312; Reddit &#20013;&#30340; <a href="https://www.reddit.com/r/swift/comments/1rx9aii/taskgate_library_for_managing_actor_reentrancy/">&#35752;&#35770;</a> &#37117;&#20540;&#24471;&#19968;&#30475;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0128-08">pico-bare-swift</a></strong></h3><p>&#33529;&#26524;&#24403;&#24180;&#21019;&#24314; Swift &#26102;&#65292;&#23545;&#23427;&#30340;&#26399;&#24453;&#26174;&#28982;&#19981;&#21482;&#26159;&#29992;&#20110;&#24320;&#21457; App&#65292;&#32780;&#26159;&#24076;&#26395;&#23427;&#26368;&#32456;&#25104;&#38271;&#20026;&#19968;&#38376;&#36866;&#29992;&#20110;&#19981;&#21516;&#39046;&#22495;&#12289;&#19981;&#21516;&#23618;&#27425;&#30340;&#36890;&#29992;&#35821;&#35328;&#12290;&#19981;&#36807;&#65292;&#22312;&#30456;&#24403;&#38271;&#19968;&#27573;&#26102;&#38388;&#37324;&#65292;Swift &#22312;&#37027;&#20123;&#20256;&#32479;&#19978;&#30001; C/C++ &#25110; Rust &#20027;&#23548;&#30340;&#39046;&#22495;&#20013;&#65292;&#22987;&#32456;&#27809;&#26377;&#23637;&#29616;&#20986;&#36275;&#22815;&#30340;&#23384;&#22312;&#24863;&#12290;<a href="https://hachyderm.io/@kishikawakatsumi">kishikawa katsumi</a> &#36890;&#36807;&#36825;&#20010;&#31034;&#20363;&#39033;&#30446;&#23637;&#31034;&#20102;&#21478;&#19968;&#31181;&#21487;&#33021;&#65306;&#20511;&#21161; Embedded Swift&#65292;Swift &#24050;&#32463;&#24320;&#22987;&#20855;&#22791;&#36827;&#20837;&#23884;&#20837;&#24335;&#24320;&#21457;&#22330;&#26223;&#30340;&#33021;&#21147;&#12290;</p><blockquote><p>&#36825;&#20010;&#39033;&#30446;&#26368;&#21560;&#24341;&#25105;&#30340;&#22320;&#26041;&#65292;&#22312;&#20110;&#23427;&#23558;&#19968;&#20214;&#21407;&#26412;&#24102;&#26377;&#26126;&#26174;&#8220;&#24213;&#23618;/C &#35821;&#35328;&#19987;&#23646;&#8221;&#33394;&#24425;&#30340;&#20107;&#24773;&#65292;&#32452;&#32455;&#25104;&#20102;&#19968;&#26465;&#30456;&#24403;&#28165;&#26224;&#30340;&#23398;&#20064;&#36335;&#24452;&#12290;&#23427;&#19981;&#20165;&#26159;&#8220;&#29992; Swift &#28857;&#20142;&#19968;&#20010; LED&#8221;&#65292;&#32780;&#26159;&#23558;&#21551;&#21160;&#20195;&#30721;&#12289;&#21521;&#37327;&#34920;&#12289;&#20869;&#23384;&#21021;&#22987;&#21270;&#12289;&#23492;&#23384;&#22120;&#35775;&#38382;&#65292;&#20197;&#21450; UART&#12289;PWM&#12289;I2C&#12289;SSD1306 OLED &#31561;&#22806;&#35774;&#39537;&#21160;&#19968;&#24182;&#32435;&#20837; Swift &#30340;&#23454;&#29616;&#33539;&#22260;&#20043;&#20013;&#12290;&#26576;&#31181;&#31243;&#24230;&#19978;&#65292;<strong>&#36825;&#31867;&#39033;&#30446;&#30340;&#24847;&#20041;&#19981;&#22312;&#20110;&#8220;&#26159;&#21542;&#23454;&#29992;&#8221;&#65292;&#32780;&#22312;&#20110;&#23427;&#37325;&#26032;&#21010;&#23450;&#20102; Swift &#30340;&#33021;&#21147;&#36793;&#30028;</strong>&#12290;</p></blockquote>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #127]]></title><description><![CDATA[Apple at 50 and Me at 51]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-127</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-127</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 16 Mar 2026 12:04:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!6zhq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6zhq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6zhq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 424w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 848w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 1272w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6zhq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp" width="1182" height="607" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:607,&quot;width&quot;:1182,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14120,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/191012253?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6zhq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 424w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 848w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 1272w, https://substackcdn.com/image/fetch/$s_!6zhq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6cdd317-b63f-4003-a4d7-c9d218007685_1182x607.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Apple at 50 and Me at 51</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-127/">Read on web &#8594;</a></p><p>In less than half a month, Apple will celebrate its 50th birthday. Tim Cook has also published <a href="https://www.apple.com/50-years-of-thinking-different/">a short piece</a> paying tribute to the journey of the past half-century. However, because of Apple&#8217;s image as a constant trendsetter, many people don&#8217;t realize that it is now a veritable elder statesman in the IT industry. Among the tech giants of its age, very few remain at the top-tier table today.</p><p>As a tech enthusiast who is only one year older than Apple, from the Apple II to today&#8217;s iPhone and MacBook, Apple&#8217;s products have accompanied me through most of my life. Strictly speaking, I wouldn&#8217;t call myself a hardcore Apple fan&#8212;I don&#8217;t feel regret if I don&#8217;t buy a new product on day one, I rarely stay up late to watch keynotes anymore, and I&#8217;m even less familiar with the exact specs of their newest devices. But looking back, at every major milestone in my life, I have naturally chosen Apple products, and in recent years, I have become a part of the Apple developer ecosystem.</p><p>To be honest, I haven&#8217;t entirely figured out where Apple&#8217;s enduring appeal to me comes from. Is it because I started using its products so early on? Is it its innovation, user experience, and overall vibe? Or is it Steve Jobs&#8217; charisma? Truth be told, my choice today is driven purely by habit and instinct, much like the unspoken understanding between old friends&#8212;it simply no longer requires any specific reason.</p><p>Of course, Apple&#8217;s path of growth hasn&#8217;t always been smooth sailing; there have been valleys along the way. But one thing must be acknowledged: its corporate positioning over the past 50 years has remained almost completely unchanged&#8212;to create powerful tools for individuals and society. Even in the latest wave of AI, where Apple seems to have lost the first-mover advantage, as the core player connecting people to the digital world in that &#8220;last centimeter,&#8221; it still holds the capital to remain at the center of the table in the AI era. After all, we live in a physical world, and we need tangible hardware and personalized services to truly enjoy the fruits of technological progress.</p><p>Apple at 50 might offer an inspiration to other companies: rather than imitating its &#8220;cool&#8221; and &#8220;innovative&#8221; exterior, it is better to learn from its focus and persistence. Becoming a long-term companion to its users is perhaps the true secret to its success.</p><p>In all likelihood, ten years from now, when Apple turns 60 and I turn 61, I will still be using a Mac.</p><p>Happy Birthday, Apple!</p><p><a href="https://fatbobman.com/en/weekly/issue-126/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-boltai">Native AI chat app &#8212; ultra-fast, privacy-first, 100+ pro features</a></strong></h3><p>One native app, 100+ AI models on Mac, iOS, and Android. Fast, keyboard-driven, no Electron. 25% off for a limited time with code <code>FATBOBMAN25</code>.</p><p><strong><a href="https://l.fatbobman.com/sb-boltai">&#9889;&#65039; Get BoltAI &#8212; 25% off -&gt;</a></strong></p><div><hr></div><h2><strong>Original</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/why-i-am-still-thinking-about-core-data-in-2026/?utm_source=fatbobman%20weekly%20issue%20127&amp;utm_medium=web">Why I&#8217;m Still Thinking About Core Data in 2026</a></strong></h3><p>By 2026, Core Data has been around for 21 years. While many developers still use it, in modern Swift projects it increasingly feels like a relic of an earlier era. Concurrency still relies on layers of <code>perform</code> calls, model declarations are filled with boilerplate, and string-based predicates are always ready to trip you up. This article is not a defense of Core Data, nor an attempt to persuade new developers to adopt it. Instead, it&#8217;s more of a problem inventory: why do some developers still choose to stick with Core Data in 2026, and if we continue using it, what are the real issues we need to address today?</p><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0127-01">Fortify Your App: Essential Strategies to Strengthen Security Q&amp;A</a></strong></h3><p>During a security-focused event hosted by Apple&#8217;s Developer Center, several Apple engineers spent nearly six hours discussing application security and memory safety, covering topics such as modern security challenges and the defensive technologies available across Apple platforms. <a href="https://x.com/AntonGubarenko">Anton Gubarenko</a> compiled and organized a large portion of the developer Q&amp;A from the session. The discussion touches on topics such as evaluating the security of third-party libraries, risks when storing data with UserDefaults or plist files, best practices for Keychain and file protection, the safe use of Swift <code>unsafe</code> APIs, and enabling Enhanced Security capabilities in Xcode. For developers interested in understanding Apple&#8217;s platform security model and practical recommendations, this is a dense and valuable collection of insights, many of them coming directly from Apple engineers.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-02">Faster iOS Subscriptions with ASC CLI and RevenueCat MCP</a></strong></h3><p>Adding subscription support to an app isn&#8217;t particularly difficult, but configuring everything across both App Store Connect and RevenueCat can be surprisingly tedious. <a href="https://x.com/rudrank">Rudrank Riyam</a> introduces a more efficient approach: using the <a href="https://github.com/rudrankriyam/App-Store-Connect-CLI">ASC CLI</a> to create App Store Connect subscription products directly from the terminal, and then letting an AI agent configure the corresponding entitlements, offerings, and paywalls through RevenueCat&#8217;s MCP Server. This workflow effectively moves the entire setup process from manual dashboard interactions into a CLI + AI agent automation pipeline.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-03">JetBrains Swift Developers Survey</a></strong></h3><p>JetBrains recently released a survey aimed at Swift developers, inviting them to share the tools they use, their development workflows, and the pain points they encounter in the Swift ecosystem. Although JetBrains has not explained the specific purpose of the survey, the community has already started to speculate that it may be related to a renewed evaluation of Swift development tooling support.</p><p>After JetBrains discontinued AppCode in 2022, most Swift developers returned to an Xcode-centric toolchain. This new survey has sparked some discussion: some developers hope JetBrains might revisit Swift tooling, while others suspect the effort could be more closely related to Kotlin Multiplatform or Swift build tooling. If you&#8217;re interested in the future direction of Swift development tools, you might want to take part in the survey.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-04">How Well Can You Detect a Swift Protocol Without the Compiler?</a></strong></h3><p>Protocols are everywhere in Swift projects, but how reliably can you determine whether a Swift file defines or references a protocol without compiling the project or resolving its dependencies? In this article, <a href="https://x.com/budo_coder">Xiangyu Sun</a> evaluates a variety of detection strategies, including SourceKit/LSP queries, SwiftSyntax AST parsing, simple keyword regex matching, and heuristic signals such as <code>extension Foo: Bar</code> or the <code>any</code>/<code>some</code> prefixes. Each method is analyzed in terms of accuracy and applicability.</p><p>One particularly interesting finding is that <strong>simple naming conventions can dramatically improve static analysis accuracy</strong>. If a team consistently uses a <code>*Protocol</code> suffix for protocol types (for example, <code>PaymentServiceProtocol</code>), many otherwise ambiguous heuristics become far more reliable. The author also explores how this convention can benefit AI-assisted development workflows: by pre-classifying protocol files before sending code to an LLM, it becomes possible to reduce token usage and improve analysis efficiency &#8212; an insightful perspective for teams experimenting with AI-driven tooling.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-05">What you should know before Migrating from GCD to Swift Concurrency</a></strong></h3><p>Migrating from GCD to Swift Concurrency is not merely a matter of replacing syntax. In this article, <a href="https://x.com/soumya_mahunt">Soumya Ranjan Mahunt</a> highlights several important differences between the two concurrency models. Swift Concurrency differs from GCD in task scheduling, execution ordering, and concurrency semantics &#8212; differences that can introduce subtle data races or difficult-to-reproduce runtime issues during migration if not properly considered.</p><p>For example, <code>Task</code> scheduling does not guarantee the same FIFO execution order as GCD, and <code>actor</code> should not be viewed as a direct replacement for <code>DispatchQueue</code>, since task priorities and scheduling strategies can influence execution behavior. The article also discusses practical migration pitfalls, such as the lack of a direct equivalent to <code>DispatchGroup</code> in Swift Concurrency, and compatibility issues that may arise when using <code>assumeIsolated</code> on older system versions.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-06">A 9-Step Framework for Choosing the Right Agent Skill</a></strong></h3><p>As AI agents become increasingly integrated into development workflows, designing the right &#8220;skills&#8221; (tools or capabilities) for those agents is emerging as a new engineering challenge. <a href="https://x.com/twannl">Antoine van der Lee</a> proposes a nine-step framework to help determine when it actually makes sense to implement a dedicated agent skill.</p><p>As Antoine points out, not every task should be delegated directly to an LLM, and not every capability needs to become an agent tool. The framework evaluates factors such as task determinism, execution cost, reusability, and security considerations, providing a structured way to reason about when and how to extend an AI agent&#8217;s capabilities.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0127-07">DataStoreKit</a></strong></h3><p>This is a particularly interesting open-source project developed by <a href="https://www.asymbas.com/">Anferne Pineda</a>. It leverages SwiftData&#8217;s custom store capability to re-implement a SQLite-backed persistence engine while preserving SwiftData&#8217;s higher-level developer experience. The project maps SwiftData models, predicates, and queries to SQLite schemas, SQL execution, snapshots, and persistent history management.</p><p>DataStoreKit also introduces several noteworthy capabilities. For example, it supports predicate queries on collection types such as arrays and dictionaries by mapping them to JSON structures stored in SQLite. It also exposes a SQL passthrough layer, allowing developers to bypass <code>#Predicate</code> when necessary and directly execute SQLite queries or maintenance operations.</p><p>This is one of the few projects that explores SwiftData&#8217;s <code>DataStore</code> extensibility at significant depth, demonstrating how SwiftData can function as a data abstraction layer rather than a complete persistence engine. The project is still in an early stage and its APIs and capabilities may evolve, but it is already well worth watching.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-08">Playwright for Swift</a></strong></h3><p>Developed by <a href="https://x.com/m1guelpf">Miguel Piedrafita</a>, <code>swift-playwright</code> brings the mature browser automation capabilities of <a href="https://playwright.dev/">Playwright</a> into the Swift ecosystem. Developers can control Chromium, Firefox, and WebKit directly from Swift code to perform tasks such as page navigation, clicking, form input, screenshots, and JavaScript execution. The API design also closely mirrors the official Playwright interface.</p><p>Under the hood, the project does not re-implement a browser automation framework. Instead, it wraps the Playwright protocol on the Swift side while continuing to communicate with browsers through the Node.js Playwright driver. For developers interested in building testing tools, CLI utilities, or even AI agents using Swift, this project offers a compelling entry point.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-127?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-127?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>50 &#23681;&#30340;&#33529;&#26524;&#21644; 51 &#23681;&#30340;&#25105;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-127/">&#32593;&#39029;&#29256;</a></strong></p><p>&#20877;&#26377;&#19981;&#21040;&#21322;&#20010;&#26376;&#65292;Apple &#23558;&#36814;&#26469; 50 &#23681;&#29983;&#26085;&#12290;Tim Cook &#20063;&#21457;&#34920;&#20102;<a href="https://www.apple.com/50-years-of-thinking-different/">&#19968;&#31687;&#30701;&#25991;</a>&#65292;&#33268;&#25964;&#36807;&#21435;&#21322;&#20010;&#19990;&#32426;&#30340;&#21382;&#31243;&#12290;&#19981;&#36807;&#65292;&#30001;&#20110;&#33529;&#26524;&#19968;&#30452;&#20197;&#26469;&#22987;&#32456;&#24341;&#39046;&#28526;&#27969;&#30340;&#24418;&#35937;&#65292;&#24456;&#22810;&#20154;&#24182;&#27809;&#26377;&#24847;&#35782;&#21040;&#23427;&#24050;&#32463;&#26159; IT &#20135;&#19994;&#20013;&#21517;&#21103;&#20854;&#23454;&#30340;&#20803;&#32769;&#12290;&#19982;&#23427;&#24180;&#40836;&#30456;&#24403;&#30340; IT &#24040;&#22836;&#65292;&#22914;&#20170;&#20173;&#30041;&#22312;&#19968;&#32447;&#29260;&#26700;&#19978;&#30340;&#23525;&#23525;&#26080;&#20960;&#12290;</p><p>&#20316;&#20026;&#19968;&#20010;&#21482;&#27604;&#33529;&#26524;&#22823;&#19968;&#23681;&#30340;&#31185;&#25216;&#29233;&#22909;&#32773;&#65292;&#20174; Apple II &#21040;&#22914;&#20170;&#30340; iPhone&#12289;MacBook&#65292;&#33529;&#26524;&#30340;&#20135;&#21697;&#20960;&#20046;&#20276;&#38543;&#25105;&#36208;&#36807;&#20102;&#22823;&#21322;&#20154;&#29983;&#12290;&#20005;&#26684;&#26469;&#35828;&#65292;&#25105;&#24182;&#19981;&#31639;&#30495;&#27491;&#30340;&#26524;&#31881;&#8212;&#8212;&#19981;&#20250;&#22240;&#20026;&#27809;&#33021;&#31532;&#19968;&#26102;&#38388;&#20080;&#21040;&#26032;&#21697;&#32780;&#36951;&#25022;&#65292;&#20063;&#20960;&#20046;&#19981;&#20877;&#29100;&#22812;&#30475;&#21457;&#24067;&#20250;&#65292;&#26356;&#35828;&#19981;&#20986;&#26032;&#20135;&#21697;&#30340;&#20855;&#20307;&#21442;&#25968;&#12290;&#20294;&#22238;&#39038;&#36807;&#21435;&#65292;&#22312;&#27599;&#19968;&#20010;&#20154;&#29983;&#33410;&#28857;&#19978;&#65292;&#25105;&#37117;&#20250;&#24456;&#33258;&#28982;&#22320;&#36873;&#25321;&#33529;&#26524;&#30340;&#20135;&#21697;&#65292;&#24182;&#22312;&#36817;&#20960;&#24180;&#25104;&#20026;&#20102;&#33529;&#26524;&#24320;&#21457;&#29983;&#24577;&#20013;&#30340;&#19968;&#21592;&#12290;</p><p>&#20854;&#23454;&#25105;&#20063;&#27809;&#26377;&#23436;&#20840;&#24819;&#26126;&#30333;&#65292;&#33529;&#26524;&#23545;&#25105;&#25345;&#20037;&#30340;&#21560;&#24341;&#21147;&#31350;&#31455;&#26469;&#33258;&#21738;&#37324;&#12290;&#26159;&#22240;&#20026;&#24456;&#26089;&#23601;&#24320;&#22987;&#20351;&#29992;&#23427;&#30340;&#20135;&#21697;&#65311;&#26159;&#23427;&#30340;&#21019;&#26032;&#12289;&#20307;&#39564;&#21644;&#27668;&#36136;&#65311;&#36824;&#26159; Jobs &#30340;&#20154;&#26684;&#39749;&#21147;&#65311;&#35828;&#23454;&#35805;&#65292;&#22914;&#20170;&#30340;&#36873;&#25321;&#24050;&#32463;&#23436;&#20840;&#20986;&#20110;&#20064;&#24815;&#21644;&#26412;&#33021;&#65292;&#23601;&#20687;&#32769;&#21451;&#38388;&#30340;&#40664;&#22865;&#65292;&#26089;&#24050;&#19981;&#38656;&#35201;&#20160;&#20040;&#29305;&#21035;&#30340;&#29702;&#30001;&#12290;</p><p>&#24403;&#28982;&#65292;&#33529;&#26524;&#30340;&#25104;&#38271;&#20043;&#36335;&#24182;&#38750;&#19968;&#24070;&#39118;&#39034;&#65292;&#20854;&#38388;&#20063;&#26377;&#36807;&#20302;&#35895;&#12290;&#20294;&#26377;&#19968;&#28857;&#24517;&#39035;&#25215;&#35748;&#65306;&#23427;&#22312;&#36807;&#21435; 50 &#24180;&#38388;&#30340;&#20225;&#19994;&#23450;&#20301;&#20960;&#20046;&#27809;&#21464;&#8212;&#8212;&#20026;&#20010;&#20154;&#21644;&#31038;&#20250;&#21019;&#36896;&#24378;&#22823;&#30340;&#24037;&#20855;&#12290;&#21363;&#20415;&#22312;&#26368;&#26032;&#19968;&#36718; AI &#28010;&#28526;&#20013;&#65292;&#33529;&#26524;&#30475;&#20284;&#22833;&#21435;&#20102;&#20808;&#26426;&#65292;&#20294;&#20316;&#20026;&#36830;&#25509;&#20154;&#19982;&#25968;&#23383;&#19990;&#30028;&#30340;&#8220;&#26368;&#21518;&#19968;&#21400;&#31859;&#8221;&#30340;&#26680;&#24515;&#21442;&#19982;&#32773;&#65292;&#23427;&#20173;&#28982;&#20855;&#22791;&#22312; AI &#26102;&#20195;&#30041;&#22312;&#29260;&#26700;&#20013;&#22830;&#30340;&#36164;&#26412;&#12290;&#27605;&#31455;&#65292;&#25105;&#20204;&#29983;&#27963;&#22312;&#29289;&#36136;&#19990;&#30028;&#20013;&#65292;&#38656;&#35201;&#23454;&#25171;&#23454;&#30340;&#30828;&#20214;&#35774;&#22791;&#21644;&#20010;&#20154;&#21270;&#26381;&#21153;&#26469;&#20139;&#21463;&#25216;&#26415;&#36827;&#27493;&#30340;&#25104;&#26524;&#12290;</p><p>50 &#23681;&#30340;&#33529;&#26524;&#25110;&#35768;&#33021;&#32473;&#26356;&#22810;&#20225;&#19994;&#24102;&#26469;&#21551;&#31034;&#65306;&#19982;&#20854;&#27169;&#20223;&#23427;&#8220;&#28843;&#37239;&#8221;&#12289;&#8220;&#21019;&#26032;&#8221;&#30340;&#22806;&#34920;&#65292;&#19981;&#22914;&#23398;&#20064;&#23427;&#30340;&#19987;&#27880;&#19982;&#22362;&#25345;&#12290;&#25104;&#20026;&#19982;&#29992;&#25143;&#38271;&#20037;&#20114;&#30456;&#38506;&#20276;&#30340;&#20249;&#20276;&#65292;&#25110;&#35768;&#25165;&#26159;&#23427;&#25104;&#21151;&#30340;&#30495;&#27491;&#23494;&#30721;&#12290;</p><p>&#22823;&#27010;&#29575;&#20877;&#36807;&#21313;&#24180;&#65292;&#24403;&#33529;&#26524; 60 &#23681;&#12289;&#25105; 61 &#23681;&#30340;&#26102;&#20505;&#65292;&#25105;&#20173;&#28982;&#29992;&#30528;&#19968;&#21488;&#33529;&#26524;&#30005;&#33041;&#12290;</p><p>&#29983;&#26085;&#24555;&#20048;&#65292;&#33529;&#26524;&#65281;</p><p><a href="https://fatbobman.com/zh/weekly/issue-126/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-boltai">&#21407;&#29983; AI &#32842;&#22825;&#24212;&#29992; &#8212; &#26497;&#36895;&#12289;&#38544;&#31169;&#20248;&#20808;&#12289;100+ &#19987;&#19994;&#21151;&#33021;</a></strong></h3><p>&#19968;&#20010;&#21407;&#29983;&#24212;&#29992;&#65292;100+ AI &#27169;&#22411;&#65292;&#25903;&#25345; Mac&#12289;iOS &#21644; Android&#12290;&#26497;&#36895;&#21709;&#24212;&#12289;&#38190;&#30424;&#39537;&#21160;&#12289;&#38750; Electron&#12290;&#38480;&#26102;&#20248;&#24800;&#65292;&#20351;&#29992;&#30721; <code>FATBOBMAN25</code> &#31435;&#20139; 75 &#25240;&#12290;</p><p><strong><a href="https://l.fatbobman.com/sb-boltai">&#9889;&#65039; &#33719;&#21462; BoltAI &#8212; 75 &#25240;&#20248;&#24800;  -&gt;</a></strong></p><div><hr></div><h2><strong>&#21407;&#21019;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/why-i-am-still-thinking-about-core-data-in-2026/?utm_source=fatbobman%20weekly%20issue%20127&amp;utm_medium=web">2026 &#24180;&#65292;&#20026;&#20160;&#20040;&#25105;&#20173;&#22312;&#24605;&#32771; Core Data</a></strong></h3><p>&#21040; 2026 &#24180;&#65292;Core Data &#24050;&#32463;&#38382;&#19990; 21 &#24180;&#65292;&#23613;&#31649;&#20173;&#26377;&#19981;&#23569;&#24320;&#21457;&#32773;&#22312;&#20351;&#29992;&#23427;&#65292;&#20294;&#22312;&#20170;&#22825;&#30340; Swift &#39033;&#30446;&#37324;&#65292;&#23427;&#36234;&#26469;&#36234;&#20687;&#20010;&#8220;&#26102;&#20195;&#36951;&#30041;&#8221;&#12290;&#24182;&#21457;&#24471;&#38752; <code>perform</code> &#19968;&#23618;&#23618;&#22871;&#65292;&#27169;&#22411;&#22768;&#26126;&#22534;&#28385;&#26679;&#26495;&#20195;&#30721;&#65292;&#23383;&#31526;&#20018;&#35859;&#35789;&#38543;&#26102;&#31561;&#20320;&#36393;&#22353;&#12290;&#36825;&#31687;&#25991;&#31456;&#19981;&#26159;&#35201;&#20026; Core Data &#36777;&#25252;&#65292;&#20063;&#19981;&#26159;&#35201;&#35828;&#26381;&#26032;&#30340;&#24320;&#21457;&#32773;&#22238;&#21040; Core Data&#12290;&#23427;&#26356;&#20687;&#26159;&#19968;&#31687;&#38382;&#39064;&#25972;&#29702;&#65306;&#22312; 2026 &#24180;&#65292;&#20026;&#20160;&#20040;&#20173;&#26377;&#20154;&#22362;&#25345;&#20351;&#29992; Core Data&#65307;&#32780;&#22914;&#26524;&#35201;&#32487;&#32493;&#20351;&#29992;&#23427;&#65292;&#25105;&#20204;&#20170;&#22825;&#30495;&#27491;&#38656;&#35201;&#35299;&#20915;&#30340;&#38382;&#39064;&#21448;&#26159;&#20160;&#20040;&#12290;</p><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0127-01">&#33529;&#26524;&#24037;&#31243;&#24072;&#35848;&#24212;&#29992;&#23433;&#20840;&#19982;&#20869;&#23384;&#20445;&#25252; (Fortify Your App: Essential Strategies to Strengthen Security Q&amp;A)</a></strong></h3><p>&#22312;&#33529;&#26524;&#24320;&#21457;&#32773;&#20013;&#24515;&#20030;&#21150;&#30340;&#19968;&#22330;&#23433;&#20840;&#19987;&#39064;&#27963;&#21160;&#20013;&#65292;&#22810;&#20301;&#33529;&#26524;&#24037;&#31243;&#24072;&#22260;&#32469;&#24212;&#29992;&#23433;&#20840;&#19982;&#20869;&#23384;&#23433;&#20840;&#36827;&#34892;&#20102;&#36817;&#20845;&#23567;&#26102;&#30340;&#20998;&#20139;&#19982;&#38382;&#31572;&#65292;&#20869;&#23481;&#28085;&#30422;&#29616;&#20195;&#24212;&#29992;&#38754;&#20020;&#30340;&#23433;&#20840;&#25361;&#25112;&#65292;&#20197;&#21450; Apple &#24179;&#21488;&#25552;&#20379;&#30340;&#19968;&#31995;&#21015;&#38450;&#25252;&#25216;&#26415;&#12290;<a href="https://x.com/AntonGubarenko">Anton Gubarenko</a> &#23558;&#36825;&#22330;&#27963;&#21160;&#20013;&#30340;&#22823;&#37327;&#24320;&#21457;&#32773;&#38382;&#31572;&#25972;&#29702;&#25104;&#25991;&#65292;&#35752;&#35770;&#20102;&#31532;&#19977;&#26041;&#24211;&#23433;&#20840;&#35780;&#20272;&#12289;UserDefaults &#19982; plist &#25968;&#25454;&#23384;&#20648;&#30340;&#39118;&#38505;&#12289;Keychain &#19982;&#25991;&#20214;&#20445;&#25252;&#31574;&#30053;&#12289;Swift <code>unsafe</code> API &#30340;&#20351;&#29992;&#36793;&#30028;&#65292;&#20197;&#21450;&#22914;&#20309;&#22312; Xcode &#20013;&#21551;&#29992; Enhanced Security &#31561;&#33021;&#21147;&#12290;&#23545;&#20110;&#24076;&#26395;&#20102;&#35299; Apple &#24179;&#21488;&#23433;&#20840;&#26426;&#21046;&#19982;&#23454;&#36341;&#24314;&#35758;&#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20221;&#20449;&#24687;&#23494;&#24230;&#24456;&#39640;&#30340;&#38382;&#31572;&#25972;&#29702;&#65292;&#20854;&#20013;&#21253;&#21547;&#19981;&#23569;&#26469;&#33258;&#33529;&#26524;&#24037;&#31243;&#24072;&#30340;&#19968;&#25163;&#20449;&#24687;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-02">&#29992; CLI &#19982; MCP &#33258;&#21160;&#21270;&#37197;&#32622; iOS &#35746;&#38405; (Faster iOS Subscriptions with ASC CLI and RevenueCat MCP)</a></strong></h3><p>&#20026;&#24212;&#29992;&#28155;&#21152;&#35746;&#38405;&#21151;&#33021;&#26412;&#36523;&#24182;&#19981;&#22797;&#26434;&#65292;&#20294;&#22312; App Store Connect &#19982; RevenueCat &#20004;&#20010;&#21518;&#21488;&#20043;&#38388;&#26469;&#22238;&#37197;&#32622;&#65292;&#36807;&#31243;&#24448;&#24448;&#30456;&#24403;&#32321;&#29712;&#12290;<a href="https://x.com/rudrank">Rudrank Riyam</a> &#20171;&#32461;&#20102;&#19968;&#31181;&#26356;&#39640;&#25928;&#30340;&#20570;&#27861;&#65306;&#20351;&#29992; <a href="https://github.com/rudrankriyam/App-Store-Connect-CLI">ASC CLI</a> &#22312;&#32456;&#31471;&#20013;&#19968;&#27425;&#24615;&#21019;&#24314;&#35746;&#38405;&#20135;&#21697;&#65292;&#20877;&#35753; AI &#20195;&#29702;&#36890;&#36807; RevenueCat &#30340; MCP Server &#33258;&#21160;&#23436;&#25104; entitlements&#12289;offerings &#19982; paywall &#30340;&#37197;&#32622;&#65292;&#20174;&#32780;&#23558;&#21407;&#26412;&#20381;&#36182;&#25511;&#21046;&#21488;&#28857;&#20987;&#30340;&#27969;&#31243;&#36801;&#31227;&#21040; CLI + AI Agent &#30340;&#33258;&#21160;&#21270;&#24037;&#20316;&#27969;&#20013;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-03">JetBrains &#38754;&#21521; Swift &#24320;&#21457;&#32773;&#30340;&#35843;&#26597; (JetBrains Swift Developers Survey)</a></strong></h3><p>JetBrains &#26368;&#36817;&#21457;&#24067;&#20102;&#19968;&#20221;&#38754;&#21521; Swift &#24320;&#21457;&#32773;&#30340;&#35843;&#30740;&#38382;&#21367;&#65292;&#36992;&#35831;&#24320;&#21457;&#32773;&#20998;&#20139;&#24403;&#21069;&#20351;&#29992;&#30340;&#24320;&#21457;&#24037;&#20855;&#12289;&#24037;&#20316;&#27969;&#31243;&#20197;&#21450;&#22312; Swift &#29983;&#24577;&#20013;&#30340;&#30171;&#28857;&#12290;&#23613;&#31649;&#23448;&#26041;&#24182;&#26410;&#35828;&#26126;&#35843;&#30740;&#30340;&#20855;&#20307;&#29992;&#36884;&#65292;&#20294;&#31038;&#21306;&#20013;&#24050;&#32463;&#20986;&#29616;&#19981;&#23569;<a href="https://www.reddit.com/r/Jetbrains/comments/1rr6wto/jetbrains_might_be_considering_bringing_back/">&#29468;&#27979;</a>&#65306;&#36825;&#39033;&#35843;&#26597;&#21487;&#33021;&#19982; JetBrains &#37325;&#26032;&#35780;&#20272; Swift &#24320;&#21457;&#24037;&#20855;&#25903;&#25345;&#26377;&#20851;&#12290;</p><p>&#22312; JetBrains &#20110; 2022 &#24180;&#23459;&#24067;&#20572;&#27490;&#32500;&#25252; AppCode &#20043;&#21518;&#65292;Swift &#24320;&#21457;&#32773;&#22522;&#26412;&#22238;&#21040;&#20102;&#20197; Xcode &#20026;&#26680;&#24515;&#30340;&#24037;&#20855;&#38142;&#12290;&#27492;&#27425;&#35843;&#30740;&#20063;&#24341;&#21457;&#20102;&#19968;&#20123;&#35752;&#35770;&#8212;&#8212;&#26377;&#20154;&#26399;&#24453; JetBrains &#37325;&#26032;&#25506;&#32034; Swift tooling &#30340;&#21487;&#33021;&#24615;&#65292;&#20063;&#26377;&#20154;&#35748;&#20026;&#36825;&#26356;&#21487;&#33021;&#19982; Kotlin Multiplatform &#25110; Swift &#26500;&#24314;&#24037;&#20855;&#38142;&#30456;&#20851;&#12290;&#22914;&#26524;&#20320;&#23545; Swift &#24320;&#21457;&#24037;&#20855;&#29983;&#24577;&#30340;&#26410;&#26469;&#26041;&#21521;&#24863;&#20852;&#36259;&#65292;&#19981;&#22952;&#21442;&#19982;&#36825;&#20221;&#35843;&#26597;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-04">&#19981;&#20381;&#36182;&#32534;&#35793;&#22120;&#35782;&#21035; Swift Protocol &#30340;&#26041;&#27861; (How Well Can You Detect a Swift Protocol Without the Compiler?)</a></strong></h3><p>&#22312; Swift &#39033;&#30446;&#20013;&#65292;Protocol &#20960;&#20046;&#26080;&#22788;&#19981;&#22312;&#65292;&#20294;&#22914;&#26524;&#19981;&#20381;&#36182;&#32534;&#35793;&#22120;&#25110;&#23436;&#25972;&#26500;&#24314;&#29615;&#22659;&#65292;&#20165;&#36890;&#36807;&#28304;&#30721;&#25991;&#26412;&#21028;&#26029;&#19968;&#20010;&#25991;&#20214;&#26159;&#21542;&#23450;&#20041;&#25110;&#20351;&#29992;&#20102;&#21327;&#35758;&#65292;&#32467;&#26524;&#20250;&#26377;&#22810;&#21487;&#38752;&#65311;<a href="https://x.com/budo_coder">Xiangyu Sun</a> &#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#31995;&#32479;&#35780;&#20272;&#20102;&#22810;&#31181;&#26816;&#27979;&#31574;&#30053;&#65292;&#20363;&#22914;&#20351;&#29992; SourceKit/LSP&#12289;SwiftSyntax AST&#12289;&#20851;&#38190;&#23383;&#27491;&#21017;&#21305;&#37197;&#65292;&#20197;&#21450;&#36890;&#36807; <code>extension Foo: Bar</code>&#12289;<code>any</code> / <code>some</code> &#31561;&#35821;&#27861;&#20449;&#21495;&#36827;&#34892;&#21551;&#21457;&#24335;&#21028;&#26029;&#65292;&#24182;&#23545;&#36825;&#20123;&#26041;&#27861;&#30340;&#20934;&#30830;&#29575;&#19982;&#36866;&#29992;&#22330;&#26223;&#36827;&#34892;&#20102;&#27604;&#36739;&#12290;</p><p>&#25991;&#31456;&#26368;&#26377;&#24847;&#24605;&#30340;&#37096;&#20998;&#22312;&#20110;&#20316;&#32773;&#21457;&#29616;&#65306;<strong>&#31616;&#21333;&#30340;&#21629;&#21517;&#32422;&#23450;&#21487;&#20197;&#26174;&#33879;&#25552;&#21319;&#38745;&#24577;&#20998;&#26512;&#25928;&#26524;</strong>&#12290;&#22914;&#26524;&#22242;&#38431;&#32479;&#19968;&#20351;&#29992; <code>*Protocol</code> &#21518;&#32512;&#21629;&#21517;&#21327;&#35758;&#31867;&#22411;&#65288;&#22914; <code>PaymentServiceProtocol</code>&#65289;&#65292;&#24456;&#22810;&#21407;&#26412;&#23384;&#22312;&#27495;&#20041;&#30340;&#26816;&#27979;&#26041;&#27861;&#37117;&#20250;&#21464;&#24471;&#26356;&#21152;&#21487;&#38752;&#12290;&#20316;&#32773;&#36824;&#36827;&#19968;&#27493;&#35752;&#35770;&#20102;&#36825;&#31181;&#32422;&#23450;&#22312; AI &#36741;&#21161;&#24320;&#21457;&#20013;&#30340;&#20215;&#20540;&#65306;&#36890;&#36807;&#22312;&#25991;&#20214;&#32423;&#21035;&#39044;&#20998;&#31867;&#21327;&#35758;&#25991;&#20214;&#65292;&#21487;&#20197;&#22312;&#21521; LLM &#25552;&#20379;&#19978;&#19979;&#25991;&#26102;&#26174;&#33879;&#20943;&#23569; token &#28040;&#32791;&#65292;&#24182;&#25552;&#39640;&#20998;&#26512;&#25928;&#29575;&#65292;&#36825;&#26159;&#19968;&#20010;&#39047;&#20855;&#21551;&#21457;&#24615;&#30340;&#35270;&#35282;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-05">&#36801;&#31227;&#21040; Swift Concurrency &#21069;&#38656;&#35201;&#27880;&#24847;&#30340;&#32454;&#33410; (What you should know before Migrating from GCD to Swift Concurrency)</a></strong></h3><p>&#20174; GCD &#36801;&#31227;&#21040; Swift Concurrency &#24182;&#38750;&#31616;&#21333;&#30340;&#35821;&#27861;&#26367;&#25442;&#12290;&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://x.com/soumya_mahunt">Soumya Ranjan Mahunt</a> &#25351;&#20986;&#65306;Swift Concurrency &#22312;&#20219;&#21153;&#35843;&#24230;&#12289;&#25191;&#34892;&#39034;&#24207;&#20197;&#21450;&#24182;&#21457;&#35821;&#20041;&#19978;&#19982; GCD &#23384;&#22312;&#19968;&#20123;&#20851;&#38190;&#24046;&#24322;&#65292;&#20363;&#22914; <code>Task</code> &#30340;&#35843;&#24230;&#24182;&#19981;&#20445;&#35777;&#19982; GCD &#30456;&#21516;&#30340; FIFO &#25191;&#34892;&#39034;&#24207;&#65292;&#32780; <code>actor</code> &#20063;&#24182;&#19981;&#26159; <code>DispatchQueue</code> &#30340;&#30452;&#25509;&#26367;&#20195;&#65292;&#20854;&#25191;&#34892;&#34892;&#20026;&#21487;&#33021;&#21463;&#21040;&#20219;&#21153;&#20248;&#20808;&#32423;&#21644;&#35843;&#24230;&#31574;&#30053;&#30340;&#24433;&#21709;&#12290;&#27492;&#22806;&#65292;&#25991;&#20013;&#36824;&#35752;&#35770;&#20102;&#19968;&#20123;&#22312;&#23454;&#38469;&#36801;&#31227;&#36807;&#31243;&#20013;&#23481;&#26131;&#34987;&#24573;&#35270;&#30340;&#38382;&#39064;&#65292;&#20363;&#22914; <code>DispatchGroup</code> &#22312; Swift Concurrency &#20013;&#24182;&#27809;&#26377;&#23436;&#20840;&#31561;&#20215;&#30340; API&#65292;&#20197;&#21450;&#22312;&#26087;&#31995;&#32479;&#29256;&#26412;&#20013;&#20351;&#29992; <code>assumeIsolated</code> &#21487;&#33021;&#36935;&#21040;&#30340;&#20860;&#23481;&#24615;&#38382;&#39064;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-06">&#36873;&#25321; AI Agent Skill &#30340;&#20061;&#27493;&#26694;&#26550; (A 9-Step Framework for Choosing the Right Agent Skill)</a></strong></h3><p>&#38543;&#30528; AI Agent &#22312;&#24320;&#21457;&#24037;&#20316;&#27969;&#20013;&#30340;&#24212;&#29992;&#36234;&#26469;&#36234;&#24191;&#27867;&#65292;&#22914;&#20309;&#20026; Agent &#35774;&#35745;&#21512;&#36866;&#30340;&#8220;&#25216;&#33021;&#8221;&#65288;Skill / Tool&#65289;&#20063;&#36880;&#28176;&#25104;&#20026;&#19968;&#20010;&#26032;&#30340;&#24037;&#31243;&#38382;&#39064;&#12290;<a href="https://x.com/twannl">Antoine van der Lee</a> &#25552;&#20986;&#20102;&#19968;&#20010;&#29992;&#20110;&#21028;&#26029;&#20309;&#26102;&#24212;&#35813;&#20026; Agent &#21019;&#24314;&#25216;&#33021;&#30340;&#20061;&#27493;&#26694;&#26550;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#22312;&#33258;&#21160;&#21270;&#33021;&#21147;&#12289;&#21487;&#32500;&#25252;&#24615;&#20197;&#21450;&#31995;&#32479;&#22797;&#26434;&#24230;&#20043;&#38388;&#21462;&#24471;&#24179;&#34913;&#12290;Antoine &#25351;&#20986;&#65292;&#24182;&#38750;&#25152;&#26377;&#20219;&#21153;&#37117;&#36866;&#21512;&#30452;&#25509;&#20132;&#32473; LLM&#65292;&#20063;&#24182;&#38750;&#25152;&#26377;&#33021;&#21147;&#37117;&#38656;&#35201;&#23454;&#29616;&#20026; Agent &#24037;&#20855;&#12290;&#25991;&#31456;&#20174;&#20219;&#21153;&#30830;&#23450;&#24615;&#12289;&#25191;&#34892;&#25104;&#26412;&#12289;&#21487;&#22797;&#29992;&#24615;&#20197;&#21450;&#23433;&#20840;&#24615;&#31561;&#35282;&#24230;&#20986;&#21457;&#65292;&#25552;&#20379;&#20102;&#19968;&#22871;&#30456;&#23545;&#31995;&#32479;&#30340;&#35780;&#20272;&#24605;&#36335;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0127-07">DataStoreKit</a></strong></h3><p>&#36825;&#26159;&#19968;&#20010;&#24456;&#26377;&#24847;&#24605;&#30340;&#24320;&#28304;&#39033;&#30446;&#65292;&#30001; <a href="https://www.asymbas.com/">Anferne Pineda</a> &#24320;&#21457;&#12290;&#23427;&#22522;&#20110; SwiftData &#30340;&#33258;&#23450;&#20041; store &#33021;&#21147;&#65292;&#22312;&#20445;&#30041; SwiftData &#19978;&#23618;&#24320;&#21457;&#20307;&#39564;&#30340;&#21516;&#26102;&#65292;&#37325;&#26032;&#23454;&#29616;&#20102;&#19968;&#22871;&#38754;&#21521; SQLite &#30340;&#24213;&#23618;&#23384;&#20648;&#21518;&#31471;&#65292;&#21253;&#25324;&#20174; SwiftData &#27169;&#22411;&#12289;&#35859;&#35789;&#21040; SQLite schema&#12289;SQL&#12289;&#24555;&#29031;&#19982;&#25345;&#20037;&#21270;&#21382;&#21490;&#30340;&#26144;&#23556;&#21644;&#25191;&#34892;&#12290;</p><p>DataStoreKit &#25552;&#20379;&#20102;&#19968;&#20123;&#20540;&#24471;&#20851;&#27880;&#30340;&#29305;&#24615;&#65292;&#20363;&#22914;&#25903;&#25345;&#23545;&#25968;&#32452;&#12289;&#23383;&#20856;&#31561;&#38598;&#21512;&#31867;&#22411;&#25968;&#25454;&#36827;&#34892;&#35859;&#35789;&#26597;&#35810;&#65292;&#24213;&#23618;&#20197; JSON &#24418;&#24335;&#26144;&#23556;&#21040; SQLite&#65307;&#21516;&#26102;&#20063;&#25552;&#20379;&#20102; SQL &#30452;&#36890;&#33021;&#21147;&#65292;&#35753;&#24320;&#21457;&#32773;&#22312; <code>#Predicate</code> &#20043;&#22806;&#65292;&#33021;&#22815;&#30452;&#25509;&#21033;&#29992; SQLite &#30340;&#33021;&#21147;&#23436;&#25104;&#26597;&#35810;&#25110;&#32500;&#25252;&#25805;&#20316;&#12290;</p><p>&#36825;&#26159;&#30446;&#21069;&#20026;&#25968;&#19981;&#22810;&#12289;&#19988;&#23454;&#29616;&#28145;&#24230;&#36739;&#39640;&#30340; SwiftData <code>DataStore</code> &#33258;&#23450;&#20041;&#23454;&#36341;&#65292;&#23637;&#31034;&#20102; SwiftData &#20316;&#20026;&#25968;&#25454;&#34920;&#29616;&#23618;&#32780;&#38750;&#23436;&#25972;&#25345;&#20037;&#21270;&#24341;&#25806;&#30340;&#21478;&#19968;&#31181;&#21487;&#33021;&#24615;&#12290;&#39033;&#30446;&#30446;&#21069;&#20173;&#22788;&#20110;&#36739;&#26089;&#26399;&#38454;&#27573;&#65292;API &#21644;&#33021;&#21147;&#36793;&#30028;&#21487;&#33021;&#36824;&#20250;&#32487;&#32493;&#35843;&#25972;&#65292;&#20294;&#24050;&#32463;&#38750;&#24120;&#20540;&#24471;&#25345;&#32493;&#20851;&#27880;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0127-08">Playwright for Swift</a></strong></h3><p><a href="https://x.com/m1guelpf">Miguel Piedrafita</a> &#24320;&#21457;&#30340; <code>swift-playwright</code>&#65292;&#23558; <a href="https://playwright.dev/">Playwright</a> &#36825;&#22871;&#25104;&#29087;&#30340;&#27983;&#35272;&#22120;&#33258;&#21160;&#21270;&#33021;&#21147;&#24102;&#20837;&#20102; Swift &#29983;&#24577;&#12290;&#24320;&#21457;&#32773;&#21487;&#20197;&#30452;&#25509;&#20351;&#29992; Swift &#20195;&#30721;&#39537;&#21160; Chromium&#12289;Firefox &#21644; WebKit&#65292;&#23436;&#25104;&#39029;&#38754;&#23548;&#33322;&#12289;&#28857;&#20987;&#12289;&#36755;&#20837;&#12289;&#25130;&#22270;&#12289;&#25191;&#34892; JavaScript &#31561;&#24120;&#35265;&#25805;&#20316;&#65292;&#25972;&#20307; API &#39118;&#26684;&#20063;&#23613;&#37327;&#36148;&#36817;&#23448;&#26041; Playwright&#12290;</p><p>&#20174;&#23454;&#29616;&#26041;&#24335;&#19978;&#30475;&#65292;&#23427;&#24182;&#19981;&#26159;&#37325;&#26032;&#23454;&#29616;&#19968;&#22871;&#27983;&#35272;&#22120;&#33258;&#21160;&#21270;&#26694;&#26550;&#65292;&#32780;&#26159;&#22312; Swift &#20391;&#23553;&#35013;&#20102; Playwright &#21327;&#35758;&#65292;&#24213;&#23618;&#20381;&#28982;&#36890;&#36807; Node.js &#30340; Playwright driver &#19982;&#27983;&#35272;&#22120;&#36890;&#20449;&#12290;&#23545;&#20110;&#24076;&#26395;&#20351;&#29992; Swift &#26500;&#24314;&#27979;&#35797;&#24037;&#20855;&#12289;CLI&#65292;&#29978;&#33267; AI Agent &#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#20010;&#39033;&#30446;&#25552;&#20379;&#20102;&#19968;&#20010;&#39047;&#20855;&#21560;&#24341;&#21147;&#30340;&#20999;&#20837;&#28857;&#12290;</p><h2><strong>&#27963;&#21160;</strong></h2><h3><strong><a href="https://letsvision.swiftgg.team/?utm_source=fatbobman%20weekly%20issue%20127&amp;utm_medium=web">LET&#8217;S VISION 2026 -- Born to Create &#183; Powered by AI</a></strong></h3><ul><li><p>&#128064; 70+ &#23637;&#21830;&#29616;&#22330;&#20307;&#39564;</p></li><li><p>&#129302; AI &#21019;&#26032;&#20135;&#21697; / AI Agent</p></li><li><p>&#129405; XR / &#31354;&#38388;&#35745;&#31639;&#27785;&#28024;&#20307;&#39564;</p></li><li><p>&#127908; &#21019;&#20316;&#32773;&#19982;&#24320;&#21457;&#32773;&#20998;&#20139;</p></li></ul><p>&#22914;&#26524;&#20320;&#26159;&#24320;&#21457;&#32773;&#12289;&#35774;&#35745;&#24072;&#12289;&#20135;&#21697;&#32463;&#29702;&#12289;&#21019;&#20316;&#32773;&#65292;&#36824;&#26159;&#23545; AI &#21644;&#26410;&#26469;&#31185;&#25216;&#24863;&#20852;&#36259;&#30340;&#25506;&#32034;&#32773;&#65292;&#37117;&#24456;&#20540;&#24471;&#26469;&#36891;&#36891;&#12290;</p><ul><li><p>&#128197; 2026.3.28 &#8211; 3.29</p></li><li><p>&#128205; &#19978;&#28023; &#183; &#28437;&#27827;&#27902;&#20250;&#35758;&#20013;&#24515;</p></li></ul><p><a href="https://l.fatbobman.com/w0127-09">&#20843;&#20116;&#25240;&#38376;&#31080;&#33719;&#21462;&#20837;&#21475; &#128071;</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YCtR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YCtR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 424w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 848w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 1272w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YCtR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png" width="450" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:450,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;qrcode_www.huodongxing.com&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="qrcode_www.huodongxing.com" title="qrcode_www.huodongxing.com" srcset="https://substackcdn.com/image/fetch/$s_!YCtR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 424w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 848w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 1272w, https://substackcdn.com/image/fetch/$s_!YCtR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6633fc4-2fbf-4fb7-90c2-3b45b05022a9_450x450.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #126]]></title><description><![CDATA[MacBook Neo: The Starting Point of Apple's Return to Campus]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125-cbb</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125-cbb</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 09 Mar 2026 12:02:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!wHjK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wHjK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wHjK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wHjK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg" width="1456" height="695" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:695,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:137839,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/190343271?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wHjK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wHjK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70bbc569-fc5c-4f62-a3c2-3689a1c62e12_1600x764.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>MacBook Neo: The Starting Point of Apple&#8217;s Return to Campus</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-126/">Read on web &#8594;</a></p><p>Last week, Apple launched several new hardware products. Unlike previous launch events, this release was unusually low-key. Initially, I was only interested in the newly announced monitor, but after seeing numerous tech media outlets criticizing the MacBook Neo&#8217;s specs, I couldn&#8217;t help but pay closer attention to it. Looking past the superficial &#8220;downgrades&#8221;, I saw Apple&#8217;s clear determination to return to the education market through its precise pricing strategy. </p><p>Over a decade ago, Apple was a dominant player in the education hardware market. A significant portion of students who grew up using Apple devices on campus naturally transitioned into long-term consumers of Apple&#8217;s hardware and software after entering the workforce. However, as Google continuously ramped up its investments in Chromebooks and Apple lacked a price-competitive alternative, this K-12-centric market was gradually taken over by competitors (Chromebooks once captured nearly 60% of the U.S. K-12 education market). This not only cost Apple a portion of its revenue but, more importantly, weakened the brand affinity it had established among teenagers surrounding desktop and laptop computing forms. Compared to tablets, laptops still hold distinct advantages in teaching experience, use cases, durability, and centralized IT management.</p><p>In today&#8217;s service-first era, hardware is deeply intertwined with ecosystems. Chromebooks have long cultivated a massive cohort of young users accustomed to using Google Docs. As these users grow older and accumulate data, even if they eventually have the purchasing power to buy Apple devices, it becomes incredibly difficult to deeply lock them into Apple&#8217;s service ecosystem, let alone cultivate true brand loyalty.</p><p>The precise pricing of the Neo changes this dynamic. A starting price of $599 and an education discount of $499 give more children the opportunity to start using Apple devices and owning an Apple ID in school, thereby following Apple&#8217;s &#8220;predetermined path&#8221; to gradually purchase more products and services. As for the widely criticized &#8220;downgraded specs&#8221;&#8212;the A18 Pro chip is more than sufficient for daily K-12 scenarios. It isn&#8217;t lacking in performance; this is exactly where it is meant to be positioned. Apple traded a mobile chip for aggressive pricing headroom&#8212;a very shrewd calculation.</p><p>The subscription-based Apple Creator Studio also demonstrates Apple&#8217;s ambition to build long-term relationships with a broader audience within its ecosystem. For schools, cheap hardware combined with a powerful creative software suite forms a perfect closed loop. The MacBook Neo&#8217;s hardware performance may not be top-tier, but it is enough to provide a stable, usable experience over a typical 4- to 5-year device lifecycle, allowing users to gradually assimilate into Apple&#8217;s service system. From this perspective, the MacBook Neo acts more like an &#8220;ecosystem anchor&#8221; tossed by Apple to Gen Z and Gen Alpha.</p><p>Too many consumers and tech reviewers focus entirely on whether Apple&#8217;s products are cool or innovative, forgetting Apple&#8217;s roots&#8212;the education hardware market is deeply embedded in its DNA. Its success today stems from decades of past accumulation, and now it needs to fill the void left over the past dozen years. For the readers of this newsletter, the Neo is highly unlikely to be your cup of tea. But that doesn&#8217;t prevent it from being a highly targeted and ambitious product&#8212;one that isn&#8217;t designed to make a quick buck, but rather serves as Apple&#8217;s long-term bet on its ecosystem landscape for the next two decades.</p><p><a href="https://fatbobman.com/en/weekly/issue-125/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-notepad">Notepad.exe &#8212; Your First Stop for Swift Experiments</a></strong></h3><p>New Swift 6 syntax to try? Xcode is too heavy, Playground too slow. Notepad.exe gets you from idea to running code in 30 seconds &#8212; no project setup. Multi-toolchain support, simulator integration, just open and code.</p><p><a href="https://l.fatbobman.com/sb-notepad">&#128640; Download for macOS &#8594;</a></p><div><hr></div><h2><strong>Original</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/sendable-nsmanagedobjectcontext/?utm_source=fatbobman%20weekly%20issue%20126&amp;utm_medium=web">Why Does Passing NSManagedObjectContext Across Isolation Domains No Longer Error in Swift 6.2? The Real Change Isn&#8217;t in the Compiler</a></strong></h3><p>When a piece of concurrency-related code fails to compile in older versions of Xcode but compiles successfully in the latest Xcode 26 (Swift 6.2), what would be your first guess? Many developers might initially assume that Swift&#8217;s concurrency analysis&#8212;such as Region-Based Isolation&#8212;has evolved again. But the reality is not that simple. In this article, I document a rather interesting debugging journey I recently encountered: starting from a failing test, constructing a minimal reproducible example, and tracing the issue all the way down to the Core Data SDK interface. Eventually, I discovered that the key change was not entirely in the Swift compiler itself, but in how the framework is imported. In the new SDK, <code>NSManagedObjectContext</code> is now annotated with macros like <code>NS_SWIFT_SENDABLE</code>, giving it <code>Sendable</code> semantics in Swift.</p><blockquote><p>Although SwiftData is the most important persistence framework for the future of the Apple ecosystem, Core Data&#8212;the foundation beneath it&#8212;has not been neglected by Apple. Over the past few years, Apple has been quietly improving its compatibility and concurrency behavior in Swift 6, which is a very encouraging sign.</p></blockquote><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0126-01">What&#8217;s new in Swift: February 2026 Edition</a></strong></h3><p><a href="https://bsky.app/profile/karenchu.online">Karen Chu</a> and <a href="https://bsky.app/profile/davelester.dev">Dave Lester</a> compiled the latest developments in the Swift ecosystem for February 2026 on the official blog. The post not only highlights Swift&#8217;s strong presence at <a href="https://swiftlang.github.io/event-fosdem/">FOSDEM</a>&#8212;the world&#8217;s largest open source conference&#8212;but also showcases several notable open-source updates and Swift Evolution proposals. Among them, <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0506-advanced-observation-tracking.md">SE-0506</a> particularly caught my attention. The proposal introduces an Options parameter to <code>withObservationTracking</code>, allowing developers to precisely control whether they observe changes before mutation (<code>willSet</code>), after mutation (<code>didSet</code>), or even lifecycle events such as <code>deinit</code>. Additionally, <code>withContinuousObservationTracking</code> enables stable, automatic continuous observation without the need to manually re-register observers recursively.</p><blockquote><p>The acceptance of SE-0506 is significant. It not only completes the timing control and continuity capabilities of state observation, but also marks the maturity of Swift&#8217;s native Observation system. It is no longer merely a companion feature for SwiftUI, but has evolved into a robust foundation capable of supporting industrial-grade, high-performance state-flow scheduling across Swift applications.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-09">macOS Input Method Development Guidelines for 2026</a></strong></h3><p>Based on years of experience developing macOS input methods, <a href="https://x.com/shikisuen">ShikiSuen</a>, the author of the <a href="https://vchewing.github.io/README.html">vChewing Input Method</a>, provides a comprehensive overview of the historical baggage of InputMethodKit (IMK) and the various issues it exposes under Swift 6&#8217;s strict concurrency checks. The article explores challenges such as NSConnection naming conventions, sandbox requirements, MainActor isolation conflicts, ARC congestion caused by frequent language switching (CapsLock), and even NSWindow memory leaks under the macOS 26 Liquid Glass mechanism. Rather than simply criticizing these legacy frameworks, the author proposes a set of engineering practices that resemble a &#8220;risk-control model&#8221;: reducing controllers to simple forwarding layers, moving business logic into weak-referenced sessions, using self-checking memory guards, and avoiding IMKCandidates entirely.</p><blockquote><p>Notably, ShikiSuen implemented these ideas in an open-source library called <a href="https://github.com/vChewing/IMKSwift">IMKSwift</a>. It provides an <code>@MainActor</code>-isolated <code>IMKInputSessionController</code> base class designed for Swift 6+, covering many concurrency pitfalls in the original <code>IMKInputController</code>. If you are developing macOS desktop applications or input methods, this library allows you to write type-safe, modern Swift code without manual hacks or data-race warnings.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-03">SwiftUI, Swift Effects: A Beautiful Onion Architecture</a></strong></h3><p>Handling data loading states in SwiftUI is something almost every application has to deal with. The common states&#8212;<code>loading</code>, <code>loaded</code>, and <code>failed</code>&#8212;are often intertwined with side effects such as network requests, caching, and logging, which can quickly make view code messy. In this article, <a href="https://www.linkedin.com/in/salgara/">Salgara</a> proposes an approach inspired by Onion Architecture. By combining ViewState with Effect Handlers, side effects such as <code>Fetch</code>, caching, and logging are separated into composable layers. AsyncSequence and injectable Effect Handlers then drive state transitions, allowing the UI to render purely based on state. In this design, the view layer remains clean while data and side effects flow through a clearly structured &#8220;effect pipeline.&#8221; The architecture also provides strong testability&#8212;tests can intercept effects and simulate data sources to validate state transitions.</p><blockquote><p>Salgara openly acknowledges that this architecture is still experimental: prototype-first, and treating everything as a view (Everything as a View). As more developers explore architectures that better align with SwiftUI&#8217;s design philosophy, such experiments may not only benefit SwiftUI itself but also enrich the broader landscape of declarative programming rather than merely replicating patterns from other UI frameworks.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-04">Spec-Driven Development: After AI Starts Writing Code</a></strong></h3><p>With the growing adoption of AI coding agents such as Cursor and Claude Code, developers are facing a new challenge: when AI can generate thousands of lines of code across dozens of files in minutes, how can humans effectively review it? And how should we deal with issues like context decay and hallucinations as conversations grow longer? A new development paradigm is emerging in response: <strong>Spec-Driven Development (SDD)</strong>. In this model, developers no longer focus primarily on writing code directly. Instead, they define clear specifications (Specs), and AI generates implementations based on those specifications.</p><p><a href="https://x.com/rbbtsn0w">Snow</a> explores this idea through a four-part series. Starting with the limitations of &#8220;Vibe Coding,&#8221; the articles outline a specification-centered development workflow and examine the evolving role of specifications in future software engineering. In this vision, code may no longer be the center of a project&#8212;it may simply become a byproduct of well-defined specifications.</p><blockquote><p>As AI increasingly handles implementation details, the center of software engineering may shift from &#8220;writing code&#8221; to &#8220;expressing intent.&#8221; SDD attempts to establish a strong layer of constraints between human ambiguity and AI&#8217;s indiscriminate code generation.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-05">Building a Mini Linker for SwiftUI Previews</a></strong></h3><p>Among the many tools provided by mcpbridge in Xcode 26.3, <code>RenderPreview</code> can directly return screenshots of SwiftUI previews, making them easier for AI to analyze. For developers who cannot yet use Xcode 26.3 mcpbridge, the approach and accompanying tools introduced by <a href="https://hachyderm.io/@IronHam">Hesham Salman</a> offer a similar capability. The technical highlight lies in using SwiftSyntax to construct a declaration dependency graph, then applying BFS to determine the minimal set of source files required by a given preview. This avoids the need to compile the entire App target, significantly reducing build time.</p><blockquote><p>The real value of this article lies in its approach: using SwiftSyntax + BFS to quickly identify the code segments required by a preview. In the past, SwiftSyntax had a relatively high barrier to entry, but in the age of AI-assisted development it is increasingly becoming foundational infrastructure for understanding code structure. Even if you are not as experienced with SwiftSyntax as Hesham Salman, once you understand its basic capabilities you can leverage AI to implement similar ideas&#8212;tools that previously were often built only by developers deeply familiar with compiler tooling.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-06">Swift at scale: building the TelemetryDeck analytics service</a></strong></h3><p>When discussing Swift on Server, many people still focus on a simple question: can it be used in production? TelemetryDeck provides a more concrete answer&#8212;not only can it be used, it is already powering an analytics service that processes data from over 16 million users each month. In this article, <a href="https://social.telemetrydeck.com/@daniel">Daniel Jilg</a> explains why the team chose Swift + Vapor for their backend stack and shares valuable lessons from operating a production system. These include using <code>Codable</code> to simplify API encoding and validation, keeping DTOs close to controllers, and recognizing that seemingly mundane practices&#8212;like cache TTLs, API versioning, and monitoring&#8212;often become the true moat in large-scale production systems.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-07">Get Rid of Your SwiftGen Dependency</a></strong></h3><p>For many years, developers relied on tools like SwiftGen to solve a longstanding issue in Apple&#8217;s resource system: resource access was stringly typed. Whether it was localization keys, image names, or color assets, typos often went unnoticed until runtime. <a href="https://www.linkedin.com/in/asserusama/">Asser Osama</a> points out that with the introduction and maturation of <strong>String Catalogs (.xcstrings)</strong> and <strong>Asset Catalog Symbols</strong>, Xcode can now automatically generate resource symbols during compilation. For many modern projects, this built-in capability may already replace the need for SwiftGen.</p><blockquote><p>It is worth noting that removing the dependency assumes your project runs entirely within the standard Xcode ecosystem. Resource symbol generation is an internal feature of the Xcode build system rather than a capability of the Swift compiler or Swift Package Manager. For teams using non-standard build systems such as Bazel or Buck, SwiftGen may still remain the more portable and controllable option.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0126-08">SwiftUI Agent Skill</a></strong></h3><p>Written by <a href="https://x.com/twostraws">Paul Hudson</a>, this SwiftUI Agent Skill aims to help developers produce smarter, simpler, and more modern SwiftUI code. The project gained over 1k stars within just two days of release.</p><blockquote><p>Over the past few weeks, this newsletter has recommended several skills created by well-known developers. While these skills encapsulate the authors&#8217; experience, I still don&#8217;t recommend using them blindly. At the very least, read them thoroughly before adopting them. A skill is essentially a condensed form of insights accumulated across dozens or even hundreds of articles. Only by understanding the underlying design ideas&#8212;and adapting them to your own development habits and project needs&#8212;can you truly unlock their value.</p></blockquote><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125-cbb?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125-cbb?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>Macbook Neo&#65306;&#33529;&#26524;&#37325;&#22238;&#26657;&#22253;&#30340;&#36215;&#28857;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-126/">&#32593;&#39029;&#29256;</a></strong></p><p>&#19978;&#21608;&#65292;&#33529;&#26524;&#25512;&#20986;&#20102;&#33509;&#24178;&#26032;&#27454;&#30828;&#20214;&#20135;&#21697;&#12290;&#19982;&#20197;&#24448;&#30340;&#21457;&#24067;&#20250;&#19981;&#21516;&#65292;&#36825;&#27425;&#21457;&#24067;&#26174;&#24471;&#24322;&#24120;&#20302;&#35843;&#12290;&#36215;&#21021;&#25105;&#21482;&#23545;&#20854;&#20013;&#26032;&#21457;&#24067;&#30340;&#26174;&#31034;&#22120;&#24863;&#20852;&#36259;&#65292;&#20294;&#22312;&#30475;&#21040;&#19981;&#23569;&#25968;&#30721;&#23186;&#20307;&#23545; Macbook Neo &#37197;&#32622;&#30340;&#21520;&#27133;&#21518;&#65292;&#20063;&#19981;&#30001;&#24471;&#22810;&#30041;&#24847;&#20102;&#36825;&#27454;&#20135;&#21697;&#12290;&#30456;&#36739;&#20110;&#20854;&#8220;&#20943;&#37197;&#8221;&#30340;&#34920;&#35937;&#65292;&#25105;&#26356;&#20174;&#20854;&#31934;&#20934;&#30340;&#23450;&#20215;&#20013;&#30475;&#21040;&#20102;&#33529;&#26524;&#37325;&#36820;&#25945;&#32946;&#24066;&#22330;&#30340;&#20915;&#24515;&#12290;</p><p>&#21313;&#20960;&#24180;&#21069;&#65292;&#33529;&#26524;&#36824;&#26366;&#26159;&#25945;&#32946;&#30828;&#20214;&#24066;&#22330;&#30340;&#37325;&#35201;&#21442;&#19982;&#32773;&#12290;&#37027;&#20123;&#22312;&#26657;&#22253;&#20013;&#20351;&#29992;&#33529;&#26524;&#35774;&#22791;&#25104;&#38271;&#36215;&#26469;&#30340;&#23398;&#29983;&#65292;&#20063;&#26377;&#30456;&#24403;&#19968;&#37096;&#20998;&#22312;&#36827;&#20837;&#31038;&#20250;&#21518;&#39034;&#29702;&#25104;&#31456;&#22320;&#25104;&#20026;&#33529;&#26524;&#36719;&#30828;&#20214;&#30340;&#38271;&#26399;&#28040;&#36153;&#32773;&#12290;&#20294;&#38543;&#30528;&#35895;&#27468;&#25345;&#32493;&#21152;&#22823;&#22312; Chromebook &#19978;&#30340;&#25237;&#20837;&#65292;&#32780;&#33529;&#26524;&#21448;&#32570;&#20047;&#26356;&#20855;&#20215;&#26684;&#31454;&#20105;&#21147;&#30340;&#20135;&#21697;&#65292;&#36825;&#19968;&#20197; K12 &#20026;&#26680;&#24515;&#30340;&#24066;&#22330;&#36880;&#28176;&#34987;&#23545;&#25163;&#21344;&#25454;&#65288;Chromebook &#26366;&#19968;&#24230;&#25343;&#19979;&#32654;&#22269;&#22522;&#30784;&#25945;&#32946;&#24066;&#22330;&#36817; 60% &#30340;&#20221;&#39069;&#65289;&#12290;&#36825;&#19981;&#20165;&#35753;&#33529;&#26524;&#25439;&#22833;&#20102;&#19968;&#37096;&#20998;&#25910;&#20837;&#65292;&#26356;&#37325;&#35201;&#30340;&#26159;&#21066;&#24369;&#20102;&#20854;&#22312;&#38738;&#23569;&#24180;&#32676;&#20307;&#20013;&#12289;&#22260;&#32469;&#21488;&#24335;&#26426;&#19982;&#31508;&#35760;&#26412;&#36825;&#31181;&#35745;&#31639;&#24418;&#24577;&#25152;&#24314;&#31435;&#30340;&#21697;&#29260;&#20146;&#21644;&#21147;&#12290;&#30456;&#27604;&#24179;&#26495;&#35774;&#22791;&#65292;&#31508;&#35760;&#26412;&#22312;&#25945;&#23398;&#20307;&#39564;&#12289;&#36866;&#29992;&#22330;&#26223;&#12289;&#32784;&#29992;&#24615;&#20197;&#21450; IT &#38598;&#20013;&#31649;&#29702;&#31561;&#26041;&#38754;&#20381;&#28982;&#20855;&#26377;&#26126;&#26174;&#20248;&#21183;&#12290;</p><p>&#22312;&#26381;&#21153;&#20248;&#20808;&#30340;&#20170;&#22825;&#65292;&#30828;&#20214;&#24448;&#24448;&#19982;&#29983;&#24577;&#28145;&#24230;&#32465;&#23450;&#12290;Chromebook &#26089;&#26089;&#22521;&#20859;&#20986;&#19968;&#22823;&#25209;&#20064;&#24815;&#20351;&#29992; Google Docs &#30340;&#24180;&#36731;&#29992;&#25143;&#12290;&#38543;&#30528;&#24180;&#40836;&#22686;&#38271;&#19982;&#25968;&#25454;&#30340;&#31215;&#32047;&#65292;&#21363;&#20415;&#20182;&#20204;&#26085;&#21518;&#20855;&#22791;&#36141;&#20080;&#33529;&#26524;&#35774;&#22791;&#30340;&#33021;&#21147;&#65292;&#20063;&#24456;&#38590;&#20877;&#19982;&#33529;&#26524;&#30340;&#26381;&#21153;&#29983;&#24577;&#24418;&#25104;&#28145;&#24230;&#32465;&#23450;&#65292;&#26356;&#38590;&#24418;&#25104;&#30495;&#27491;&#30340;&#21697;&#29260;&#20449;&#20208;&#12290;</p><p>Neo &#31934;&#20934;&#30340;&#23450;&#20215;&#25913;&#21464;&#20102;&#36825;&#19968;&#23616;&#38754;&#12290;$599 &#30340;&#36215;&#21806;&#20215;&#12289;$499 &#30340;&#25945;&#32946;&#20248;&#24800;&#65292;&#35753;&#26356;&#22810;&#23401;&#23376;&#26377;&#26426;&#20250;&#22312;&#23398;&#26657;&#23601;&#24320;&#22987;&#20351;&#29992;&#33529;&#26524;&#35774;&#22791;&#12289;&#25317;&#26377; Apple ID&#65292;&#20174;&#32780;&#39034;&#30528;&#33529;&#26524;&#8220;&#39044;&#35774;&#8221;&#30340;&#36712;&#36857;&#65292;&#36880;&#27493;&#36141;&#20080;&#26356;&#22810;&#20135;&#21697;&#19982;&#26381;&#21153;&#12290;&#33267;&#20110;&#34987;&#24191;&#27867;&#25209;&#35780;&#30340;&#8221;&#20943;&#37197;&#8221;&#8212;&#8212;A18 Pro &#33455;&#29255;&#23545; K12 &#26085;&#24120;&#20351;&#29992;&#22330;&#26223;&#32780;&#35328;&#23436;&#20840;&#36275;&#22815;&#65292;&#23427;&#32570;&#30340;&#19981;&#26159;&#24615;&#33021;&#65292;&#32780;&#26159;&#23450;&#20301;&#26412;&#23601;&#22914;&#27492;&#12290;&#33529;&#26524;&#29992;&#31227;&#21160;&#31471;&#33455;&#29255;&#25442;&#26469;&#20102;&#28608;&#36827;&#30340;&#23450;&#20215;&#31354;&#38388;&#65292;&#36825;&#26159;&#19968;&#31508;&#31639;&#24471;&#24456;&#28165;&#26970;&#30340;&#36134;&#12290;</p><p>&#37319;&#29992;&#35746;&#38405;&#21046;&#30340; Apple Creator Studio&#65292;&#21516;&#26679;&#23637;&#29616;&#20102;&#33529;&#26524;&#24076;&#26395;&#35753;&#26356;&#22810;&#20154;&#19982;&#20854;&#29983;&#24577;&#24314;&#31435;&#38271;&#26399;&#32852;&#31995;&#30340;&#37326;&#24515;&#12290;&#23545;&#20110;&#23398;&#26657;&#32780;&#35328;&#65292;&#24265;&#20215;&#30828;&#20214;+&#24378;&#22823;&#30340;&#21019;&#20316;&#36719;&#20214;&#22871;&#20214;&#65292;&#26500;&#25104;&#20102;&#38381;&#29615;&#12290;Macbook Neo &#30340;&#30828;&#20214;&#24615;&#33021;&#25110;&#35768;&#19981;&#31639;&#24378;&#21170;&#65292;&#20294;&#36275;&#20197;&#22312;&#27599;&#21488;&#35774;&#22791;&#32422; 4&#8211;5 &#24180;&#30340;&#29983;&#21629;&#21608;&#26399;&#20013;&#25552;&#20379;&#31283;&#23450;&#12289;&#21487;&#29992;&#30340;&#20307;&#39564;&#65292;&#35753;&#20351;&#29992;&#32773;&#36880;&#27493;&#34701;&#20837;&#33529;&#26524;&#30340;&#26381;&#21153;&#20307;&#31995;&#12290;&#20174;&#36825;&#20010;&#35282;&#24230;&#26469;&#30475;&#65292;MacBook Neo &#26356;&#20687;&#26159;&#33529;&#26524;&#25243;&#21521; Z &#19990;&#20195;&#19982; Alpha &#19990;&#20195;&#30340;&#19968;&#26522;&#8220;&#29983;&#24577;&#38170;&#28857;&#8221;&#12290;</p><p>&#22826;&#22810;&#28040;&#36153;&#32773;&#21644;&#25968;&#30721;&#21338;&#20027;&#36807;&#20110;&#32858;&#28966;&#20110;&#33529;&#26524;&#20135;&#21697;&#26159;&#21542;&#28843;&#37239;&#12289;&#26159;&#21542;&#26377;&#21019;&#26032;&#65292;&#21364;&#24536;&#35760;&#20102;&#33529;&#26524;&#30340;&#26469;&#26102;&#36335;&#8212;&#8212;&#25945;&#32946;&#30828;&#20214;&#24066;&#22330;&#28145;&#26893;&#20110;&#23427;&#30340;&#22522;&#22240;&#20043;&#20013;&#65292;&#20170;&#22825;&#30340;&#25104;&#21151;&#28304;&#20110;&#25968;&#21313;&#24180;&#21069;&#30340;&#31215;&#32047;&#65292;&#32780;&#29616;&#22312;&#23427;&#38656;&#35201;&#34917;&#19978;&#26368;&#36817;&#21313;&#20960;&#24180;&#30340;&#31354;&#32570;&#12290;&#23545;&#20110;&#26412;&#21608;&#25253;&#30340;&#35835;&#32773;&#26469;&#35828;&#65292;Neo &#22823;&#27010;&#29575;&#19981;&#26159;&#20320;&#30340;&#33756;&#12290;&#20294;&#36825;&#24182;&#19981;&#22952;&#30861;&#23427;&#25104;&#20026;&#19968;&#27454;&#26497;&#20855;&#38024;&#23545;&#24615;&#12289;&#20063;&#39047;&#20855;&#37326;&#24515;&#30340;&#20135;&#21697;&#8212;&#8212;&#19981;&#26159;&#29992;&#26469;&#36186;&#24555;&#38065;&#30340;&#65292;&#32780;&#26159;&#33529;&#26524;&#20026;&#26410;&#26469;&#20108;&#21313;&#24180;&#30340;&#29983;&#24577;&#29256;&#22270;&#25152;&#20570;&#30340;&#19968;&#27425;&#38271;&#26399;&#25276;&#27880;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-125/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-notepad">Notepad.exe &#8212; Swift &#26032;&#29305;&#24615;&#30340;&#31532;&#19968;&#20010;&#23454;&#39564;&#22330;</a></strong></h3><p>Swift 6 &#20986;&#20102;&#26032;&#35821;&#27861;&#65311;Xcode &#22826;&#37325;&#65292;Playground &#21448;&#22826;&#24930;&#12290;Notepad.exe &#35753;&#20320;&#22312; 30 &#31186;&#20869;&#20889;&#20195;&#30721;&#12289;&#36305;&#32467;&#26524;&#65292;&#19987;&#27880;&#39564;&#35777;&#24819;&#27861;&#26412;&#36523;&#12290;&#25903;&#25345;&#22810;&#29256;&#26412;&#24037;&#20855;&#38142;&#20999;&#25442;&#65292;&#38598;&#25104;&#27169;&#25311;&#22120;&#65292;&#38543;&#24320;&#38543;&#29992;&#12290;</p><p><a href="https://l.fatbobman.com/sb-notepad">&#128640; &#31435;&#21363;&#20351;&#29992; &#8594;</a></p><div><hr></div><h2><strong>&#21407;&#21019;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/sendable-nsmanagedobjectcontext/?utm_source=fatbobman%20weekly%20issue%20126&amp;utm_medium=web">&#36328;&#22495;&#20256;&#36882; NSManagedObjectContext &#20026;&#20160;&#20040;&#22312; Swift 6.2 &#20013;&#19981;&#20877;&#25253;&#38169;&#65311;&#30495;&#27491;&#30340;&#21464;&#21270;&#19981;&#22312;&#32534;&#35793;&#22120;</a></strong></h3><p>&#24403;&#21516;&#19968;&#27573;&#19982;&#24182;&#21457;&#26377;&#20851;&#30340;&#20195;&#30721;&#22312;&#26087;&#29256; Xcode &#20013;&#26080;&#27861;&#36890;&#36807;&#65292;&#21364;&#22312;&#26032;&#29256; Xcode 26&#65288;Swift 6.2&#65289;&#20013;&#39034;&#21033;&#32534;&#35793;&#26102;&#65292;&#20320;&#31532;&#19968;&#26102;&#38388;&#20250;&#24819;&#21040;&#20160;&#20040;&#65311;&#24456;&#22810;&#20154;&#26368;&#21021;&#30340;&#21028;&#26029;&#21487;&#33021;&#26159; Swift &#32534;&#35793;&#22120;&#30340;&#24182;&#21457;&#20998;&#26512;&#65288;&#22914; Region-Based Isolation&#65289;&#21448;&#36827;&#21270;&#20102;&#65292;&#20294;&#29616;&#23454;&#24182;&#27809;&#26377;&#36825;&#20040;&#31616;&#21333;&#12290;&#26412;&#25991;&#35760;&#24405;&#20102;&#25105;&#26368;&#36817;&#36935;&#21040;&#30340;&#19968;&#27425;&#38750;&#24120;&#26377;&#24847;&#24605;&#30340;&#25490;&#26597;&#36807;&#31243;&#65306;&#20174;&#27979;&#35797;&#22833;&#36133;&#20986;&#21457;&#65292;&#36890;&#36807;&#26500;&#24314;&#26368;&#23567;&#22797;&#29616;&#29992;&#20363;&#65292;&#19968;&#27493;&#27493;&#36861;&#28335;&#21040; Core Data &#30340; SDK interface&#65292;&#26368;&#32456;&#21457;&#29616;&#65292;&#38382;&#39064;&#30340;&#20851;&#38190;&#24182;&#19981;&#23436;&#20840;&#22312; Swift &#32534;&#35793;&#22120;&#26412;&#36523;&#65292;&#32780;&#26159;&#26694;&#26550;&#30340;&#23548;&#20837;&#35821;&#20041;&#21457;&#29983;&#20102;&#21464;&#21270;&#8212;&#8212;&#22312;&#26032;&#30340; SDK &#20013;&#65292;<code>NSManagedObjectContext</code> &#33719;&#24471;&#20102; <code>NS_SWIFT_SENDABLE</code> &#31561;&#23439;&#26631;&#27880;&#65292;&#20351;&#20854;&#22312; Swift &#20013;&#25317;&#26377;&#20102; <code>Sendable</code> &#35821;&#20041;&#12290;</p><blockquote><p>&#23613;&#31649; SwiftData &#26159;&#26410;&#26469;&#33529;&#26524;&#29983;&#24577;&#26368;&#37325;&#35201;&#30340;&#25345;&#20037;&#21270;&#26694;&#26550;&#65292;&#20294;&#20316;&#20026;&#20854;&#22522;&#30784;&#30340; Core Data &#24182;&#27809;&#26377;&#34987;&#33529;&#26524;&#20919;&#33853;&#12290;&#22312;&#36807;&#21435;&#20960;&#24180;&#20013;&#65292;&#33529;&#26524;&#19968;&#30452;&#22312;&#40664;&#40664;&#25913;&#21892;&#20854;&#22312; Swift 6 &#20013;&#30340;&#20860;&#23481;&#24615;&#21644;&#24182;&#21457;&#20307;&#39564;&#65292;&#36825;&#26159;&#19968;&#20010;&#24456;&#22909;&#30340;&#29616;&#35937;&#12290;</p></blockquote><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0126-01">Swift &#35821;&#35328; 2 &#26376;&#26032;&#21160;&#24577; (What&#8217;s new in Swift: February 2026 Edition)</a></strong></h3><p><a href="https://bsky.app/profile/karenchu.online">Karen Chu</a> &#21644; <a href="https://bsky.app/profile/davelester.dev">Dave Lester</a> &#22312;&#23448;&#26041;&#21338;&#23458;&#19978;&#25972;&#29702;&#20102; 2026 &#24180; 2 &#26376; Swift &#31038;&#21306;&#30340;&#29983;&#24577;&#21160;&#24577;&#12290;&#20869;&#23481;&#19981;&#20165;&#28085;&#30422;&#20102; Swift &#22312; <a href="https://swiftlang.github.io/event-fosdem/">FOSDEM</a>&#65288;&#20840;&#29699;&#26368;&#22823;&#24320;&#28304;&#20250;&#35758;&#65289;&#19978;&#30340;&#27963;&#36291;&#34920;&#29616;&#65292;&#36824;&#25512;&#20171;&#20102;&#22810;&#39033;&#37325;&#30917;&#30340;&#24320;&#28304;&#36827;&#23637;&#19982; Swift Evolution &#25552;&#26696;&#12290;&#20854;&#20013;&#30340; <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0506-advanced-observation-tracking.md">SE-0506</a> &#23588;&#20026;&#35753;&#25105;&#24778;&#21916;&#12290;&#35813;&#25552;&#26696;&#20026; <code>withObservationTracking</code> &#22686;&#21152;&#20102; Options &#21442;&#25968;&#65292;&#24320;&#21457;&#32773;&#29616;&#22312;&#21487;&#20197;&#31934;&#30830;&#25511;&#21046;&#26159;&#35266;&#23519;&#21464;&#21270;&#21069;&#65288;willSet&#65289;&#12289;&#21464;&#21270;&#21518;&#65288;didSet&#65289;&#36824;&#26159;&#23545;&#35937;&#30340;&#29983;&#21629;&#21608;&#26399;&#65288;&#22914; deinit&#65289;&#12290;&#24182;&#19988;&#36890;&#36807; <code>withContinuousObservationTracking</code> &#26080;&#38656;&#20877;&#25163;&#21160;&#36882;&#24402;&#27880;&#20876;&#65292;&#21363;&#21487;&#23454;&#29616;&#31283;&#23450;&#12289;&#33258;&#21160;&#24490;&#29615;&#30340;&#36830;&#32493;&#20107;&#20214;&#36861;&#36394;&#12290;</p><blockquote><p>SE-0506 &#25552;&#26696;&#30340;&#36890;&#36807;&#24847;&#20041;&#37325;&#22823;&#12290;&#23427;&#19981;&#20165;&#23436;&#32654;&#34917;&#40784;&#20102;&#29366;&#24577;&#36861;&#36394;&#30340;&#26102;&#26426;&#25511;&#21046;&#21644;&#36830;&#32493;&#24615;&#33021;&#21147;&#65292;&#26356;&#26631;&#24535;&#30528; Swift &#21407;&#29983;&#30340; Observation &#24050;&#32463;&#24443;&#24213;&#25104;&#29087;&#8212;&#8212;&#23427;&#19981;&#20877;&#20165;&#20165;&#26159; SwiftUI &#30340;&#8220;&#19987;&#23646;&#38468;&#24248;&#8221;&#65292;&#32780;&#26159;&#30495;&#27491;&#34581;&#21464;&#20026;&#20102; Swift &#35821;&#35328;&#20013;&#36275;&#20197;&#24212;&#23545;&#21508;&#31181;&#24037;&#19994;&#32423;&#12289;&#39640;&#24615;&#33021;&#29366;&#24577;&#27969;&#35843;&#24230;&#30340;&#26680;&#24515;&#22522;&#30784;&#35774;&#26045;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-02">&#20889;&#22312; 2026 &#24180;&#30340; macOS &#36755;&#20837;&#27861;&#24320;&#21457;&#35268;&#33539;</a></strong></h3><p><a href="https://vchewing.github.io/README.html">vChewing &#32500;&#38899;&#36755;&#20837;&#27861;</a> &#30340;&#20316;&#32773; <a href="https://x.com/shikisuen">ShikiSuen</a> &#22522;&#20110;&#22810;&#24180;&#28145;&#32789; macOS &#36755;&#20837;&#27861;&#30340;&#24320;&#21457;&#32463;&#39564;&#65292;&#20840;&#38754;&#26803;&#29702;&#20102; InputMethodKit (IMK) &#30340;&#21382;&#21490;&#21253;&#34993;&#65292;&#20197;&#21450;&#23427;&#22312; Swift 6 &#20005;&#26684;&#24182;&#21457;&#26816;&#26597;&#19979;&#26292;&#38706;&#20986;&#30340;&#31181;&#31181;&#30171;&#28857;&#12290;&#25991;&#31456;&#28145;&#20837;&#25506;&#35752;&#20102; NSConnection &#30340;&#21629;&#21517;&#35268;&#33539;&#12289;&#21551;&#29992;&#27801;&#30418;&#30340;&#24517;&#35201;&#24615;&#12289;MainActor &#38548;&#31163;&#20914;&#31361;&#65292;&#20197;&#21450;&#39640;&#39057;&#20013;&#33521;&#20999;&#25442;&#65288;CapsLock&#65289;&#23548;&#33268;&#30340; ARC &#25317;&#22581;&#12289;macOS 26 Liquid Glass &#26426;&#21046;&#19979; NSWindow &#20869;&#23384;&#19981;&#37322;&#25918;&#31561;&#26840;&#25163;&#38382;&#39064;&#12290;&#38754;&#23545;&#33529;&#26524;&#8220;&#19978;&#21476;&#26694;&#26550;&#8221;&#19982;&#29616;&#20195; Swift &#24182;&#21457;&#27169;&#22411;&#30340;&#30896;&#25758;&#65292;&#20316;&#32773;&#27809;&#26377;&#20572;&#30041;&#22312;&#25265;&#24616;&#19978;&#65292;&#32780;&#26159;&#25552;&#20986;&#20102;&#19968;&#22871;&#20687;&#8220;&#39118;&#38505;&#25511;&#21046;&#27169;&#22411;&#8221;&#19968;&#26679;&#30340;&#24037;&#31243;&#35268;&#33539;&#8212;&#8212;&#23558;&#25511;&#21046;&#22120;&#36864;&#21270;&#20026;&#32431;&#36716;&#21457;&#23618;&#12289;&#25226;&#19994;&#21153;&#36923;&#36753;&#21093;&#31163;&#21040;&#24369;&#24341;&#29992; Session&#12289;&#20351;&#29992;&#20869;&#23384;&#33258;&#26597;&#33258;&#23613;&#12289;&#24443;&#24213;&#36991;&#24320; IMKCandidates &#31561;&#12290;</p><blockquote><p>&#21487;&#36149;&#30340;&#26159;&#65292;ShikiSuen &#22522;&#20110;&#19978;&#36848;&#24605;&#36335;&#24320;&#21457;&#24182;&#24320;&#28304;&#20102; <a href="https://github.com/vChewing/IMKSwift">IMKSwift</a> &#24211;&#12290;&#23427;&#20026; Swift 6+ &#25552;&#20379;&#20102; <code>@MainActor</code> &#23436;&#25972;&#38548;&#31163;&#30340; <code>IMKInputSessionController</code> &#22522;&#31867;&#65292;&#23436;&#32654;&#35206;&#30422;&#20102;&#21407;&#29983; <code>IMKInputController</code> &#30340;&#24182;&#21457;&#22320;&#38647;&#21306;&#12290;&#22914;&#26524;&#20320;&#38656;&#35201;&#24320;&#21457; macOS &#26700;&#38754;&#31471;&#24212;&#29992;&#25110;&#36755;&#20837;&#27861;&#65292;&#36825;&#20010;&#24211;&#33021;&#35753;&#20320;&#26080;&#38656;&#25163;&#21160; Hack&#65292;&#23601;&#33021;&#20889;&#20986;&#31867;&#22411;&#23433;&#20840;&#12289;&#26080; data-race &#35686;&#21578;&#30340;&#29616;&#20195;&#20195;&#30721;&#65292;&#38750;&#24120;&#20540;&#24471;&#23398;&#20064;&#19982;&#20351;&#29992;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-03">SwiftUI &#30340;&#27915;&#33905;&#24335;&#26550;&#26500;&#65306;Swift Effects &#23454;&#36341; (SwiftUI, Swift Effects: A Beautiful Onion Architecture)</a></strong></h3><p>&#22312; SwiftUI &#20013;&#22788;&#29702;&#25968;&#25454;&#21152;&#36733;&#29366;&#24577;&#20960;&#20046;&#26159;&#27599;&#20010;&#24212;&#29992;&#37117;&#20250;&#38754;&#23545;&#30340;&#38382;&#39064;&#65306;<code>loading</code>&#12289;<code>loaded</code>&#12289;<code>failed</code> &#19977;&#31181;&#29366;&#24577;&#24448;&#24448;&#20276;&#38543;&#30528;&#32593;&#32476;&#35831;&#27714;&#12289;&#32531;&#23384;&#12289;&#26085;&#24535;&#35760;&#24405;&#31561;&#21103;&#20316;&#29992;&#36923;&#36753;&#65292;&#24456;&#23481;&#26131;&#35753;&#35270;&#22270;&#20195;&#30721;&#36880;&#28176;&#21464;&#24471;&#33219;&#32959;&#12290;<a href="https://www.linkedin.com/in/salgara/">Salgara</a> &#22312;&#26412;&#25991;&#20013;&#25552;&#20986;&#20102;&#19968;&#31181;&#31867;&#20284; Onion Architecture &#30340;&#24605;&#36335;&#65306;&#36890;&#36807; ViewState + Effect Handlers &#23558; <code>Fetch</code>&#12289;&#32531;&#23384;&#12289;&#26085;&#24535;&#31561;&#21103;&#20316;&#29992;&#25286;&#20998;&#20026;&#22810;&#20010;&#21487;&#32452;&#21512;&#23618;&#32423;&#65292;&#24182;&#21033;&#29992; AsyncSequence &#19982;&#21487;&#27880;&#20837;&#30340; Effect Handler &#39537;&#21160;&#29366;&#24577;&#21464;&#21270;&#65292;&#20351; UI &#20165;&#26681;&#25454;&#29366;&#24577;&#36827;&#34892;&#28210;&#26579;&#12290;&#36825;&#26679;&#19968;&#26469;&#65292;&#35270;&#22270;&#20445;&#25345;&#32431;&#31929;&#65292;&#32780;&#25968;&#25454;&#33719;&#21462;&#19982;&#21103;&#20316;&#29992;&#21017;&#27839;&#30528;&#19968;&#26465;&#28165;&#26224;&#30340;&#8220;Effect &#31649;&#36947;&#8221;&#36880;&#23618;&#27969;&#21160;&#12290;&#21516;&#26102;&#65292;&#36825;&#31181;&#32467;&#26500;&#20063;&#22825;&#28982;&#20855;&#22791;&#33391;&#22909;&#30340;&#21487;&#27979;&#35797;&#24615;&#8212;&#8212;&#27979;&#35797;&#20195;&#30721;&#21487;&#20197;&#30452;&#25509;&#25318;&#25130;&#24182;&#27169;&#25311;&#25968;&#25454;&#28304;&#36820;&#22238;&#20540;&#65292;&#20174;&#32780;&#39564;&#35777;&#23436;&#25972;&#30340;&#29366;&#24577;&#36716;&#25442;&#27969;&#31243;&#12290;</p><blockquote><p>Salgara &#22374;&#35328;&#65292;&#36825;&#31181;&#26550;&#26500;&#30446;&#21069;&#20173;&#28982;&#26159;&#23454;&#39564;&#24615;&#30340;&#65306;&#21407;&#22411;&#20248;&#20808;&#65292;&#24182;&#23581;&#35797;&#23558;&#19968;&#20999;&#35270;&#20026;&#35270;&#22270;&#65288;Everything as a View&#65289;&#12290;&#38543;&#30528;&#36234;&#26469;&#36234;&#22810;&#24320;&#21457;&#32773;&#20174;&#19981;&#21516;&#35282;&#24230;&#24605;&#32771;&#24182;&#23581;&#35797;&#26500;&#24314;&#26356;&#31526;&#21512; SwiftUI &#29305;&#24615;&#30340;&#26550;&#26500;&#65292;&#36825;&#31867;&#25506;&#32034;&#19981;&#20165;&#21487;&#33021;&#35753; SwiftUI &#26412;&#36523;&#21463;&#30410;&#65292;&#20063;&#26377;&#26426;&#20250;&#21453;&#36807;&#26469;&#20016;&#23500;&#25972;&#20010;&#22768;&#26126;&#24335;&#32534;&#31243;&#33539;&#24335;&#65292;&#32780;&#19981;&#20877;&#21482;&#26159;&#22797;&#21046;&#20854;&#20182; UI &#26694;&#26550;&#30340;&#26082;&#26377;&#23454;&#36341;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-04">Spec-Driven Development&#65306;&#24403; AI &#20889;&#20195;&#30721;&#20043;&#21518;</a></strong></h3><p>&#38543;&#30528; Cursor&#12289;Claude Code &#31561; AI &#32534;&#31243;&#26234;&#33021;&#20307;&#65288;Agent&#65289;&#30340;&#26222;&#21450;&#65292;&#24320;&#21457;&#32773;&#20204;&#27491;&#38754;&#20020;&#19968;&#20010;&#26032;&#30340;&#30171;&#28857;&#65306;&#24403; AI &#33021;&#22312;&#20960;&#20998;&#38047;&#20869;&#36328;&#36234;&#20960;&#21313;&#20010;&#25991;&#20214;&#29983;&#25104;&#19978;&#21315;&#34892;&#20195;&#30721;&#26102;&#65292;&#20154;&#31867;&#35813;&#22914;&#20309;&#26377;&#25928;&#23457;&#26597;&#65311;&#21448;&#35813;&#22914;&#20309;&#24212;&#23545; AI &#22312;&#38271;&#27969;&#31243;&#20013;&#36880;&#28176;&#20986;&#29616;&#30340;&#8220;&#19978;&#19979;&#25991;&#36951;&#24536;&#65288;Context Decay&#65289;&#8221;&#19982;&#24187;&#35273;&#38382;&#39064;&#65311;&#20026;&#27492;&#65292;&#19968;&#31181;&#26032;&#30340;&#24320;&#21457;&#33539;&#24335;&#27491;&#22312;&#36880;&#28176;&#25104;&#24418;&#65306;Spec-Driven Development&#65288;SDD&#65289;&#12290;&#22312;&#36825;&#19968;&#27169;&#24335;&#19979;&#65292;&#24320;&#21457;&#32773;&#30340;&#20027;&#35201;&#20219;&#21153;&#19981;&#20877;&#26159;&#30452;&#25509;&#32534;&#20889;&#20195;&#30721;&#65292;&#32780;&#26159;&#23450;&#20041;&#28165;&#26224;&#30340;&#35268;&#26684;&#65288;Spec&#65289;&#65292;&#20877;&#30001; AI &#26681;&#25454;&#36825;&#20123;&#35268;&#26684;&#29983;&#25104;&#23454;&#29616;&#12290;</p><p><a href="https://x.com/rbbtsn0w">Snow</a> &#36890;&#36807;&#22235;&#31687;&#25991;&#31456;&#31995;&#32479;&#26803;&#29702;&#20102;&#36825;&#19968;&#24605;&#36335;&#65306;&#20174; &#8220;Vibe Coding&#8221; &#30340;&#23616;&#38480;&#20986;&#21457;&#65292;&#20171;&#32461;&#20197;&#35268;&#26684;&#20026;&#26680;&#24515;&#30340;&#24320;&#21457;&#27969;&#31243;&#65292;&#24182;&#36827;&#19968;&#27493;&#25506;&#35752;&#35268;&#26684;&#22312;&#26410;&#26469;&#36719;&#20214;&#24037;&#31243;&#20013;&#30340;&#35282;&#33394;&#8212;&#8212;&#20195;&#30721;&#25110;&#35768;&#19981;&#20877;&#26159;&#39033;&#30446;&#30340;&#20013;&#24515;&#65292;&#32780;&#21482;&#26159;&#35268;&#26684;&#30340;&#34893;&#29983;&#29289;&#12290;</p><blockquote><p>&#22312; AI &#36880;&#28176;&#25215;&#25285;&#23454;&#29616;&#32454;&#33410;&#30340;&#26102;&#20195;&#65292;&#36719;&#20214;&#24037;&#31243;&#30340;&#37325;&#24515;&#25110;&#35768;&#27491;&#22312;&#20174;&#8220;&#20889;&#20195;&#30721;&#8221;&#36716;&#21521;&#8220;&#34920;&#36798;&#24847;&#22270;&#8221;&#12290;SDD &#23581;&#35797;&#22312;&#20154;&#31867;&#30340;&#27169;&#31946;&#24847;&#22270;&#19982; AI &#30340;&#26080;&#24046;&#21035;&#29983;&#25104;&#20043;&#38388;&#65292;&#24314;&#31435;&#19968;&#23618;&#24378;&#26377;&#21147;&#30340;&#32422;&#26463;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-05">&#20026; SwiftUI Preview &#26500;&#24314;&#19968;&#20010; Mini Linker (Building a Mini Linker for SwiftUI Previews)</a></strong></h3><p>&#22312; Xcode 26.3 &#30340; mcpbridge &#25552;&#20379;&#30340;&#20247;&#22810;&#24037;&#20855;&#20013;&#65292;<code>RenderPreview</code> &#21487;&#20197;&#30452;&#25509;&#36820;&#22238; SwiftUI Preview &#30340;&#25130;&#22270;&#65292;&#26041;&#20415; AI &#36827;&#34892;&#20998;&#26512;&#12290;&#23545;&#20110;&#26242;&#26102;&#26080;&#27861;&#20351;&#29992; Xcode 26.3 mcpbridge &#30340;&#24320;&#21457;&#32773;&#65292;<a href="https://hachyderm.io/@IronHam">Hesham Salman</a> &#22312;&#26412;&#25991;&#20013;&#20171;&#32461;&#30340;&#24605;&#36335;&#20197;&#21450;&#37197;&#22871;&#24037;&#20855;&#65292;&#21516;&#26679;&#21487;&#20197;&#23454;&#29616;&#31867;&#20284;&#30340;&#33021;&#21147;&#12290;&#20854;&#25216;&#26415;&#20142;&#28857;&#22312;&#20110;&#21033;&#29992; SwiftSyntax &#26500;&#24314;&#22768;&#26126;&#20381;&#36182;&#22270;&#65292;&#20877;&#36890;&#36807; BFS &#25214;&#20986;&#24403;&#21069; Preview &#30495;&#27491;&#38656;&#35201;&#30340;&#26368;&#23567;&#28304;&#25991;&#20214;&#38598;&#21512;&#65292;&#20174;&#32780;&#36991;&#20813;&#32534;&#35793;&#25972;&#20010; App Target &#24102;&#26469;&#30340;&#26500;&#24314;&#31561;&#24453;&#12290;</p><blockquote><p>&#26412;&#25991;&#30340;&#31934;&#21326;&#22312;&#20110;&#24605;&#36335;&#65306;&#21033;&#29992; SwiftSyntax + BFS &#24555;&#36895;&#23450;&#20301; Preview &#20381;&#36182;&#30340;&#20195;&#30721;&#29255;&#27573;&#12290;&#36807;&#21435; SwiftSyntax &#30340;&#20351;&#29992;&#38376;&#27099;&#36739;&#39640;&#65292;&#20294;&#22312; AI &#36741;&#21161;&#24320;&#21457;&#36880;&#28176;&#26222;&#21450;&#30340;&#20170;&#22825;&#65292;&#23427;&#27491;&#36880;&#28176;&#25104;&#20026;&#29702;&#35299;&#20195;&#30721;&#32467;&#26500;&#30340;&#37325;&#35201;&#22522;&#30784;&#35774;&#26045;&#12290;&#21363;&#20415;&#20320;&#19981;&#20687; Hesham Salman &#37027;&#26679;&#29087;&#32451;&#25484;&#25569;&#35813;&#24037;&#20855;&#65292;&#20102;&#35299;&#20854;&#22522;&#26412;&#33021;&#21147;&#21518;&#65292;&#20063;&#21487;&#20197;&#20511;&#21161; AI &#23558;&#31867;&#20284;&#24605;&#36335;&#33853;&#22320;&#8212;&#8212;&#32780;&#36825;&#31867;&#24037;&#20855;&#22312;&#36807;&#21435;&#24448;&#24448;&#21482;&#23646;&#20110;&#23569;&#25968;&#29087;&#24713;&#32534;&#35793;&#22120;&#24037;&#20855;&#38142;&#30340;&#24320;&#21457;&#32773;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-06">Swift &#30340;&#35268;&#27169;&#21270;&#23454;&#36341;&#65306;TelemetryDeck &#30340;&#20998;&#26512;&#26381;&#21153; (Swift at scale: building the TelemetryDeck analytics service)</a></strong></h3><p>&#24456;&#22810;&#20154;&#35752;&#35770; Swift on Server &#26102;&#65292;&#20851;&#27880;&#28857;&#24448;&#24448;&#20572;&#30041;&#22312;&#8220;&#33021;&#19981;&#33021;&#29992;&#8221;&#65292;&#32780; TelemetryDeck &#32473;&#20986;&#30340;&#21017;&#26159;&#19968;&#20010;&#26356;&#23454;&#38469;&#30340;&#31572;&#26696;&#65306;&#19981;&#20165;&#33021;&#29992;&#65292;&#32780;&#19988;&#24050;&#32463;&#25903;&#25745;&#36215;&#19968;&#39033;&#38754;&#21521;&#24320;&#21457;&#32773;&#12289;&#27599;&#26376;&#22788;&#29702;&#36229;&#36807; 1600 &#19975;&#29992;&#25143;&#25968;&#25454;&#30340; analytics &#26381;&#21153;&#12290;<a href="https://social.telemetrydeck.com/@daniel">Daniel Jilg</a> &#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#22238;&#39038;&#20102;&#22242;&#38431;&#20026;&#20309;&#36873;&#25321; Swift + Vapor &#26500;&#24314;&#21518;&#31471;&#65292;&#24182;&#20998;&#20139;&#20102;&#19981;&#23569;&#26469;&#33258;&#29983;&#20135;&#29615;&#22659;&#30340;&#32463;&#39564;&#65306;&#20363;&#22914;&#22914;&#20309;&#20511;&#21161; <code>Codable</code> &#31616;&#21270; API &#32534;&#35299;&#30721;&#19982;&#26657;&#39564;&#12289;&#20026;&#20160;&#20040;&#24212;&#35753; DTO &#26356;&#36148;&#36817; controller&#12289;&#20197;&#21450;&#20026;&#20309;&#32531;&#23384; TTL&#12289;API &#29256;&#26412;&#31649;&#29702;&#21644;&#38169;&#35823;&#30417;&#25511;&#36825;&#20123;&#8220;&#32769;&#29983;&#24120;&#35848;&#8221;&#65292;&#22312;&#35268;&#27169;&#21270;&#30340;&#29983;&#20135;&#29615;&#22659;&#20013;&#24448;&#24448;&#25165;&#26159;&#30495;&#27491;&#30340;&#25252;&#22478;&#27827;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0126-07">&#26159;&#26102;&#20505;&#21578;&#21035; SwiftGen &#20102;&#21527;&#65311; (Get Rid of Your SwiftGen Dependency)</a></strong></h3><p>&#24456;&#38271;&#19968;&#27573;&#26102;&#38388;&#65292;&#24320;&#21457;&#32773;&#38656;&#35201;&#20381;&#36182;&#31867;&#20284; SwiftGen &#36825;&#26679;&#30340;&#24037;&#20855;&#26469;&#35299;&#20915; Apple &#36164;&#28304;&#31995;&#32479;&#20013;&#30340;&#19968;&#20010;&#32769;&#38382;&#39064;&#65306;&#36164;&#28304;&#35775;&#38382;&#26159;&#23383;&#31526;&#20018;&#31867;&#22411;&#65288;stringly-typed&#65289;&#12290;&#26080;&#35770;&#26159; localization key&#12289;&#22270;&#29255;&#21517;&#31216;&#36824;&#26159;&#39068;&#33394;&#36164;&#20135;&#65292;&#19968;&#26086;&#25340;&#20889;&#38169;&#35823;&#65292;&#24448;&#24448;&#21482;&#33021;&#22312;&#36816;&#34892;&#26102;&#25165;&#20250;&#26292;&#38706;&#38382;&#39064;&#12290;<a href="https://www.linkedin.com/in/asserusama/">Asser Osama</a> &#25351;&#20986;&#65292;&#38543;&#30528; String Catalog&#65288;.xcstrings&#65289;&#19982; Asset Catalog Symbols &#30340;&#24341;&#20837;&#19982;&#36880;&#27493;&#23436;&#21892;&#65292;Xcode &#24050;&#32463;&#33021;&#22815;&#22312;&#32534;&#35793;&#38454;&#27573;&#33258;&#21160;&#29983;&#25104;&#36164;&#28304;&#31526;&#21495;&#65292;&#36825;&#31181;&#21407;&#29983;&#33021;&#21147;&#22312;&#19981;&#23569;&#29616;&#20195;&#39033;&#30446;&#20013;&#25110;&#35768;&#24050;&#32463;&#36275;&#20197;&#26367;&#20195; SwiftGen&#12290;</p><blockquote><p>&#38656;&#35201;&#35828;&#26126;&#30340;&#26159;&#65292;&#8220;&#31227;&#38500;&#20381;&#36182;&#8221;&#30340;&#21069;&#25552;&#26159;&#39033;&#30446;&#23436;&#20840;&#36816;&#34892;&#22312;&#26631;&#20934;&#30340; Xcode &#29983;&#24577;&#20013;&#12290;Xcode &#30340;&#31526;&#21495;&#29983;&#25104;&#23646;&#20110;&#26500;&#24314;&#31995;&#32479;&#20869;&#37096;&#26426;&#21046;&#65292;&#32780;&#19981;&#26159; Swift &#32534;&#35793;&#22120;&#25110; Swift Package Manager &#30340;&#33021;&#21147;&#8212;&#8212;&#36825;&#24847;&#21619;&#30528;&#23545;&#20110;&#20351;&#29992; Bazel&#12289;Buck &#31561;&#38750;&#26631;&#20934;&#26500;&#24314;&#31995;&#32479;&#30340;&#22242;&#38431;&#26469;&#35828;&#65292;SwiftGen &#20173;&#28982;&#21487;&#33021;&#26159;&#26356;&#21487;&#31227;&#26893;&#12289;&#26356;&#21487;&#25511;&#30340;&#36873;&#25321;&#12290;</p></blockquote><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0126-08">SwiftUI Agent Skill</a></strong></h3><p>&#30001; <a href="https://x.com/twostraws">Paul Hudson</a> &#32534;&#20889;&#30340; SwiftUI Agent Skill&#65292;&#26088;&#22312;&#24110;&#21161;&#24320;&#21457;&#32773;&#32534;&#20889;&#26356;&#26234;&#33021;&#12289;&#26356;&#31616;&#27905;&#12289;&#26356;&#29616;&#20195;&#30340; SwiftUI &#20195;&#30721;&#12290;&#35813;&#39033;&#30446;&#21457;&#24067;&#20165;&#20004;&#22825;&#20415;&#33719;&#24471;&#20102; 1k+ Star&#12290;</p><blockquote><p>&#22312;&#36807;&#21435;&#20960;&#21608;&#20013;&#65292;&#26412;&#21608;&#25253;&#24050;&#32463;&#25512;&#33616;&#20102;&#19981;&#23569;&#30693;&#21517;&#24320;&#21457;&#32773;&#32534;&#20889;&#30340;&#21508;&#31867; Skill&#12290;&#23613;&#31649;&#36825;&#20123; Skill &#37117;&#20957;&#32858;&#20102;&#20316;&#32773;&#30340;&#32463;&#39564;&#65292;&#20294;&#25105;&#20173;&#19981;&#24314;&#35758;&#24320;&#21457;&#32773;&#30452;&#25509;&#8220;&#25343;&#26469;&#21363;&#29992;&#8221;&#12290;&#33267;&#23569;&#24212;&#22312;&#37319;&#29992;&#21069;&#23436;&#25972;&#38405;&#35835;&#19968;&#36941;&#65306;Skill &#26356;&#20687;&#26159;&#20316;&#32773;&#23545;&#33258;&#24049;&#25968;&#21313;&#29978;&#33267;&#19978;&#30334;&#31687;&#25991;&#31456;&#32463;&#39564;&#30340;&#25552;&#28860;&#65292;&#32780;&#19981;&#26159;&#21487;&#20197;&#30452;&#25509;&#26367;&#20195;&#24605;&#32771;&#30340;&#8220;&#26368;&#20339;&#23454;&#36341;&#8221;&#12290;&#24320;&#21457;&#32773;&#22312;&#29702;&#35299;&#20854;&#32972;&#21518;&#30340;&#35774;&#35745;&#24605;&#36335;&#21518;&#65292;&#20877;&#26681;&#25454;&#33258;&#24049;&#30340;&#24320;&#21457;&#20064;&#24815;&#19982;&#39033;&#30446;&#38656;&#27714;&#36827;&#34892;&#21462;&#33293;&#65292;&#36825;&#26679;&#25165;&#33021;&#26356;&#22823;&#22320;&#21457;&#25381;&#23427;&#20204;&#30340;&#20215;&#20540;&#12290;</p></blockquote><h2><strong>&#27963;&#21160;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-10">LET&#8217;S VISION 2026&#65292;&#24320;&#31080;&#21862;&#65281;</a></strong></h3><p>&#20316;&#20026;&#22312;&#20013;&#22269;&#20030;&#21150;&#12289;&#38754;&#21521;&#20840;&#29699;&#30340; Apple &#29983;&#24577;&#19979;&#30340;&#22823;&#20250;&#65292;&#20170;&#24180;&#30340; LET&#8217;S VISION &#23558;&#20250;&#26377;&#32422; 20 &#22330;&#28436;&#35762;&#12289;&#36229;&#36807; 80 &#20010;&#23637;&#20301;&#65292;&#27426;&#36814;&#21069;&#24448;&#23448;&#32593;&#21644;&#31080;&#21153;&#24179;&#21488;&#20102;&#35299;&#26356;&#22810;&#20449;&#24687;&#12290;</p><ul><li><p><strong>&#26102;&#38388;&#21450;&#22320;&#28857;</strong>&#65306;03.28 - 03.29&#65292;&#19978;&#28023;&#183;&#28437;&#27827;&#27902;&#20250;&#35758;&#20013;&#24515;</p></li><li><p><strong><a href="https://letsvision.swiftgg.team/">&#27963;&#21160;&#23448;&#32593;</a></strong></p></li><li><p><strong><a href="https://l.fatbobman.com/w0125-10">&#33719;&#21462;&#38376;&#31080;</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #125]]></title><description><![CDATA[OpenClaw Is Impressive &#8212; I Just Don&#8217;t Really Need It (Yet)]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 02 Mar 2026 12:02:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Ovah!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ovah!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ovah!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 424w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 848w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 1272w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ovah!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp" width="1436" height="672" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:672,&quot;width&quot;:1436,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12152,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/189608684?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ovah!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 424w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 848w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 1272w, https://substackcdn.com/image/fetch/$s_!Ovah!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0adce669-0139-4c00-8084-17c45e975f1b_1436x672.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>OpenClaw Is Impressive &#8212; I Just Don&#8217;t Really Need It (Yet)</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-125/">Read on web &#8594;</a></p><p>On the morning of March 1st, I received a message from OpenClaw. It was part of a scheduled task I had set up after installing it: on the first day of every month, it sends me a summary of the main tasks it executed on my behalf over the past month.</p><p>Reading through that rather sparse report, I found myself pausing. At this stage, I don&#8217;t think I actually need a personal AI agent. To be honest, if it hadn&#8217;t sent that message yesterday, I might have almost forgotten it was even there.</p><p>After the OpenClaw project name was finalized, I still couldn&#8217;t quite resist the stream of flashy demos filling my social media timeline. I dug out an idle Mac mini M4 and followed the setup guides to get everything running. During the first few days, I spent some time studying how others were using it, trying to see whether it could naturally fit into my own life and workflow.</p><p>Eventually, though, I came to realize that&#8212;at least given my current workload and habits&#8212;many traditional tools that have already matured are more than sufficient for my needs. Even when I do need an agent loop on mobile devices, using more focused, single-purpose tools often results in less configuration overhead and a lower cognitive burden overall.</p><p>A year ago, few people would have expected that CLI tools would see a resurgence at a time when GUIs have long been the default. In a similar way, before OpenClaw gained traction, hardly anyone anticipated the sudden emergence of so many OpenClaw-like projects. I have little doubt that most people will eventually have their own personal AI assistants. OpenClaw presents one possible vision of that future&#8212;very much from a hacker&#8217;s perspective. But what form these assistants will ultimately take, and how they will balance privacy, security, and efficiency, remains an open question.</p><p>From one angle, having an intelligent assistant does seem pretty cool. Still, life without one feels just as calm and comfortable. For now, I&#8217;ll let &#129438; rest quietly on my mini&#8212;until the day I truly need to wake it up.</p><p><a href="https://fatbobman.com/en/weekly/issue-124/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-notepad">Notepad.exe &#8212; A Notepad for Developers</a></strong></h3><p>Notepad.exe is a lightweight coding scratchpad for macOS, built for experiments, snippets, and rapid prototyping. Open it, write your code, and run it &#8212; no project setup required.</p><p><a href="https://l.fatbobman.com/sb-notepad">&#128640; </a><strong><a href="https://l.fatbobman.com/sb-notepad">Download for macOS &#8594;</a></strong></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-01">Building Lists: A High-Performance Diffable Data Source Framework</a></strong></h3><p>After integrating <code>UICollectionViewDiffableDataSource</code> with TCA, <a href="https://mastodon.social/@IronHam@hachyderm.io">Hesham Salman</a> noticed more than 100 UI stalls per minute. A deeper investigation revealed that <code>NSDiffableDataSourceSnapshot</code> heavily relies on Objective-C&#8217;s <code>NSOrderedSet</code> under the hood. In a reactive architecture where state updates frequently, repeated snapshot reconstruction leads to substantial hashing costs and Objective-C bridging overhead. To address this, Hesham built a pure Swift alternative, <a href="https://github.com/Iron-Ham/Lists">ListKit</a>. By leveraging <code>ContiguousArray</code>, a two-level diff algorithm, and lazily constructed reverse indices, snapshot construction performance improved by several hundred times.</p><blockquote><p>In imperative frameworks, developers can precisely control refresh timing, so diff performance issues may not be immediately obvious. But as reactive programming increasingly makes its way into UIKit, traditional assumptions and techniques must adapt to new refresh patterns. Yesterday&#8217;s &#8220;best practice APIs&#8221; can quietly become today&#8217;s performance bottlenecks.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-02">SwiftUI Charts caused major stutter in my app &#8212; replacing it with Path fixed everything</a></strong></h3><p>There is no doubt that Swift Charts provides a clean declarative API and polished visual output, making it a go-to choice for many developers. However, even years after its release, when dealing with large datasets and high-frequency interactions, its reliance on numerous fine-grained view components can amplify SwiftUI&#8217;s diffing and layout costs, resulting in noticeable performance degradation. After reassessing his needs, <a href="https://medium.com/@oscarberggren082">Oscar Berggren</a> replaced Charts with a custom <code>Shape</code> built on <code>Path</code>, completely eliminating drag-related stutters.</p><blockquote><p>As highlighted in the ListKit article above, when high-frequency state updates (such as gesture-driven refreshes) combine with heavyweight view construction (hundreds of <code>LineMark</code> instances), performance bottlenecks become almost inevitable. In such cases, stepping back to lower-level drawing APIs like <code>Path</code> often yields more predictable and stable results.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-03">We added an MCP server to our macOS app and learned a lot the hard way</a></strong></h3><p>Adding MCP support to a macOS app sounds like just exposing a few more interfaces &#8212; until you actually try it. <a href="https://medium.com/@charidimos">Charidimos Chaintoutis</a> discovered this firsthand while implementing native Swift MCP support for unclutr: the gap between &#8220;works in dev&#8221; and &#8220;users can configure, diagnose, and install it&#8221; is wider than expected.</p><p>The article details challenges around stdio transport, client handshakes, launcher configuration, and macOS sandbox restrictions&#8212;particularly the friction between sandboxing and spawning external processes. These constraints ultimately forced them to disable MCP support in the Mac App Store version and offer it only in the direct-download build. The security model they arrived at is especially instructive: separating read and write tools, requiring explicit deletion calls, enforcing absolute paths, supporting dry runs, and always moving files to Trash rather than permanently deleting them. These are lessons learned the hard way.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-04">Array expression trailing closures in Swift</a></strong></h3><p>In this article, <a href="https://www.linkedin.com/in/artem-mirzabekian/">Artem Mirzabekian</a> introduces the accepted Swift Evolution proposal <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0508-array-expression-trailing-closures.md">SE-0508</a>. The proposal removes a long-standing syntactic special case: array and dictionary type expressions previously could not be followed directly by trailing closures. With this restriction lifted, building collections using result builders (for example, <code>let items = [String] { "First"; "Second" }</code>) becomes far more natural. It also enables calling <code>callAsFunction</code> directly after array literals, such as <code>["a", "b", "c"] { $0.uppercased() }</code>.</p><blockquote><p>At first glance, this may seem like a minor syntactic refinement. In reality, it eliminates inconsistencies between collection types and other types, further smoothing Swift&#8217;s surface. Language progress does not always come from bold new features&#8212;sometimes it comes from patiently sanding down long-standing rough edges.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-05">Mastering Geometry in SwiftUI - GeometryReader, GeometryProxy &amp; onGeometryChange</a></strong></h3><p>For a long time, developers relied almost exclusively on <code>GeometryReader</code> to obtain a view&#8217;s size or position. However, <code>GeometryReader</code> is itself a layout container that expands to fill all available space. This &#8220;greedy&#8221; behavior often causes unexpected layout issues for those unfamiliar with its mechanics. In this comprehensive article, <a href="https://www.linkedin.com/in/sdunagar/">Sagar Unagar</a> revisits SwiftUI&#8217;s geometry system from an architectural perspective. He compares the traditional <code>GeometryReader</code> + <code>PreferenceKey</code> pattern, the <code>Layout</code> protocol introduced in iOS 16, and the <code>.onGeometryChange</code> modifier introduced in iOS 18. Rather than merely listing APIs, the article explains how geometry fits into SwiftUI&#8217;s proposal-driven layout system.</p><blockquote><p>If you approach SwiftUI with a command-style mindset and attempt to &#8220;control&#8221; layout directly, it will likely feel awkward. But once your mental model aligns with its negotiation-based design, you begin to see that SwiftUI&#8217;s expressive ceiling is much higher than it first appears.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-07">Xcode Assistant Copilot Server</a></strong></h3><p>Xcode 26.3 introduced support for Codex and Claude Code, officially bringing agent capabilities into the IDE workflow. But not every developer uses those services. Developed by <a href="https://x.com/fercabj">Fernando Romiti</a>, Xcode Assistant Copilot Server offers an alternative for GitHub Copilot subscribers. It is a Swift-based local service that translates Xcode&#8217;s OpenAI-compatible requests into GitHub Copilot API calls. <strong>However, it should not be mistaken for a simple protocol adapter.</strong></p><p>In its default mode, it acts as a transparent proxy, forwarding Xcode&#8217;s <code>/v1/chat/completions</code> requests to Copilot. Once Agent mode is enabled and MCP is configured, it runs a full local agent loop. When the Copilot model issues tool calls, the server intercepts them, executes the corresponding operations locally (via <code>xcrun mcpbridge</code> or permitted CLI tools), appends the results to the conversation, re-queries the model, and continues this cycle until a final response is produced and returned to Xcode.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-08">Foundation Models SDK for Python</a></strong></h3><p>Foundation Models SDK for Python is a recently released open-source project from Apple. Through a Swift bridge, it enables developers to <strong>directly invoke Apple Intelligence foundation models running on macOS (on-device) from a Python environment</strong>.</p><p>In modern LLM application development, evaluation is critical. Developers need to run large test suites to measure the impact of prompt adjustments and tool-calling strategies. Data-driven analysis of this kind has long been dominated by the Python ecosystem. This SDK fills that gap: developers can export real transcripts (JSON) from Swift, then reproduce on-device inference behavior in Python and perform batch analysis, scoring, clustering, and error attribution as if processing ordinary datasets.</p><blockquote><p>In effect, Apple is signaling a standardized workflow for AI application development: <strong>Swift handles on-device integration and user experience, while Python powers offline evaluation and iterative optimization.</strong></p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-09">vphone-cli: Running a Real iPhone on Your Mac</a></strong></h3><p>When Apple introduced Apple Intelligence in 2024, it also unveiled PCC (Private Cloud Compute), a privacy-focused infrastructure running on Apple Silicon servers. Its significance lies not merely in &#8220;offloading AI to the cloud&#8221;, but in extending the iPhone&#8217;s security model to server-side environments. Apple even released research materials and virtual research environments to allow security researchers to audit PCC nodes locally.</p><p>Starting with cloudOS 26, Apple added components related to <code>vphone600ap</code> in PCC firmware. The community quickly took notice. Building on <a href="https://github.com/wh1te4ever/super-tart-vphone-writeup">in-depth reverse engineering work</a> by <a href="https://x.com/wh1te4ever">Hyungyu Seo</a> and others, <a href="https://x.com/Lakr233">Lakr</a> developed vphone-cli, which operationalizes this virtualization mechanism. By leveraging private APIs from <code>Virtualization.framework</code>, it creates a fully functional virtual iPhone research environment on macOS. Unlike the Xcode Simulator, this setup runs real iOS firmware, executing the full boot chain from start to finish.</p><blockquote><p>What makes this development fascinating is not merely jailbreak research or firmware analysis, but the broader signal it sends: Apple appears to be externalizing the iOS security architecture it has refined for over a decade, extending it to reshape its cloud computing infrastructure.</p></blockquote><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-125?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>OpenClaw &#19981;&#38169;&#65292;&#20294;&#25105;&#22909;&#20687;&#27809;&#26377;&#37027;&#20040;&#38656;&#35201;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-125/">&#32593;&#39029;&#29256;</a></strong></p><p>3 &#26376; 1 &#26085;&#26089;&#19978;&#65292;&#25105;&#25910;&#21040;&#20102; OpenClaw &#21457;&#26469;&#30340;&#20449;&#24687;&#12290;&#36825;&#26159;&#25105;&#22312;&#23433;&#35013;&#23427;&#20043;&#21518;&#35774;&#32622;&#30340;&#19968;&#20010;&#23450;&#26102;&#20219;&#21153;&#65306;&#27599;&#20010;&#26376;&#30340;&#31532;&#19968;&#22825;&#65292;&#21521;&#25105;&#27719;&#25253;&#36807;&#21435;&#19968;&#20010;&#26376;&#23427;&#20026;&#25105;&#25191;&#34892;&#36807;&#30340;&#20027;&#35201;&#20219;&#21153;&#27719;&#24635;&#12290;&#30475;&#30528;&#27719;&#24635;&#20013;&#23525;&#23525;&#25968;&#35821;&#65292;&#25105;&#19981;&#30001;&#24471;&#38519;&#20837;&#20102;&#24605;&#32771;&#8212;&#8212;&#29616;&#38454;&#27573;&#65292;&#25105;&#20284;&#20046;&#30495;&#30340;&#36824;&#19981;&#38656;&#35201;&#19968;&#20010;&#20010;&#20154;&#26234;&#33021;&#20307;&#12290;&#35828;&#23454;&#35805;&#65292;&#22914;&#26524;&#19981;&#26159;&#23427;&#26152;&#22825;&#21457;&#26469;&#30340;&#36825;&#26465;&#28040;&#24687;&#65292;&#25105;&#20960;&#20046;&#24050;&#32463;&#24573;&#30053;&#20102;&#23427;&#30340;&#23384;&#22312;&#12290;</p><p>&#22312; OpenClaw &#39033;&#30446;&#21517;&#31216;&#27491;&#24335;&#30830;&#23450;&#20043;&#21518;&#65292;&#25105;&#36824;&#26159;&#27809;&#33021;&#25269;&#25377;&#20303;&#31038;&#20132;&#23186;&#20307;&#26102;&#38388;&#32447;&#19978;&#37027;&#20123;&#28843;&#37239;&#28436;&#31034;&#30340;&#35825;&#24785;&#65292;&#32763;&#20986;&#20102;&#19968;&#21488;&#38386;&#32622;&#30340; Mac mini M4&#65292;&#29031;&#30528;&#25945;&#31243;&#25240;&#33150;&#20102;&#36215;&#26469;&#12290;&#26368;&#21021;&#20960;&#22825;&#65292;&#25105;&#20063;&#35748;&#30495;&#30740;&#31350;&#36807;&#20854;&#20182;&#20154;&#30340;&#20351;&#29992;&#22330;&#26223;&#65292;&#23581;&#35797;&#23558;&#23427;&#34701;&#20837;&#33258;&#24049;&#30340;&#29983;&#27963;&#21644;&#24037;&#20316;&#27969;&#20013;&#12290;&#20294;&#21518;&#26469;&#25105;&#36880;&#28176;&#24847;&#35782;&#21040;&#65292;&#33267;&#23569;&#20197;&#25105;&#30446;&#21069;&#30340;&#24037;&#20316;&#24378;&#24230;&#21644;&#20351;&#29992;&#20064;&#24815;&#26469;&#30475;&#65292;&#19968;&#20123;&#24050;&#32463;&#36275;&#22815;&#25104;&#29087;&#30340;&#20256;&#32479;&#24037;&#20855;&#65292;&#20381;&#28982;&#21487;&#20197;&#24456;&#22909;&#22320;&#28385;&#36275;&#25105;&#30340;&#38656;&#27714;&#12290;&#21363;&#20415;&#38656;&#35201;&#22312;&#31227;&#21160;&#35774;&#22791;&#19978;&#36827;&#34892; Agent loop&#65292;&#30452;&#25509;&#20351;&#29992;&#21151;&#33021;&#26356;&#32858;&#28966;&#30340;&#21333;&#19968;&#29992;&#36884;&#20135;&#21697;&#65292;&#21453;&#32780;&#33021;&#20943;&#23569;&#37197;&#32622;&#21644;&#20351;&#29992;&#19978;&#30340;&#24515;&#26234;&#36127;&#25285;&#12290;</p><p>&#19968;&#24180;&#21069;&#65292;&#25110;&#35768;&#27809;&#26377;&#22810;&#23569;&#20154;&#20250;&#24819;&#21040;&#65292;&#22312; GUI &#24050;&#32463;&#25104;&#20026;&#40664;&#35748;&#24418;&#24577;&#30340;&#20170;&#22825;&#65292;CLI &#20250;&#37325;&#26032;&#36814;&#26469;&#19968;&#36718;&#22238;&#28526;&#12290;&#21516;&#26679;&#65292;&#22312; OpenClaw &#28779;&#29190;&#20043;&#21069;&#65292;&#20063;&#24456;&#23569;&#26377;&#20154;&#39044;&#26009;&#21040;&#65292;&#22914;&#20170;&#20250;&#28044;&#29616;&#20986;&#22914;&#27492;&#22810;&#30340; OpenClaw-like &#39033;&#30446;&#12290;&#25105;&#24182;&#19981;&#24576;&#30097;&#65292;&#26410;&#26469;&#22823;&#22810;&#25968;&#20154;&#37117;&#20250;&#25317;&#26377;&#23646;&#20110;&#33258;&#24049;&#30340;&#20010;&#20154;&#26234;&#33021;&#21161;&#25163;&#12290;OpenClaw &#20197;&#19968;&#31181;&#30456;&#24403;&#26497;&#23458;&#30340;&#26041;&#24335;&#65292;&#23637;&#31034;&#20102;&#20854;&#20013;&#30340;&#19968;&#31181;&#21487;&#33021;&#24615;&#65307;&#20294;&#26234;&#33021;&#20307;&#21161;&#25163;&#26368;&#32456;&#20250;&#20197;&#24590;&#26679;&#30340;&#24418;&#24577;&#23384;&#22312;&#65292;&#21448;&#23558;&#22914;&#20309;&#22312;&#38544;&#31169;&#12289;&#23433;&#20840;&#19982;&#25928;&#29575;&#20043;&#38388;&#21462;&#24471;&#24179;&#34913;&#65292;&#30452;&#21040;&#29616;&#22312;&#20381;&#28982;&#27809;&#26377;&#19968;&#20010;&#30830;&#23450;&#30340;&#31572;&#26696;&#12290;</p><p>&#20174;&#26576;&#31181;&#35282;&#24230;&#26469;&#30475;&#65292;&#25317;&#26377;&#19968;&#20010;&#26234;&#33021;&#21161;&#25163;&#30830;&#23454;&#25402;&#37239;&#65307;&#20294;&#27809;&#26377;&#23427;&#65292;&#20063;&#19997;&#27627;&#19981;&#24433;&#21709;&#25105;&#20139;&#21463;&#24403;&#19979;&#30340;&#24179;&#38745;&#19982;&#23433;&#36920;&#12290;&#23601;&#35753; &#129438; &#22312;&#25105;&#30340; mini &#37324;&#22909;&#22909;&#20241;&#24687;&#21543;&#65292;&#31561;&#21040;&#25105;&#30495;&#27491;&#38656;&#35201;&#21796;&#37266;&#23427;&#30340;&#37027;&#19968;&#22825;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-124/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-notepad">Notepad.exe &#8212; &#38543;&#24320;&#38543;&#29992;&#30340;&#20195;&#30721;&#33609;&#31295;&#26412;</a></strong></h3><p>&#36731;&#37327;&#32423; macOS &#20195;&#30721;&#33609;&#31295;&#24037;&#20855;&#65292;&#19987;&#20026;&#20195;&#30721;&#23454;&#39564;&#12289;&#29255;&#27573;&#35760;&#24405;&#21644;&#24555;&#36895;&#21407;&#22411;&#32780;&#29983;&#12290;&#25171;&#24320;&#21363;&#29992;&#65292;&#20889;&#20195;&#30721;&#12289;&#36305;&#20195;&#30721;&#65292;&#38646;&#39033;&#30446;&#37197;&#32622;&#12290;</p><p><strong><a href="https://l.fatbobman.com/sb-notepad">&#128640; &#20813;&#36153;&#19979;&#36733; &#8594;</a></strong></p><div><hr></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-01">Diffable &#30340;&#24615;&#33021;&#38519;&#38449;&#19982; ListKit &#30772;&#23616; (Building Lists: A High-Performance Diffable Data Source Framework)</a></strong></h3><p><a href="https://mastodon.social/@IronHam@hachyderm.io">Hesham Salman</a> &#22312;&#23558; <code>UICollectionViewDiffableDataSource</code> &#19982; TCA &#37197;&#21512;&#20351;&#29992;&#21518;&#65292;&#21457;&#29616;&#21407;&#29983; DiffableDataSource &#23548;&#33268;&#20102;&#27599;&#20998;&#38047; 100 &#22810;&#27425;&#30340;&#21345;&#39039;&#12290;&#28145;&#20837;&#20998;&#26512;&#21518;&#65292;&#20182;&#21457;&#29616; <code>NSDiffableDataSourceSnapshot</code> &#24213;&#23618;&#20854;&#23454;&#37325;&#24230;&#20381;&#36182; Objective-C &#30340; <code>NSOrderedSet</code>&#12290;&#22312;&#21709;&#24212;&#24335;&#26550;&#26500;&#20013;&#65292;&#30001;&#20110;&#29366;&#24577;&#30340;&#39640;&#39057;&#21047;&#26032;&#65292;Snapshot &#30340;&#39057;&#32321;&#37325;&#24314;&#24341;&#21457;&#20102;&#24040;&#22823;&#30340;&#21704;&#24076;&#35745;&#31639;&#19982; Obj-C &#26725;&#25509;&#24320;&#38144;&#12290;&#20026;&#27492;&#65292;Hesham &#24320;&#21457;&#20102;&#19968;&#20010;&#32431; Swift &#23454;&#29616;&#30340;&#26367;&#20195;&#21697; <a href="https://github.com/Iron-Ham/Lists">ListKit</a>&#12290;&#36890;&#36807;&#20351;&#29992; <code>ContiguousArray</code>&#12289;&#21452;&#23618; Diff &#31639;&#27861;&#20197;&#21450;&#24310;&#36831;&#26500;&#24314;&#21453;&#21521;&#32034;&#24341;&#65292;&#23558;&#26500;&#24314; Snapshot &#30340;&#36895;&#24230;&#25552;&#21319;&#20102;&#25968;&#30334;&#20493;&#12290;</p><blockquote><p>&#22312;&#21629;&#20196;&#24335;&#26694;&#26550;&#20013;&#65292;&#30001;&#20110;&#24320;&#21457;&#32773;&#21487;&#20197;&#31934;&#30830;&#25511;&#21046;&#21047;&#26032;&#26102;&#26426;&#65292;&#22240;&#27492; Diff &#30340;&#25928;&#29575;&#38382;&#39064;&#21487;&#33021;&#26292;&#38706;&#24471;&#24182;&#19981;&#26126;&#26174;&#12290;&#20294;&#38543;&#30528;&#36234;&#26469;&#36234;&#22810;&#30340;&#24320;&#21457;&#32773;&#23558;&#21709;&#24212;&#24335;&#32534;&#31243;&#24341;&#20837; UIKit&#65292;&#19968;&#20123;&#20256;&#32479;&#30340;&#24605;&#32500;&#25110;&#25216;&#24039;&#38656;&#35201;&#26681;&#25454;&#26032;&#30340;&#21047;&#26032;&#26426;&#21046;&#26469;&#20570;&#35843;&#25972;&#65292;&#36807;&#21435;&#30340;&#8220;&#26368;&#20339;&#23454;&#36341; API&#8221;&#21487;&#33021;&#27491;&#22312;&#25104;&#20026;&#26032;&#30340;&#24615;&#33021;&#29942;&#39048;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-02">SwiftUI Charts &#24615;&#33021;&#36991;&#22353;&#65306;&#22238;&#24402;&#24213;&#23618; Path &#32472;&#21046; (SwiftUI Charts caused major stutter in my app &#8212; replacing it with Path fixed everything)</a></strong></h3><p>&#27595;&#24248;&#32622;&#30097;&#65292;Swift Charts &#25552;&#20379;&#20102;&#31616;&#27905;&#30340;&#22768;&#26126;&#24335;&#20307;&#39564;&#19982;&#31934;&#33268;&#30340;&#35270;&#35273;&#21576;&#29616;&#65292;&#33258;&#21457;&#24067;&#20197;&#26469;&#20415;&#25104;&#20026;&#19981;&#23569;&#24320;&#21457;&#32773;&#32472;&#21046;&#22270;&#34920;&#30340;&#39318;&#36873;&#12290;&#28982;&#32780;&#65292;&#21363;&#20415;&#22312;&#25512;&#20986;&#22810;&#24180;&#20043;&#21518;&#65292;&#24403;&#38754;&#23545;&#21253;&#21547;&#39640;&#39057;&#20132;&#20114;&#30340;&#22823;&#25968;&#25454;&#38598;&#22330;&#26223;&#26102;&#65292;&#20854;&#22522;&#20110;&#22823;&#37327;&#32454;&#31890;&#24230; View &#32452;&#21512;&#30340;&#23454;&#29616;&#26041;&#24335;&#65292;&#20173;&#21487;&#33021;&#25918;&#22823; SwiftUI &#30340; diff &#19982;&#24067;&#23616;&#25104;&#26412;&#65292;&#20174;&#32780;&#24341;&#21457;&#24615;&#33021;&#38382;&#39064;&#12290;<a href="https://medium.com/@oscarberggren082">Oscar Berggren</a> &#22312;&#35780;&#20272;&#33258;&#36523;&#38656;&#27714;&#21518;&#65292;&#25918;&#24323;&#20351;&#29992; Charts&#65292;&#20026;&#25240;&#32447;&#32472;&#21046;&#25913;&#29992;&#33258;&#23450;&#20041; <code>Shape</code> + <code>Path</code>&#65292;&#25104;&#21151;&#28040;&#38500;&#20102;&#25302;&#25341;&#36807;&#31243;&#20013;&#30340;&#21345;&#39039;&#12290;</p><blockquote><p>&#27491;&#22914;&#21069;&#25991; ListKit &#25152;&#25581;&#31034;&#30340;&#65292;&#24403;&#39640;&#39057;&#29366;&#24577;&#21464;&#26356;&#65288;&#20363;&#22914;&#25163;&#21183;&#39537;&#21160;&#30340;&#21047;&#26032;&#65289;&#21472;&#21152;&#22312;&#37325;&#37327;&#32423;&#23545;&#35937;&#26500;&#24314;&#65288;&#22823;&#37327; <code>LineMark</code>&#65289;&#20043;&#19978;&#26102;&#65292;&#24615;&#33021;&#29942;&#39048;&#24448;&#24448;&#19981;&#21487;&#36991;&#20813;&#12290;&#27492;&#26102;&#65292;&#36866;&#24230;&#22238;&#24402;&#26356;&#24213;&#23618;&#30340;&#32472;&#21046; API&#65288;&#22914; <code>Path</code>&#65289;&#65292;&#21453;&#32780;&#33021;&#22815;&#24102;&#26469;&#26356;&#31283;&#23450;&#12289;&#21487;&#25511;&#30340;&#34920;&#29616;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-03">&#32431; Swift MCP Server &#24320;&#21457;&#19982;&#20998;&#21457;&#36393;&#22353;&#23454;&#24405; (We added an MCP server to our macOS app and learned a lot the hard way)</a></strong></h3><p>&#20026; macOS &#24212;&#29992;&#28155;&#21152; MCP &#33021;&#21147;&#65292;&#21548;&#36215;&#26469;&#19981;&#36807;&#26159;&#22810;&#26292;&#38706;&#20960;&#20010;&#25509;&#21475;&#8212;&#8212;&#30452;&#21040;&#20320;&#30495;&#27491;&#21435;&#20570;&#12290;<a href="https://medium.com/@charidimos">Charidimos Chaintoutis</a> &#22312;&#20026;&#24212;&#29992; unclutr &#23454;&#29616;&#32431; Swift &#30340; MCP &#25903;&#25345;&#26102;&#21457;&#29616;&#65292;&#20174;&#8220;&#24320;&#21457;&#29615;&#22659;&#21487;&#36816;&#34892;&#8221;&#21040;&#8220;&#29992;&#25143;&#21487;&#37197;&#32622;&#12289;&#21487;&#35786;&#26029;&#12289;&#21487;&#20998;&#21457;&#8221;&#20043;&#38388;&#65292;&#20173;&#26377;&#30456;&#24403;&#38271;&#30340;&#19968;&#27573;&#36317;&#31163;&#12290;</p><p>&#25991;&#31456;&#35760;&#24405;&#20102;&#20182;&#22312; stdio &#36890;&#20449;&#12289;&#23458;&#25143;&#31471;&#25569;&#25163;&#12289;launcher &#37197;&#32622;&#20197;&#21450; macOS &#27801;&#30418;&#65288;Sandbox&#65289;&#38480;&#21046;&#31561;&#26041;&#38754;&#36935;&#21040;&#30340;&#38382;&#39064;&#65292;&#23588;&#20854;&#26159;&#27801;&#30418;&#29615;&#22659;&#19979;&#22806;&#37096;&#36827;&#31243;&#21796;&#36215;&#30340;&#26435;&#38480;&#20914;&#31361;&#65292;&#26368;&#32456;&#36843;&#20351;&#20182;&#20204;&#22312; Mac App Store &#29256;&#26412;&#20013;&#20851;&#38381; MCP &#21151;&#33021;&#65292;&#20165;&#22312;&#30452;&#35013;&#29256;&#26412;&#20013;&#25552;&#20379;&#25903;&#25345;&#12290;&#27492;&#22806;&#65292;&#22312;&#8220;&#22914;&#20309;&#23433;&#20840;&#22320;&#35753; AI &#25805;&#20316;&#29992;&#25143;&#25991;&#20214;&#8221;&#36825;&#19968;&#28857;&#19978;&#65292;&#20316;&#32773;&#24635;&#32467;&#20986;&#30340;&#23454;&#36341;&#32463;&#39564;&#23588;&#20026;&#20540;&#24471;&#21442;&#32771;&#65306;&#35835;&#20889;&#24037;&#20855;&#20998;&#31163;&#12289;&#21024;&#38500;&#24517;&#39035;&#26174;&#24335;&#35843;&#29992;&#12289;&#24378;&#21046;&#32477;&#23545;&#36335;&#24452;&#12289;&#25903;&#25345; Dry Run&#12289;&#32479;&#19968;&#20351;&#29992; Trash &#32780;&#38750;&#30828;&#21024;&#38500;&#12290;&#36825;&#20123;&#35774;&#35745;&#37117;&#26159;&#22312;&#36393;&#36807;&#36275;&#22815;&#22810;&#22353;&#20043;&#21518;&#25165;&#33021;&#24471;&#21040;&#30340;&#32463;&#39564;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-04">&#35299;&#38145;&#25968;&#32452;&#19982;&#23383;&#20856;&#30340;&#23614;&#38543;&#38381;&#21253;&#35821;&#27861; (Array expression trailing closures in Swift)</a></strong></h3><p><a href="https://www.linkedin.com/in/artem-mirzabekian/">Artem Mirzabekian</a> &#22312;&#26412;&#25991;&#20013;&#20171;&#32461;&#20102;&#19968;&#20010;&#24050;&#32463;&#36890;&#36807;&#30340;&#25552;&#26696;&#65306;<a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0508-array-expression-trailing-closures.md">SE-0508</a>&#12290;&#35813;&#25552;&#26696;&#31227;&#38500;&#20102; Swift &#35821;&#27861;&#20013;&#30340;&#19968;&#20010;&#8220;&#21382;&#21490;&#29305;&#20363;&#8221;&#65306;&#25968;&#32452;&#19982;&#23383;&#20856;&#31867;&#22411;&#34920;&#36798;&#24335;&#27492;&#21069;&#26080;&#27861;&#30452;&#25509;&#36319;&#38543; trailing closure&#12290;&#38543;&#30528;&#36825;&#19968;&#38480;&#21046;&#34987;&#35299;&#38500;&#65292;&#21033;&#29992; Result Builder &#26500;&#24314;&#38598;&#21512;&#31867;&#22411;&#65288;&#20363;&#22914; <code>let items = [String] { "First"; "Second" }</code>&#65289;&#23558;&#21464;&#24471;&#26356;&#21152;&#33258;&#28982;&#65292;&#21516;&#26102;&#20063;&#20801;&#35768;&#22312;&#25968;&#32452;&#23383;&#38754;&#37327;&#21518;&#30452;&#25509;&#35302;&#21457; <code>callAsFunction</code>&#65288;&#22914; <code>["a", "b", "c"] { $0.uppercased() }</code>&#65289;&#12290;</p><blockquote><p>&#36825;&#30475;&#20284;&#21482;&#26159;&#19968;&#27425;&#35821;&#27861;&#23618;&#38754;&#30340;&#32454;&#33410;&#35843;&#25972;&#65292;&#21364;&#36827;&#19968;&#27493;&#28040;&#38500;&#20102;&#38598;&#21512;&#31867;&#22411;&#19982;&#26222;&#36890;&#31867;&#22411;&#20043;&#38388;&#30340;&#35299;&#26512;&#24046;&#24322;&#65292;&#35753;&#35821;&#35328;&#22312;&#34920;&#36798;&#19968;&#33268;&#24615;&#19978;&#26356;&#36827;&#19968;&#27493;&#12290;&#26377;&#26102;&#20505;&#65292;&#35821;&#35328;&#30340;&#36827;&#27493;&#24182;&#38750;&#26469;&#33258;&#23439;&#22823;&#30340;&#26032;&#29305;&#24615;&#65292;&#32780;&#26159;&#26469;&#33258;&#23545;&#37027;&#20123;&#23384;&#22312;&#22810;&#24180;&#30340;&#23567;&#29781;&#30133;&#30340;&#25345;&#32493;&#25171;&#30952;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-05">&#37325;&#22609; SwiftUI &#24067;&#23616;&#24515;&#26234;&#65306;&#21578;&#21035; GeometryReader &#28389;&#29992; (Mastering Geometry in SwiftUI - GeometryReader, GeometryProxy &amp; onGeometryChange)</a></strong></h3><p>&#24456;&#38271;&#19968;&#27573;&#26102;&#38388;&#37324;&#65292;&#24320;&#21457;&#32773;&#33509;&#24819;&#33719;&#21462;&#35270;&#22270;&#30340;&#23610;&#23544;&#25110;&#20301;&#32622;&#65292;&#20960;&#20046;&#21482;&#33021;&#20381;&#36182; <code>GeometryReader</code>&#12290;&#28982;&#32780;&#65292;<code>GeometryReader</code> &#26412;&#36136;&#19978;&#26159;&#19968;&#20010;&#20250;&#21344;&#28385;&#25152;&#26377;&#21487;&#29992;&#31354;&#38388;&#30340;&#24067;&#23616;&#23481;&#22120;&#65292;&#36825;&#31181;&#8220;&#36138;&#23146;&#8221;&#30340;&#29305;&#24615;&#65292;&#24120;&#24120;&#35753;&#19981;&#29087;&#24713;&#20854;&#34892;&#20026;&#30340;&#24320;&#21457;&#32773;&#38519;&#20837;&#24067;&#23616;&#22256;&#22659;&#12290;<a href="https://www.linkedin.com/in/sdunagar/">Sagar Unagar</a> &#22312;&#26412;&#25991;&#20013;&#31995;&#32479;&#26803;&#29702;&#20102; SwiftUI &#20960;&#20309;&#20307;&#31995;&#30340;&#28436;&#36827;&#36335;&#24452;&#19982;&#24515;&#26234;&#27169;&#22411;&#65292;&#23545;&#27604;&#20102;&#20256;&#32479;&#30340; <code>GeometryReader</code> + <code>PreferenceKey</code> &#32452;&#21512;&#12289;iOS 16 &#24341;&#20837;&#30340; <code>Layout</code> &#21327;&#35758;&#65292;&#20197;&#21450; iOS 18 &#24102;&#26469;&#30340; <code>.onGeometryChange</code> &#20462;&#39280;&#31526;&#12290;&#20174;&#26550;&#26500;&#35270;&#35282;&#35299;&#37322;&#20102;&#20960;&#20309;&#20449;&#24687;&#22312; proposal-driven &#24067;&#23616;&#31995;&#32479;&#20013;&#30340;&#20301;&#32622;&#65292;&#32780;&#19981;&#20165;&#20165;&#26159; API &#30340;&#20351;&#29992;&#26041;&#27861;&#12290;</p><blockquote><p>&#22312; SwiftUI &#20013;&#65292;&#22914;&#26524;&#20320;&#22987;&#32456;&#35797;&#22270;&#29992;&#21629;&#20196;&#24335;&#24605;&#32500;&#21435;&#8220;&#25511;&#21046;&#8221;&#24067;&#23616;&#65292;&#23427;&#24448;&#24448;&#20250;&#26174;&#24471;&#21035;&#25197;&#65307;&#20294;&#24403;&#20320;&#30340;&#29702;&#35299;&#19982;&#20854;&#21327;&#21830;&#24335;&#24067;&#23616;&#26426;&#21046;&#23545;&#40784;&#26102;&#65292;&#20320;&#20250;&#21457;&#29616;&#23427;&#30340;&#34920;&#36798;&#33021;&#21147;&#36828;&#27604;&#24819;&#35937;&#20013;&#26356;&#39640;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-06">iOS &#24320;&#21457; 2015-2025</a></strong></h3><p>&#36825;&#26159;&#19968;&#37096;&#29992;&#21313;&#24180;&#26102;&#20809;&#20889;&#23601;&#30340;&#20010;&#20154;&#25216;&#26415;&#32534;&#24180;&#21490;&#65292;&#20063;&#26159;&#19968;&#20221;&#20851;&#20110; iOS &#29983;&#24577;&#28436;&#36827;&#30340;&#29645;&#36149;&#35760;&#24405;&#12290;&#20174; 2015 &#24180;&#30340; Auto Layout &#36866;&#37197;&#12289;&#32452;&#20214;&#21270;&#28010;&#28526;&#65292;&#21040; 2025 &#24180;&#30340; Liquid Glass &#19982; AI Agent&#65292;<a href="https://x.com/daiming_cn">&#25140;&#38125;</a> &#20197;&#20146;&#21382;&#32773;&#30340;&#35270;&#35282;&#65292;&#20018;&#32852;&#36215;&#25216;&#26415;&#21464;&#36801;&#12289;&#31038;&#21306;&#25925;&#20107;&#19982;&#24037;&#31243;&#23454;&#36341;&#12290;&#25991;&#20013;&#26082;&#26377;&#23545;&#24213;&#23618;&#21407;&#29702;&#30340;&#28145;&#25366;&#65288;&#22914; dyld&#12289;Runtime&#12289;&#24615;&#33021;&#20248;&#21270;&#65289;&#65292;&#20063;&#26377;&#23545;&#25216;&#26415;&#21069;&#36744;&#30340;&#28145;&#20999;&#22238;&#26395;&#12290;&#20316;&#32773;&#35748;&#20026;&#65306;&#24213;&#23618;&#21407;&#29702;&#27704;&#36828;&#19981;&#36807;&#26102;&#65307;&#19981;&#35201;&#34987;&#26032;&#25216;&#26415;&#28966;&#34385;&#32465;&#26550;&#65307;&#25216;&#26415;&#22312;&#21464;&#65292;&#20294;&#23398;&#20064;&#30340;&#26041;&#27861;&#27809;&#21464;&#12290;&#20445;&#25345;&#22909;&#22855;&#19982;&#23398;&#20064;&#65292;&#26041;&#33021;&#22374;&#28982;&#38754;&#23545;&#26356;&#22810;&#30340;&#21313;&#24180;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-07">Xcode Assistant Copilot Server</a></strong></h3><p>Xcode 26.3 &#24341;&#20837;&#20102;&#23545; Codex &#19982; Claude Code &#30340;&#25903;&#25345;&#65292;&#23558;&#26234;&#33021;&#20307;&#33021;&#21147;&#27491;&#24335;&#24102;&#20837; IDE &#24037;&#20316;&#27969;&#12290;&#20294;&#24182;&#38750;&#27599;&#20301;&#24320;&#21457;&#32773;&#37117;&#20351;&#29992;&#36825;&#20123;&#26381;&#21153;&#12290;&#30001; <a href="https://x.com/fercabj">Fernando Romiti</a> &#24320;&#21457;&#30340; Xcode Assistant Copilot Server &#21017;&#20026; GitHub Copilot &#35746;&#38405;&#32773;&#25552;&#20379;&#20102;&#19968;&#26465;&#26367;&#20195;&#36335;&#24452;&#12290;&#23427;&#26159;&#19968;&#20010;&#22522;&#20110; Swift &#23454;&#29616;&#30340;&#26412;&#22320;&#26381;&#21153;&#65292;&#23558; Xcode &#30340; OpenAI &#20860;&#23481;&#35831;&#27714;&#36716;&#35793;&#20026; Copilot API &#35843;&#29992;&#12290;<strong>&#20294;&#19981;&#35201;&#23558;&#20854;&#35823;&#35299;&#20026;&#19968;&#20010;&#31616;&#21333;&#30340;&#25509;&#21475;&#36716;&#25442;&#23618;&#12290;</strong></p><p>&#22312;&#40664;&#35748;&#27169;&#24335;&#19979;&#65292;&#23427;&#30830;&#23454;&#20805;&#24403;&#36879;&#26126;&#20195;&#29702;&#65292;&#23558; Xcode &#30340; <code>/v1/chat/completions</code> &#35831;&#27714;&#36716;&#21457;&#33267; GitHub Copilot API&#65307;&#28982;&#32780;&#19968;&#26086;&#21551;&#29992; Agent &#27169;&#24335;&#24182;&#37197;&#32622; MCP&#65292;&#23427;&#20415;&#20250;&#22312;&#26412;&#22320;&#36816;&#34892;&#23436;&#25972;&#30340; agent loop&#12290;&#24403; Copilot &#27169;&#22411;&#21457;&#36215; tool call &#26102;&#65292;Server &#20250;&#22312;&#26412;&#22320;&#25318;&#25130;&#35843;&#29992;&#65292;&#36890;&#36807; <code>xcrun mcpbridge</code> &#25110;&#20801;&#35768;&#30340; CLI &#24037;&#20855;&#25191;&#34892;&#30456;&#24212;&#25805;&#20316;&#65292;&#23558;&#25191;&#34892;&#32467;&#26524;&#36861;&#21152;&#33267;&#23545;&#35805;&#19978;&#19979;&#25991;&#65292;&#20877;&#27425;&#35831;&#27714;&#27169;&#22411;&#25512;&#29702;&#65292;&#30452;&#33267;&#29983;&#25104;&#26368;&#32456;&#21709;&#24212;&#65292;&#26368;&#21518;&#25165;&#23558;&#32467;&#26524;&#36820;&#22238;&#32473; Xcode&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-08">Foundation Models SDK for Python</a></strong></h3><p>Foundation Models SDK for Python &#26159;&#33529;&#26524;&#23448;&#26041;&#36817;&#26399;&#25512;&#20986;&#30340;&#19968;&#20010;&#24320;&#28304;&#39033;&#30446;&#12290;&#23427;&#22312;&#24213;&#23618;&#36890;&#36807; Swift &#26725;&#25509;&#65292;&#35753;&#24320;&#21457;&#32773;&#33021;&#22815;<strong>&#30452;&#25509;&#22312; Python &#29615;&#22659;&#20013;&#35843;&#29992; macOS &#26412;&#22320;&#65288;On-Device&#65289;&#30340; Apple Intelligence &#22522;&#30784;&#27169;&#22411;</strong>&#12290;</p><p>&#22312;&#29616;&#20195;&#22823;&#27169;&#22411;&#24212;&#29992;&#24320;&#21457;&#20013;&#65292;&#35780;&#27979;&#65288;Evaluation&#65289;&#26159;&#26497;&#20854;&#37325;&#35201;&#30340;&#19968;&#29615;&#12290;&#24320;&#21457;&#32773;&#38656;&#35201;&#36816;&#34892;&#22823;&#37327;&#30340;&#27979;&#35797;&#29992;&#20363;&#65292;&#29992;&#21508;&#31181;&#27979;&#35797;&#38598;&#21435;&#39564;&#35777; Prompt &#35843;&#25972;&#25110;&#24037;&#20855;&#35843;&#29992;&#30340;&#20934;&#30830;&#29575;&#65292;&#32780;&#36825;&#20123;&#25968;&#25454;&#39537;&#21160;&#30340;&#24037;&#20316;&#22312;&#19994;&#30028;&#19968;&#30452;&#26159;&#30001; Python &#29983;&#24577;&#20027;&#23548;&#12290;&#35813; SDK &#24688;&#22909;&#22635;&#34917;&#20102;&#36825;&#19968;&#31354;&#30333;&#65306;&#24320;&#21457;&#32773;&#21487;&#20197;&#26080;&#32541;&#23454;&#29616;&#20174; Swift &#31471;&#23548;&#20986;&#30495;&#23454;&#36816;&#34892;&#30340; transcript&#65288;JSON&#65289;&#65292;&#28982;&#21518;&#22312; Python &#31471;&#21033;&#29992;&#35813; SDK &#21407;&#29983;&#22797;&#29616;&#31471;&#20391;&#30340;&#25512;&#29702;&#36807;&#31243;&#65292;&#24182;&#20687;&#22788;&#29702;&#26222;&#36890;&#25968;&#25454;&#19968;&#26679;&#36827;&#34892;&#25209;&#37327;&#20998;&#26512;&#12289;&#25171;&#20998;&#12289;&#32858;&#31867;&#19982;&#35823;&#24046;&#24402;&#22240;&#12290;</p><blockquote><p>&#36825;&#22522;&#26412;&#31561;&#20110; Apple &#22312;&#21521;&#24320;&#21457;&#32773;&#26126;&#31034;&#19968;&#31181;&#26631;&#20934;&#21270;&#30340; AI &#24212;&#29992;&#24320;&#21457;&#33539;&#24335;&#65306;<strong>Swift &#36127;&#36131;&#32447;&#19978;&#20307;&#39564;&#19982;&#31471;&#20391;&#38598;&#25104;&#65307;Python &#36127;&#36131;&#31163;&#32447;&#35780;&#27979;&#19982;&#36845;&#20195;&#20248;&#21270;&#12290;</strong></p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0125-09">vphone-cli&#65306;&#22312; Mac &#19978;&#36816;&#34892;&#19968;&#21488;&#30495;&#23454;&#30340; iPhone</a></strong></h3><p>2024 &#24180; Apple &#21457;&#24067; Apple Intelligence &#26102;&#65292;&#21516;&#27493;&#25512;&#20986;&#20102; PCC&#65288;Private Cloud Compute&#65289;&#65306;&#19968;&#22871;&#36816;&#34892;&#22312; Apple Silicon &#26381;&#21153;&#22120;&#19978;&#30340;&#38544;&#31169;&#35745;&#31639;&#22522;&#30784;&#35774;&#26045;&#12290;&#23427;&#30340;&#29305;&#21035;&#20043;&#22788;&#19981;&#21482;&#26159;&#8221;&#25226; AI &#35831;&#27714;&#25918;&#21040;&#20113;&#31471;&#22788;&#29702;&#8221;&#65292;&#32780;&#26159;&#25226; iPhone&#37027;&#22871;&#23433;&#20840;&#27169;&#22411;&#24310;&#20280;&#21040;&#20102;&#26381;&#21153;&#22120;&#20391;&#12290;&#20026;&#27492;&#65292;Apple &#36824;&#32597;&#35265;&#22320;&#24320;&#25918;&#20102;&#30740;&#31350;&#26448;&#26009;&#21644;&#34394;&#25311;&#30740;&#31350;&#29615;&#22659;&#65292;&#20801;&#35768;&#23433;&#20840;&#30740;&#31350;&#21592;&#22312;&#26412;&#22320;&#23457;&#35745; PCC &#33410;&#28857;&#30340;&#36719;&#20214;&#26632;&#12290;</p><p>&#20174; cloudOS 26 &#24320;&#22987;&#65292;&#33529;&#26524;&#22312; PCC &#22266;&#20214;&#20013;&#26032;&#22686;&#20102;&#19982; vphone600ap &#30456;&#20851;&#30340;&#32452;&#20214;&#12290;&#31038;&#21306;&#30340;&#26497;&#23458;&#20204;&#25935;&#38160;&#22320;&#25235;&#20303;&#20102;&#36825;&#20010;&#22865;&#26426;&#65292;&#22522;&#20110; <a href="https://x.com/wh1te4ever">Hyungyu Seo</a> &#31561;&#20154; <a href="https://github.com/wh1te4ever/super-tart-vphone-writeup">&#23545;&#35813;&#34394;&#25311;&#21270;&#26426;&#21046;&#30340;&#30828;&#26680;&#36870;&#21521;&#30740;&#31350;</a>&#65292;<a href="https://x.com/Lakr233">Lakr</a> &#24320;&#21457;&#30340; vphone-cli &#23558;&#20854;&#24443;&#24213;&#24037;&#31243;&#21270;&#65306;&#36890;&#36807;&#35843;&#29992; <code>Virtualization.framework</code> &#30340;&#31169;&#26377; API&#65292;&#30452;&#25509;&#22312; Mac &#19978;&#25645;&#20986;&#19968;&#22871;&#23436;&#25972;&#30340;&#34394;&#25311; iPhone &#30740;&#31350;&#29615;&#22659;&#12290;&#21644; Xcode &#27169;&#25311;&#22120;&#19981;&#21516;&#65292;&#36825;&#37324;&#36305;&#30340;&#26159;&#30495;&#23454;&#30340; iOS &#22266;&#20214;&#65292;&#23436;&#25972;&#30340;&#21551;&#21160;&#38142;&#20250;&#20174;&#22836;&#36208;&#19968;&#36941;&#12290;</p><blockquote><p>&#26377;&#24847;&#24605;&#30340;&#22320;&#26041;&#19981;&#21482;&#26159;&#36234;&#29425;&#25110;&#22266;&#20214;&#30740;&#31350;&#26412;&#36523;&#65292;&#26356;&#22312;&#20110;&#20174; PCC &#21040;&#36825;&#19968;&#31867;&#34394;&#25311;&#21270;&#24037;&#20855;&#25152;&#36879;&#38706;&#20986;&#30340;&#24213;&#23618;&#26041;&#21521;&#65306;Apple &#27491;&#22312;&#25226;&#23427;&#21313;&#22810;&#24180;&#26469;&#22312;&#31227;&#21160;&#31471;&#31215;&#32047;&#30340; iOS &#23433;&#20840;&#26550;&#26500;&#65292;&#24443;&#24213;&#22806;&#28322;&#24182;&#37325;&#22609;&#20113;&#31471;&#35745;&#31639;&#22522;&#30784;&#35774;&#26045;&#12290;</p></blockquote><h2><strong>&#27963;&#21160;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0125-10">LET&#8217;S VISION 2026&#65292;&#24320;&#31080;&#21862;&#65281;</a></strong></h3><p>&#20316;&#20026;&#22312;&#20013;&#22269;&#20030;&#21150;&#12289;&#38754;&#21521;&#20840;&#29699;&#30340; Apple &#29983;&#24577;&#19979;&#30340;&#22823;&#20250;&#65292;&#20170;&#24180;&#30340; LET&#8217;S VISION &#23558;&#20250;&#26377;&#32422; 20 &#22330;&#28436;&#35762;&#12289;&#36229;&#36807; 80 &#20010;&#23637;&#20301;&#65292;&#27426;&#36814;&#21069;&#24448;&#23448;&#32593;&#21644;&#31080;&#21153;&#24179;&#21488;&#20102;&#35299;&#26356;&#22810;&#20449;&#24687;&#12290;</p><ul><li><p><strong>&#26102;&#38388;&#21450;&#22320;&#28857;</strong>&#65306;03.28 - 03.29&#65292;&#19978;&#28023;&#183;&#28437;&#27827;&#27902;&#20250;&#35758;&#20013;&#24515;</p></li><li><p><strong><a href="https://letsvision.swiftgg.team/">&#27963;&#21160;&#23448;&#32593;</a></strong></p></li><li><p><strong><a href="https://l.fatbobman.com/w0125-10">&#33719;&#21462;&#38376;&#31080;</a></strong></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #124]]></title><description><![CDATA[The Spring Festival Gala, Robots, AI, and LLMs]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-124</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-124</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 23 Feb 2026 12:03:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PoXb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PoXb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PoXb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 424w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 848w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 1272w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PoXb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:106124,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/188874352?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PoXb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 424w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 848w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 1272w, https://substackcdn.com/image/fetch/$s_!PoXb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fa3a993-5717-45e8-a908-a12bf5516b70_1622x912.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>The Spring Festival Gala, Robots, AI, and LLMs</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-124/">Read on web &#8594;</a></p><p>As a television program with over a billion viewers, the China Central Television&#8217;s Spring Festival Gala is undoubtedly an exceptional showcase platform. In this year&#8217;s Gala, multiple Chinese robotics manufacturers presented their products in various performances, among which Unitree&#8217;s humanoid robots caught the most attention. During the show, multiple models of these humanoid robots executed a series of highly complex martial arts and dynamic movements. Compared to the more static, stationary displays of last year, the complexity and stability of their movements have seen a significant leap&#8212;a progress that has drawn attention from global media.</p><p>Following the Gala, discussions on social media showed a clear divide. Alongside the amazement at the technological progress, there was no shortage of skeptical voices dismissing the performance as &#8220;pre-programmed,&#8221; &#8220;lacking AI,&#8221; or &#8220;impractical.&#8221; To a certain extent, this reflects the public&#8217;s underestimation of the sheer complexity of robotics&#8212;especially a lack of awareness regarding the difficulties of motion control, real-time feedback systems, and system-level integration.</p><p>One point needs clarification: pre-trained does not equal &#8220;record-and-playback.&#8221; It is true that humanoid robots currently employ highly orchestrated movement sequences in such performances, but this shares a similar logic with the training of human dancers or athletes. Extensive offline training and rehearsal form the foundation of the movements, but during actual execution, the &#8220;body&#8221; must still rely on dynamic balance and real-time corrections to cope with real-world disturbances. It is precisely this fault tolerance and real-time repair capability that allows humanoid robots&#8212;a naturally unstable bipedal system&#8212;to pull off highly dynamic, continuous movements.</p><p>Meanwhile, the explosion of Large Language Models (LLMs) in recent years has led many to mistakenly equate LLMs with AI as a whole. In reality, AI, a field with decades of history, encompasses far more than just language understanding. Especially when interacting with the real physical world, the usage of specialized models&#8212;such as computer vision, path planning, motion control, and reinforcement learning&#8212;in industrial and physical systems still vastly exceeds that of LLMs. In the realm of robotics, the true ceiling of a system&#8217;s capability is typically determined by its perception systems, control systems, and low-latency feedback algorithms, rather than its language reasoning abilities.</p><p>Even if stronger &#8220;cognitive abilities&#8221; are introduced to humanoid robots in the future, the better path may not necessarily be directly plugging in an LLM. Instead, it will likely involve building World Models that inherently understand the laws of physics, paired with control systems capable of low-latency responses&#8212;two areas that happen to be inherent weaknesses of LLMs. The challenges of Embodied AI are fundamentally different from pure text reasoning.</p><p>As for the issue of &#8220;practicality,&#8221; kung fu or dancing indeed hardly correspond directly to real-world job scenarios. However, it is precisely these movements&#8212;which demand extreme balance, coordination, and dynamic response&#8212;that provide the perfect validation ground for highly complex and unstable systems like humanoid robots. They function as engineering stress tests, demonstrating the maturity of mechanical design, electronic control, and algorithmic integration, rather than proving short-term commercial viability.</p><p>Personally, I remain cautious about the future market size for humanoid robots. There is often a significant chasm between technological breakthroughs and widespread commercial adoption. Nevertheless, judging by the magnitude of progress showcased at this year&#8217;s Gala, it is reasonable to conclude that within the next decade, robots or smart machines integrating into our daily work and living environments is no longer just sci-fi imagination. Whether you like &#8220;robots&#8221; or not, the trajectory of technological evolution is unmistakably clear: we will eventually need to coexist with them.</p><p>As for the apocalyptic scenario of &#8220;robots enslaving humanity,&#8221; I&#8217;m not worried about that for now. My more realistic concern is this: if they encounter a bug at work and swing a punch at me, I genuinely couldn&#8217;t take the hit.</p><p><a href="https://fatbobman.com/en/weekly/issue-123/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0124-01">How to Migrate to @Observable Without Breaking Your App</a></strong></h3><p>As more apps raise their minimum deployment target to iOS 17, <code>@Observable</code> is replacing <code>ObservableObject</code> as the new state management foundation. However, when a project has deeply relied on <code>ObservableObject</code> + <code>@Published</code>, migration is far from a simple macro substitution. <a href="https://x.com/PawelKozielecki">Pawel Kozielecki</a> draws on a real-world migration experience to systematically walk through the correct usage of property wrappers in the new system &#8212; using <code>@State</code> for lifecycle management, <code>@Bindable</code> for two-way bindings, and plain properties for read-only access &#8212; while highlighting easily overlooked details such as <code>@ObservationIgnored</code> and computed property tracking blind spots. The real challenge of migration was never about syntax; it&#8217;s about truly understanding who owns the view model&#8217;s lifecycle.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-02">Testing with Event Streams</a></strong></h3><p>Although Swift Testing offers a rich assertion API, in practice you&#8217;ll find there&#8217;s no single tool that fully corresponds to XCTest&#8217;s ability to verify that multiple callbacks are triggered in order (<code>fulfillment</code> + <code>enforceOrder</code>). <code>confirmation</code> requires nesting and cannot directly validate trigger order. <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> proposes an approach that better fits Swift&#8217;s concurrency model: using <code>AsyncStream</code> to collect events, wrapped in a lightweight <code>EventStream</code> type &#8212; yielding event identifiers when callbacks fire, then calling <code>collect</code> at the end to retrieve the full event sequence for comparison against an expected array. As for why not just use a plain array, Matt provides a compelling answer: when <code>@Sendable</code> constraints or inconsistent actor isolation are involved, writing directly to an array creates concurrency safety issues, whereas the <code>AsyncStream</code>-based approach naturally conforms to the concurrency model.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-03">If You&#8217;re Not Versioning Your SwiftData Schema, You&#8217;re Gambling</a></strong></h3><p>SwiftData&#8217;s declarative syntax and automatic migration capabilities make it easy to fall into the trap of thinking &#8220;the framework will handle everything.&#8221; The reality is that once your model structure changes &#8212; adding fields, renaming, adjusting relationships &#8212; without an explicit schema version and migration plan, you&#8217;re left relying on implicit inference. When that inference fails, the result is rarely a graceful migration; more often it&#8217;s crashes, data loss, or an app that won&#8217;t launch. <a href="https://x.com/azamsharp">Mohammad Azam</a> offers direct, pragmatic advice: explicitly declare <code>Schema</code> versions; prepare migration paths for future structural changes; and treat migration design as part of model design, not an afterthought.</p><blockquote><p>This advice applies equally to Core Data. Even when a model is fully compatible with lightweight migration, creating a corresponding model version file for each release (whenever structural changes occur) not only helps track the model&#8217;s evolution but also enables clear, controlled rollback when issues arise. Using explicit versioning to govern model evolution is fundamentally about establishing safety boundaries for long-term maintenance.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-04">How to build a simple CLI tool using Swift</a></strong></h3><p>There&#8217;s an interesting phenomenon in the age of AI Coding: CLI tools are experiencing a renaissance &#8212; more and more developers are building CLI tools to power their MCP and Agent workflows. <a href="https://x.com/tanaschita">Natascha Fadeeva</a> walks through how to build structured command-line tools using Swift Package Manager and Apple&#8217;s official ArgumentParser library: defining root commands and subcommands, handling async network requests, and compiling to a standalone distributable binary. For iOS developers already fluent in Swift, this path is more natural than maintaining a bash or Python script, and easier to evolve alongside the project.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-05">Navigation Notes &#8211; Agentic coding</a></strong></h3><p>As an experienced developer, <a href="https://mastodon.social/@heckj">Joseph Heck</a> observes that as AI becomes capable of executing tasks, generating code, and driving changes autonomously, the developer&#8217;s role shifts from &#8220;line-by-line implementer&#8221; to &#8220;path navigator.&#8221; The truly scarce skill is no longer coding speed, but navigation &#8212; how developers maintain their sense of direction in complex codebases and multi-agent environments. Joseph offers several practical suggestions: always include &#8220;ask me about anything ambiguous&#8221; in your prompts; have the agent draft a plan and get your approval before implementation; provide deterministic feedback loops (unit tests, compiler errors) that allow the agent to self-correct; and distill frequently reused instructions into Skill files.</p><p>Heck avoids amplifying the &#8220;AI will disrupt developers&#8221; narrative, instead emphasizing a more grounded reality: agentic coding amplifies existing engineering capabilities. If you&#8217;re already good at modular design and abstraction, AI will accelerate you. If your sense of boundaries is fuzzy, AI will just create chaos faster.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-06">Setting up a delivery pipeline for your agentic iOS projects</a></strong></h3><p>When code generation, modification, and refactoring begin to be driven by agents, is the traditional CI/CD pipeline still sufficient? <a href="https://x.com/donnywals">Donny Wals</a> opens with a real experience: his app crashed mid-workout at the gym, he handed the crash report to an agent for analysis, and by the time he finished training, a PR was waiting. After merging, a TestFlight build landed shortly after. Around this experience, he systematically outlines how to build a reliable delivery pipeline for agentic iOS projects &#8212; one that keeps automated changes controllable, verifiable, and releasable.</p><p>The article&#8217;s focus isn&#8217;t on any specific tool, but on pipeline design itself. Donny emphasizes that code generated by agents is fundamentally &#8220;a change that hasn&#8217;t been reviewed line by line,&#8221; which makes clear quality gates all the more important: automated testing, continuous integration, and the release pipeline must bear ultimate responsibility for delivery. Agents can significantly accelerate implementation, but engineering discipline cannot be relaxed in kind &#8212; when velocity increases, control mechanisms become even more critical.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-07">Tracking Token Usage in Foundation Models</a></strong></h3><p>Apple&#8217;s Foundation Models run on-device with a context window of just 4,096 tokens &#8212; once exceeded, the conversation cannot continue. iOS 26.4 introduces token usage tracking APIs to help developers monitor context consumption in real time. <a href="https://x.com/iosartem">Artem Novichkov</a> covers four key metrics: total model context capacity (<code>contextSize</code>), token consumption for Instructions, consumption for individual Prompts, and cumulative usage for the full conversation Transcript. The article also highlights an easily overlooked detail: when a Tool is introduced, its name, description, and argument schema are serialized and counted toward the token budget &#8212; the same Instructions jump from 16 to 79 tokens once a Tool is attached. For on-device models, token observability will become essential infrastructure for optimizing the user experience.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0124-08">App Store Connect CLI</a></strong></h3><p>App Store Connect CLI is an unofficial App Store Connect command-line tool developed by <a href="https://x.com/rudrank">Rudrank Riyam</a>, covering the full release pipeline: TestFlight management, build uploads, code signing, screenshot automation, localization sync, app review submission, notarization, and financial report downloads. The tool was designed from the ground up with agent scenarios in mind and includes dedicated documentation for agent-oriented workflows. If your release pipeline centers on TestFlight, metadata, submission, signing, and CI automation, ASC is worth considering as a lightweight alternative to fastlane.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-09">GRDB 7.10.0: Android, Linux, and Windows Support</a></strong></h3><p>GRDB 7.10.0 is a milestone release: it formally introduces support for Android, Linux, and Windows, and adds the ability to use SQLCipher (encrypted databases) via Swift Package Manager &#8212; two long-awaited features from the community. This marks a meaningful evolution for Swift&#8217;s most mature SQLite wrapper, from an Apple-platform tool into a truly cross-platform data layer solution.</p><p><a href="https://x.com/groue">Gwendal Rou&#233;</a> notes in the <a href="https://forums.swift.org/t/grdb-v7-10-0-android-linux-windows-and-sqlcipher-swiftpm/84754">release announcement</a> that because Xcode does not yet support package traits, SwiftPM will still download unused dependencies; until this is resolved, SQLCipher support will continue to require a fork.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-10">Swift System Metrics</a></strong></h3><p>Swift System Metrics provides Swift applications &#8212; particularly server-side projects &#8212; with unified system-level metrics collection: CPU utilization, memory usage, file descriptor counts, and more, exposed through a standardized Metrics interface that integrates with existing monitoring systems such as Prometheus. It is not a standalone monitoring system, but rather an infrastructure component driven by the Swift Server Work Group, designed to align with the Swift Metrics ecosystem and bring system resource metrics into the same observability stack as application-level metrics. The 1.0 release signals API stability and production readiness. For teams building Swift backend services or investing in Swift observability, this is a foundational piece of the puzzle.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-124?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-124?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#26149;&#26202;&#12289;&#26426;&#22120;&#20154;&#12289;AI &#19982; LLM</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-124/">&#32593;&#39029;&#29256;</a></strong></p><p>&#20316;&#20026;&#19968;&#20010;&#35266;&#20247;&#25968;&#37327;&#36229;&#21313;&#20159;&#30340;&#30005;&#35270;&#33410;&#30446;&#65292;&#22830;&#35270;&#26149;&#26202;&#26080;&#30097;&#26159;&#26497;&#20339;&#30340;&#23637;&#31034;&#24179;&#21488;&#12290;&#20170;&#24180;&#26149;&#26202;&#20013;&#65292;&#22810;&#23478;&#20013;&#22269;&#26426;&#22120;&#20154;&#21378;&#21830;&#22312;&#19981;&#21516;&#33410;&#30446;&#20013;&#23637;&#31034;&#20102;&#20854;&#20135;&#21697;&#65292;&#20854;&#20013;&#35752;&#35770;&#24230;&#26368;&#39640;&#30340;&#24403;&#23646;&#23431;&#26641;&#65288;Unitree&#65289;&#30340;&#20154;&#24418;&#26426;&#22120;&#20154;&#12290;&#22312;&#34920;&#28436;&#29615;&#33410;&#65292;&#22810;&#27454;&#22411;&#21495;&#30340;&#20154;&#24418;&#26426;&#22120;&#20154;&#23436;&#25104;&#20102;&#22823;&#37327;&#36739;&#20026;&#22797;&#26434;&#30340;&#27494;&#26415;&#19982;&#21160;&#24577;&#21160;&#20316;&#23637;&#31034;&#12290;&#19982;&#21435;&#24180;&#20559;&#38745;&#24577;&#12289;&#20559;&#31449;&#26729;&#24335;&#30340;&#21576;&#29616;&#30456;&#27604;&#65292;&#20170;&#24180;&#30340;&#21160;&#20316;&#22797;&#26434;&#24230;&#19982;&#31283;&#23450;&#24615;&#30830;&#23454;&#26377;&#26126;&#26174;&#25552;&#21319;&#65292;&#36825;&#19968;&#28857;&#20063;&#24471;&#21040;&#20102;&#20840;&#29699;&#23186;&#20307;&#30340;&#20851;&#27880;&#19982;&#25253;&#36947;&#12290;</p><p>&#26149;&#26202;&#20043;&#21518;&#65292;&#31038;&#20132;&#23186;&#20307;&#19978;&#30340;&#35752;&#35770;&#21576;&#29616;&#20986;&#26126;&#26174;&#20998;&#21270;&#12290;&#38500;&#20102;&#23545;&#25216;&#26415;&#36827;&#27493;&#30340;&#24778;&#21497;&#20043;&#22806;&#65292;&#8220;&#39044;&#32534;&#31243;&#8221;&#12289;&#8220;&#27809;&#26377; AI&#8221;&#12289;&#8220;&#32570;&#20047;&#23454;&#29992;&#24615;&#8221;&#31561;&#36136;&#30097;&#22768;&#38899;&#21516;&#26679;&#19981;&#23569;&#12290;&#36825;&#22312;&#19968;&#23450;&#31243;&#24230;&#19978;&#21453;&#26144;&#20102;&#20844;&#20247;&#23545;&#26426;&#22120;&#20154;&#25216;&#26415;&#22797;&#26434;&#24230;&#30340;&#20302;&#20272;&#8212;&#8212;&#23588;&#20854;&#26159;&#23545;&#36816;&#21160;&#25511;&#21046;&#12289;&#23454;&#26102;&#21453;&#39304;&#31995;&#32479;&#21644;&#31995;&#32479;&#32423;&#25972;&#21512;&#38590;&#24230;&#30340;&#35748;&#30693;&#19981;&#36275;&#12290;</p><p>&#38656;&#35201;&#28548;&#28165;&#30340;&#19968;&#28857;&#26159;&#65306;&#39044;&#35757;&#32451;&#24182;&#19981;&#31561;&#20110;&#8220;&#24405;&#21046;-&#22238;&#25918;&#8221;&#12290;&#24403;&#21069;&#20154;&#24418;&#26426;&#22120;&#20154;&#22312;&#27492;&#31867;&#34920;&#28436;&#20013;&#30340;&#30830;&#37319;&#29992;&#20102;&#39640;&#24230;&#35268;&#21010;&#30340;&#21160;&#20316;&#27969;&#31243;&#65292;&#36825;&#19982;&#20154;&#31867;&#33310;&#32773;&#12289;&#36816;&#21160;&#21592;&#30340;&#35757;&#32451;&#36923;&#36753;&#26377;&#30456;&#36890;&#20043;&#22788;&#8212;&#8212;&#22823;&#37327;&#30340;&#31163;&#32447;&#35757;&#32451;&#19982;&#35843;&#35797;&#26500;&#25104;&#20102;&#21160;&#20316;&#30340;&#22522;&#30784;&#65292;&#20294;&#22312;&#23454;&#38469;&#25191;&#34892;&#36807;&#31243;&#20013;&#65292;&#36523;&#20307;&#20173;&#38656;&#20381;&#36182;&#21160;&#24577;&#24179;&#34913;&#19982;&#21363;&#26102;&#20462;&#27491;&#26469;&#24212;&#23545;&#30495;&#23454;&#29615;&#22659;&#30340;&#25200;&#21160;&#12290;&#27491;&#26159;&#36825;&#31181;&#23481;&#38169;&#19982;&#23454;&#26102;&#20462;&#22797;&#33021;&#21147;&#65292;&#25165;&#35753;&#20154;&#24418;&#26426;&#22120;&#20154;&#36825;&#20010;&#22825;&#28982;&#19981;&#31283;&#23450;&#30340;&#21452;&#36275;&#31995;&#32479;&#24471;&#20197;&#23436;&#25104;&#39640;&#21160;&#24577;&#30340;&#36830;&#32493;&#21160;&#20316;&#12290;</p><p>&#19982;&#27492;&#21516;&#26102;&#65292;&#36817;&#24180;&#26469;&#22823;&#35821;&#35328;&#27169;&#22411;&#65288;LLM&#65289;&#30340;&#29190;&#21457;&#65292;&#35753;&#19981;&#23569;&#20154;&#23558; LLM &#19982; AI &#31561;&#21516;&#36215;&#26469;&#12290;&#20107;&#23454;&#19978;&#65292;AI &#20316;&#20026;&#19968;&#20010;&#24050;&#26377;&#25968;&#21313;&#24180;&#21457;&#23637;&#30340;&#39046;&#22495;&#65292;&#36828;&#36828;&#19981;&#27490;&#35821;&#35328;&#29702;&#35299;&#36825;&#19968;&#20998;&#25903;&#12290;&#23588;&#20854;&#26159;&#38754;&#23545;&#30495;&#23454;&#30340;&#29289;&#29702;&#19990;&#30028;&#26102;&#65292;&#35270;&#35273;&#35782;&#21035;&#12289;&#36335;&#24452;&#35268;&#21010;&#12289;&#36816;&#21160;&#25511;&#21046;&#12289;&#24378;&#21270;&#23398;&#20064;&#31561;&#19987;&#29992;&#27169;&#22411;&#22312;&#24037;&#19994;&#19982;&#23454;&#20307;&#31995;&#32479;&#20013;&#30340;&#20351;&#29992;&#37327;&#65292;&#20381;&#28982;&#36828;&#39640;&#20110; LLM&#12290;&#22312;&#26426;&#22120;&#20154;&#39046;&#22495;&#65292;&#30495;&#27491;&#20915;&#23450;&#33021;&#21147;&#19978;&#38480;&#30340;&#24448;&#24448;&#26159;&#24863;&#30693;&#31995;&#32479;&#12289;&#25511;&#21046;&#31995;&#32479;&#20197;&#21450;&#20302;&#24310;&#36831;&#21453;&#39304;&#31639;&#27861;&#65292;&#32780;&#19981;&#26159;&#35821;&#35328;&#25512;&#29702;&#33021;&#21147;&#12290;</p><p>&#21363;&#20415;&#26410;&#26469;&#20026;&#20154;&#24418;&#26426;&#22120;&#20154;&#24341;&#20837;&#26356;&#24378;&#30340;&#8221;&#35748;&#30693;&#33021;&#21147;&#8221;&#65292;&#26356;&#36866;&#21512;&#30340;&#36335;&#24452;&#20063;&#26410;&#24517;&#26159;&#30452;&#25509;&#25509;&#20837; LLM&#65292;&#32780;&#21487;&#33021;&#26159;&#26500;&#24314;&#33021;&#29702;&#35299;&#29289;&#29702;&#35268;&#24459;&#30340;&#19990;&#30028;&#27169;&#22411;&#65288;World Models&#65289;&#19982;&#20855;&#22791;&#20302;&#24310;&#36831;&#21709;&#24212;&#33021;&#21147;&#30340;&#25511;&#21046;&#31995;&#32479;&#8212;&#8212;&#36825;&#20004;&#28857;&#24688;&#24688;&#26159; LLM &#30340;&#22266;&#26377;&#30701;&#26495;&#12290;&#20855;&#36523;&#26234;&#33021;&#65288;Embodied AI&#65289;&#30340;&#25361;&#25112;&#65292;&#19982;&#32431;&#25991;&#26412;&#25512;&#29702;&#23384;&#22312;&#26412;&#36136;&#24046;&#24322;&#12290;</p><p>&#33267;&#20110;&#8220;&#23454;&#29992;&#24615;&#8221;&#30340;&#38382;&#39064;&#65292;&#21151;&#22827;&#25110;&#33310;&#36424;&#30830;&#23454;&#38590;&#20197;&#30452;&#25509;&#23545;&#24212;&#29616;&#23454;&#24037;&#20316;&#22330;&#26223;&#12290;&#20294;&#24688;&#24688;&#26159;&#36825;&#20123;&#23545;&#24179;&#34913;&#24615;&#12289;&#21327;&#35843;&#24615;&#19982;&#21160;&#24577;&#21709;&#24212;&#35201;&#27714;&#26497;&#39640;&#30340;&#21160;&#20316;&#65292;&#20026;&#20154;&#24418;&#26426;&#22120;&#20154;&#36825;&#31181;&#39640;&#24230;&#22797;&#26434;&#19988;&#19981;&#31283;&#23450;&#30340;&#31995;&#32479;&#25552;&#20379;&#20102;&#26497;&#20339;&#30340;&#39564;&#35777;&#22330;&#26223;&#12290;&#23427;&#20204;&#26356;&#20687;&#26159;&#24037;&#31243;&#33021;&#21147;&#30340;&#21387;&#21147;&#27979;&#35797;&#65292;&#23637;&#31034;&#30340;&#26159;&#26426;&#26800;&#35774;&#35745;&#12289;&#30005;&#23376;&#25511;&#21046;&#19982;&#31639;&#27861;&#31995;&#32479;&#25972;&#21512;&#30340;&#25104;&#29087;&#24230;&#65292;&#32780;&#38750;&#30701;&#26399;&#21830;&#19994;&#33853;&#22320;&#33021;&#21147;&#12290;</p><p>&#25105;&#20010;&#20154;&#23545;&#20110;&#20154;&#24418;&#26426;&#22120;&#20154;&#26410;&#26469;&#30340;&#24066;&#22330;&#35268;&#27169;&#20173;&#28982;&#25345;&#23457;&#24910;&#24577;&#24230;&#12290;&#25216;&#26415;&#36827;&#27493;&#19982;&#21830;&#19994;&#26222;&#21450;&#20043;&#38388;&#24448;&#24448;&#23384;&#22312;&#19981;&#23567;&#30340;&#40511;&#27807;&#12290;&#20294;&#20174;&#20170;&#24180;&#26149;&#26202;&#25152;&#21576;&#29616;&#30340;&#36827;&#27493;&#24133;&#24230;&#26469;&#30475;&#65292;&#21487;&#20197;&#21512;&#29702;&#21028;&#26029;&#65306;&#22312;&#26410;&#26469;&#21313;&#24180;&#20869;&#65292;&#26426;&#22120;&#20154;&#25110;&#26234;&#33021;&#26426;&#22120;&#20197;&#26576;&#31181;&#24418;&#24335;&#34701;&#20837;&#26085;&#24120;&#24037;&#20316;&#19982;&#29983;&#27963;&#22330;&#26223;&#65292;&#24050;&#19981;&#20877;&#26159;&#31185;&#24187;&#24819;&#35937;&#12290;&#26080;&#35770;&#20320;&#26159;&#21542;&#21916;&#27426;&#8220;&#26426;&#22120;&#20154;&#8221;&#65292;&#25216;&#26415;&#28436;&#36827;&#30340;&#36235;&#21183;&#24050;&#32463;&#21313;&#20998;&#26126;&#30830;&#65292;&#25105;&#20204;&#32456;&#23558;&#38656;&#35201;&#19982;&#23427;&#20204;&#20849;&#23384;&#12290;</p><p>&#33267;&#20110;&#8220;&#26426;&#22120;&#20154;&#22900;&#24441;&#20154;&#31867;&#8221;&#30340;&#24773;&#26223;&#65292;&#25105;&#26242;&#26102;&#24182;&#19981;&#25285;&#24515;&#12290;&#25105;&#26356;&#29616;&#23454;&#30340;&#25285;&#24551;&#26159;&#65306;&#22914;&#26524;&#23427;&#20204;&#22312;&#24037;&#20316;&#20013;&#20986;&#29616; Bug&#65292;&#32473;&#25105;&#19968;&#25331;&#65292;&#25105;&#30495;&#30340;&#25384;&#19981;&#20303;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-123/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0124-01">&#22914;&#20309;&#22312;&#19981;&#30772;&#22351; App &#30340;&#21069;&#25552;&#19979;&#36801;&#31227;&#21040; @Observable (How to Migrate to @Observable Without Breaking Your App)</a></strong></h3><p>&#38543;&#30528;&#36234;&#26469;&#36234;&#22810;&#30340;&#24212;&#29992;&#23558;&#26368;&#20302;&#31995;&#32479;&#29256;&#26412;&#25552;&#21319;&#33267; iOS 17&#65292;<code>@Observable</code> &#27491;&#22312;&#21462;&#20195; <code>ObservableObject</code> &#25104;&#20026;&#26032;&#30340;&#29366;&#24577;&#31649;&#29702;&#22522;&#30784;&#35774;&#26045;&#65292;&#20294;&#24403;&#39033;&#30446;&#24050;&#32463;&#28145;&#24230;&#20381;&#36182; <code>ObservableObject</code> + <code>@Published</code> &#26102;&#65292;&#36801;&#31227;&#36828;&#38750;&#31616;&#21333;&#26367;&#25442;&#23439;&#21363;&#21487;&#23436;&#25104;&#12290;<a href="https://x.com/PawelKozielecki">Pawel Kozielecki</a> &#32467;&#21512;&#19968;&#27425;&#30495;&#23454;&#30340;&#36801;&#31227;&#36393;&#22353;&#32463;&#21382;&#65292;&#20174;&#24213;&#23618;&#26426;&#21046;&#24046;&#24322;&#20986;&#21457;&#65292;&#31995;&#32479;&#26803;&#29702;&#20102;&#26032;&#20307;&#31995;&#19979;&#23646;&#24615;&#21253;&#35013;&#22120;&#30340;&#27491;&#30830;&#20351;&#29992;&#26041;&#24335;&#8212;&#8212;&#29992; <code>@State</code> &#31649;&#29702;&#29983;&#21629;&#21608;&#26399;&#12289;&#29992; <code>@Bindable</code> &#22788;&#29702;&#21452;&#21521;&#32465;&#23450;&#12289;&#21482;&#35835;&#22330;&#26223;&#30452;&#25509;&#20351;&#29992;&#26222;&#36890;&#23646;&#24615;&#65292;&#24182;&#29305;&#21035;&#25351;&#20986;&#20102; <code>@ObservationIgnored</code>&#12289;&#35745;&#31639;&#23646;&#24615;&#36861;&#36394;&#30450;&#28857;&#31561;&#23481;&#26131;&#34987;&#24573;&#35270;&#30340;&#32454;&#33410;&#12290;&#36801;&#31227;&#30340;&#38590;&#28857;&#20174;&#26469;&#19981;&#22312;&#35821;&#27861;&#23618;&#38754;&#65292;&#32780;&#22312;&#20110;&#30495;&#27491;&#21400;&#28165;&#8220;&#35841;&#25317;&#26377; view model &#30340;&#29983;&#21629;&#21608;&#26399;&#8221;&#36825;&#19968;&#26681;&#26412;&#38382;&#39064;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-02">&#39564;&#35777;&#22810;&#20010;&#22238;&#35843;&#25353;&#39034;&#24207;&#35302;&#21457; (Testing with Event Streams)</a></strong></h3><p>&#23613;&#31649; Swift Testing &#25552;&#20379;&#20102;&#20016;&#23500;&#30340;&#26029;&#35328; API&#65292;&#20294;&#22312;&#23454;&#38469;&#20351;&#29992;&#20013;&#20320;&#20250;&#21457;&#29616;&#65292;&#24182;&#27809;&#26377;&#19968;&#20010;&#24037;&#20855;&#33021;&#22815;&#23436;&#20840;&#23545;&#24212; XCTest &#20013;&#8220;&#39564;&#35777;&#22810;&#20010;&#22238;&#35843;&#25353;&#39034;&#24207;&#35302;&#21457;&#8221;&#65288;<code>fulfillment</code> + <code>enforceOrder</code>&#65289;&#30340;&#33021;&#21147;&#12290;<code>confirmation</code> &#26082;&#38656;&#35201;&#23884;&#22871;&#20351;&#29992;&#65292;&#20063;&#26080;&#27861;&#30452;&#25509;&#26657;&#39564;&#35302;&#21457;&#39034;&#24207;&#12290;&#23545;&#27492;&#65292;<a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#25552;&#20986;&#20102;&#19968;&#31181;&#26356;&#31526;&#21512; Swift &#24182;&#21457;&#27169;&#22411;&#30340;&#24605;&#36335;&#65306;&#20351;&#29992; <code>AsyncStream</code> &#25910;&#38598;&#20107;&#20214;&#65292;&#24182;&#23553;&#35013;&#20026;&#19968;&#20010;&#36731;&#37327;&#32423;&#30340; <code>EventStream</code> &#31867;&#22411;&#8212;&#8212;&#24403;&#22238;&#35843;&#35302;&#21457;&#26102; <code>yield</code> &#20107;&#20214;&#26631;&#35782;&#65292;&#27979;&#35797;&#32467;&#26463;&#21518;&#36890;&#36807; <code>collect</code> &#33719;&#21462;&#23436;&#25972;&#20107;&#20214;&#24207;&#21015;&#65292;&#20877;&#19982;&#39044;&#26399;&#25968;&#32452;&#36827;&#34892;&#23545;&#27604;&#12290;&#23545;&#20110;&#8220;&#20026;&#20160;&#20040;&#19981;&#30452;&#25509;&#20351;&#29992;&#25968;&#32452;&#8221;&#36825;&#19968;&#30097;&#38382;&#65292;Matt &#20063;&#32473;&#20986;&#20102;&#20805;&#20998;&#29702;&#30001;&#65306;&#22312;&#23384;&#22312; <code>@Sendable</code> &#32422;&#26463;&#25110; actor &#38548;&#31163;&#19981;&#19968;&#33268;&#30340;&#22330;&#26223;&#19979;&#65292;&#30452;&#25509;&#20889;&#20837;&#25968;&#32452;&#20250;&#35302;&#21457;&#24182;&#21457;&#23433;&#20840;&#38382;&#39064;&#65292;&#32780;&#22522;&#20110; <code>AsyncStream</code> &#30340;&#26041;&#26696;&#21017;&#22825;&#28982;&#31526;&#21512;&#24182;&#21457;&#27169;&#22411;&#30340;&#32422;&#26463;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-03">&#21153;&#24517;&#20026; SwiftData &#27169;&#22411;&#26174;&#24335;&#22768;&#26126; Schema &#29256;&#26412; (If You&#8217;re Not Versioning Your SwiftData Schema, You&#8217;re Gambling)</a></strong></h3><p>SwiftData &#30340;&#22768;&#26126;&#24335;&#20889;&#27861;&#19982;&#33258;&#21160;&#36801;&#31227;&#33021;&#21147;&#24456;&#23481;&#26131;&#35753;&#20154;&#20135;&#29983;&#8220;&#26694;&#26550;&#20250;&#26367;&#25105;&#22788;&#29702;&#19968;&#20999;&#8221;&#30340;&#38169;&#35273;&#65292;&#20294;&#29616;&#23454;&#26159;&#65292;&#19968;&#26086;&#27169;&#22411;&#32467;&#26500;&#21457;&#29983;&#21464;&#21270;&#65288;&#23383;&#27573;&#26032;&#22686;&#12289;&#37325;&#21629;&#21517;&#12289;&#20851;&#31995;&#35843;&#25972;&#65289;&#65292;&#22914;&#26524;&#27809;&#26377;&#26174;&#24335;&#30340; schema version &#19982; migration plan&#65292;&#23601;&#21482;&#33021;&#20381;&#36182;&#38544;&#24335;&#25512;&#26029;&#12290;&#19968;&#26086;&#25512;&#26029;&#22833;&#36133;&#65292;&#32467;&#26524;&#24448;&#24448;&#19981;&#26159;&#20248;&#38597;&#30340;&#36801;&#31227;&#65292;&#32780;&#26159;&#23849;&#28291;&#12289;&#25968;&#25454;&#20002;&#22833;&#65292;&#29978;&#33267;&#23548;&#33268;&#24212;&#29992;&#26080;&#27861;&#21551;&#21160;&#12290;<a href="https://x.com/azamsharp">Mohammad Azam</a> &#30340;&#24314;&#35758;&#30452;&#25509;&#32780;&#21153;&#23454;&#65306;&#26174;&#24335;&#22768;&#26126; <code>Schema</code> &#29256;&#26412;&#65307;&#20026;&#26410;&#26469;&#30340;&#32467;&#26500;&#21464;&#21270;&#39044;&#30041;&#36801;&#31227;&#36335;&#24452;&#65307;&#23558;&#8220;&#36801;&#31227;&#35774;&#35745;&#8221;&#35270;&#20026;&#27169;&#22411;&#35774;&#35745;&#30340;&#19968;&#37096;&#20998;&#65292;&#32780;&#19981;&#26159;&#20107;&#21518;&#34917;&#25937;&#12290;</p><blockquote><p>&#26412;&#25991;&#30340;&#35266;&#28857;&#21516;&#26679;&#36866;&#29992;&#20110; Core Data&#12290;&#21363;&#20415;&#27169;&#22411;&#23436;&#20840;&#20860;&#23481;&#36731;&#37327;&#36801;&#31227;&#65292;&#20026;&#27599;&#20010;&#21457;&#34892;&#29256;&#26412;&#21019;&#24314;&#23545;&#24212;&#30340;&#27169;&#22411;&#29256;&#26412;&#25991;&#20214;&#65288;&#21482;&#35201;&#21457;&#29983;&#32467;&#26500;&#20462;&#25913;&#65289;&#65292;&#19981;&#20165;&#26377;&#21161;&#20110;&#36861;&#36394;&#27169;&#22411;&#28436;&#21270;&#36712;&#36857;&#65292;&#20063;&#33021;&#22312;&#20986;&#29616;&#38382;&#39064;&#26102;&#23454;&#29616;&#28165;&#26224;&#32780;&#21487;&#25511;&#30340;&#22238;&#28378;&#12290;&#29992;&#26126;&#30830;&#30340;&#29256;&#26412;&#26426;&#21046;&#32422;&#26463;&#27169;&#22411;&#28436;&#36827;&#65292;&#26412;&#36136;&#19978;&#26159;&#22312;&#20026;&#38271;&#26399;&#32500;&#25252;&#24314;&#31435;&#23433;&#20840;&#36793;&#30028;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-04">&#29992; Swift &#24320;&#21457; CLI &#24037;&#20855; (How to build a simple CLI tool using Swift)</a></strong></h3><p>&#19968;&#20010;&#26377;&#36259;&#30340;&#29616;&#35937;&#26159;&#65292;&#22312; AI Coding &#26102;&#20195;&#65292;CLI &#27491;&#22312;&#37325;&#28949;&#38738;&#26149;&#8212;&#8212;&#36234;&#26469;&#36234;&#22810;&#30340;&#24320;&#21457;&#32773;&#36890;&#36807;&#26500;&#24314; CLI &#24037;&#20855;&#26469;&#25215;&#36733;&#33258;&#24049;&#30340; MCP &#19982; Agent &#24037;&#20316;&#27969;&#12290;<a href="https://x.com/tanaschita">Natascha Fadeeva</a> &#20171;&#32461;&#20102;&#22914;&#20309;&#29992; Swift Package Manager &#21644; Apple &#23448;&#26041;&#30340; ArgumentParser &#24211;&#26500;&#24314;&#32467;&#26500;&#21270;&#30340;&#21629;&#20196;&#34892;&#24037;&#20855;&#65306;&#23450;&#20041;&#20027;&#21629;&#20196;&#19982;&#23376;&#21629;&#20196;&#12289;&#22788;&#29702;&#24322;&#27493;&#32593;&#32476;&#35831;&#27714;&#12289;&#26368;&#32456;&#32534;&#35793;&#20026;&#21487;&#29420;&#31435;&#20998;&#21457;&#30340;&#20108;&#36827;&#21046;&#25991;&#20214;&#12290;&#23545;&#20110;&#24050;&#32463;&#29087;&#24713; Swift &#30340; iOS &#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#26465;&#36335;&#24452;&#27604;&#32500;&#25252;&#19968;&#22871; bash/Python &#33050;&#26412;&#26356;&#33258;&#28982;&#65292;&#20063;&#26356;&#23481;&#26131;&#38543;&#39033;&#30446;&#19968;&#36215;&#28436;&#36827;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-05">&#22312; AI &#32534;&#31243;&#26102;&#20445;&#25345;&#26041;&#21521;&#24863; (Navigation Notes &#8211; Agentic coding)</a></strong></h3><p>&#20316;&#20026;&#19968;&#20010;&#25317;&#26377;&#20016;&#23500;&#32463;&#39564;&#30340;&#24320;&#21457;&#32773;&#65292;<a href="https://mastodon.social/@heckj">Joseph Heck</a> &#35748;&#20026;&#24403; AI &#33021;&#22815;&#20027;&#21160;&#25191;&#34892;&#20219;&#21153;&#12289;&#29983;&#25104;&#20195;&#30721;&#29978;&#33267;&#25512;&#21160;&#25913;&#21160;&#26102;&#65292;&#24320;&#21457;&#32773;&#30340;&#35282;&#33394;&#20174;&#8220;&#36880;&#34892;&#23454;&#29616;&#32773;&#8221;&#36716;&#21464;&#20026;&#8220;&#36335;&#24452;&#35268;&#21010;&#32773;&#8221;&#12290;&#30495;&#27491;&#31232;&#32570;&#30340;&#33021;&#21147;&#19981;&#20877;&#26159;&#20889;&#20195;&#30721;&#30340;&#36895;&#24230;&#65292;&#32780;&#22312;&#8220;&#23548;&#33322;&#8221;&#8212;&#8212;&#20063;&#23601;&#26159;&#24320;&#21457;&#32773;&#22312;&#22797;&#26434;&#20195;&#30721;&#19982;&#22810;&#20195;&#29702;&#29615;&#22659;&#20013;&#22914;&#20309;&#20445;&#25345;&#26041;&#21521;&#24863;&#12290;Joseph &#32473;&#20986;&#20102;&#20960;&#26465;&#24314;&#35758;&#65292;&#20363;&#22914;&#65306;&#22312;&#25552;&#31034;&#35789;&#20013;&#22987;&#32456;&#21152;&#20837;&#8221;&#23545;&#20219;&#20309;&#27169;&#31946;&#20043;&#22788;&#21521;&#25105;&#25552;&#38382;&#8221;&#65307;&#20808;&#35753; Agent &#21046;&#23450;&#35745;&#21010;&#24182;&#33719;&#24471;&#30830;&#35748;&#65292;&#20877;&#24320;&#22987;&#23454;&#26045;&#65307;&#25552;&#20379;&#30830;&#23450;&#24615;&#30340;&#21453;&#39304;&#22238;&#36335;&#65288;&#21333;&#20803;&#27979;&#35797;&#12289;&#32534;&#35793;&#22120;&#38169;&#35823;&#65289;&#65292;&#35753; Agent &#33021;&#22815;&#33258;&#25105;&#20462;&#27491;&#65307;&#20197;&#21450;&#23558;&#21453;&#22797;&#20351;&#29992;&#30340;&#25351;&#20196;&#38598;&#27785;&#28096;&#20026; Skill &#25991;&#20214;&#31561;&#12290;</p><p>Heck &#24182;&#27809;&#26377;&#36807;&#24230;&#28210;&#26579;&#8220;AI &#39072;&#35206;&#24320;&#21457;&#32773;&#8221;&#30340;&#21465;&#20107;&#65292;&#32780;&#26159;&#24378;&#35843;&#19968;&#31181;&#26356;&#20919;&#38745;&#30340;&#29616;&#23454;&#65306;agentic coding &#20250;&#25918;&#22823;&#24050;&#26377;&#30340;&#24037;&#31243;&#33021;&#21147;&#12290;&#22914;&#26524;&#20320;&#26412;&#26469;&#23601;&#21892;&#20110;&#27169;&#22359;&#21010;&#20998;&#19982;&#25277;&#35937;&#35774;&#35745;&#65292;AI &#20250;&#21152;&#36895;&#20320;&#65307;&#22914;&#26524;&#36793;&#30028;&#24863;&#27169;&#31946;&#65292;AI &#21482;&#20250;&#26356;&#24555;&#21046;&#36896;&#28151;&#20081;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-06">&#20026; Agent &#39537;&#21160;&#30340; iOS &#39033;&#30446;&#26500;&#24314;&#21487;&#38752;&#20132;&#20184;&#31649;&#32447; (Setting up a delivery pipeline for your agentic iOS projects)</a></strong></h3><p>&#24403;&#20195;&#30721;&#30340;&#29983;&#25104;&#12289;&#20462;&#25913;&#19982;&#37325;&#26500;&#24320;&#22987;&#30001; Agent &#39537;&#21160;&#26102;&#65292;&#20256;&#32479;&#30340; CI/CD &#27969;&#31243;&#26159;&#21542;&#20173;&#28982;&#36275;&#22815;&#65311;<a href="https://x.com/donnywals">Donny Wals</a> &#20197;&#19968;&#27425;&#30495;&#23454;&#32463;&#21382;&#23637;&#24320;&#65306;&#20581;&#36523;&#26102;&#24212;&#29992;&#23849;&#28291;&#65292;&#20182;&#23558; Crash Report &#20132;&#32473; Agent &#20998;&#26512;&#65292;&#35757;&#32451;&#32467;&#26463;&#21518; PR &#24050;&#32463;&#20934;&#22791;&#23601;&#32490;&#65292;&#21512;&#24182;&#21518; TestFlight &#26500;&#24314;&#38543;&#21363;&#33853;&#22320;&#12290;&#22260;&#32469;&#36825;&#19968;&#23454;&#36341;&#65292;&#20182;&#31995;&#32479;&#26803;&#29702;&#20102;&#22914;&#20309;&#20026;&#8220;agentic iOS &#39033;&#30446;&#8221;&#26500;&#24314;&#19968;&#26465;&#21487;&#38752;&#30340;&#20132;&#20184;&#31649;&#32447;&#65288;delivery pipeline&#65289;&#65292;&#30830;&#20445;&#33258;&#21160;&#21270;&#25913;&#21160;&#20381;&#28982;&#21487;&#25511;&#12289;&#21487;&#39564;&#35777;&#12289;&#21487;&#21457;&#24067;&#12290;</p><p>&#25991;&#31456;&#30340;&#37325;&#28857;&#24182;&#19981;&#22312;&#26576;&#20010;&#20855;&#20307;&#24037;&#20855;&#65292;&#32780;&#22312;&#27969;&#31243;&#35774;&#35745;&#26412;&#36523;&#12290;Donny &#24378;&#35843;&#65292;Agent &#29983;&#25104;&#30340;&#20195;&#30721;&#26412;&#36136;&#19978;&#20173;&#23646;&#20110;&#8220;&#26410;&#32463;&#20154;&#24037;&#36880;&#34892;&#23457;&#26597;&#30340;&#25913;&#21160;&#8221;&#65292;&#22240;&#27492;&#26356;&#38656;&#35201;&#26126;&#30830;&#30340;&#36793;&#30028;&#19982;&#36136;&#37327;&#38392;&#21475;&#65306;&#33258;&#21160;&#21270;&#27979;&#35797;&#12289;&#25345;&#32493;&#38598;&#25104;&#19982;&#21457;&#24067;&#27969;&#31243;&#24517;&#39035;&#25215;&#25285;&#26368;&#32456;&#30340;&#20132;&#20184;&#36131;&#20219;&#12290;Agent &#21487;&#20197;&#26174;&#33879;&#25552;&#21319;&#23454;&#29616;&#36895;&#24230;&#65292;&#20294;&#24037;&#31243;&#32426;&#24459;&#19981;&#33021;&#38543;&#20043;&#25918;&#26494;&#8212;&#8212;&#36895;&#24230;&#25552;&#21319;&#20043;&#21518;&#65292;&#25511;&#21046;&#26426;&#21046;&#21453;&#32780;&#26356;&#20026;&#20851;&#38190;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-07">&#23454;&#26102;&#25484;&#25569; Foundation Models &#30340;&#19978;&#19979;&#25991;&#28040;&#32791; (Tracking Token Usage in Foundation Models)</a></strong></h3><p>Apple &#30340; Foundation Models &#36816;&#34892;&#22312;&#35774;&#22791;&#31471;&#65292;&#19978;&#19979;&#25991;&#31383;&#21475;&#20165; 4096 &#20010; token&#65292;&#19968;&#26086;&#36229;&#20986;&#20415;&#26080;&#27861;&#32487;&#32493;&#23545;&#35805;&#12290;iOS 26.4 &#26032;&#22686;&#20102; token &#29992;&#37327;&#36861;&#36394; API&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#23454;&#26102;&#25484;&#25569;&#19978;&#19979;&#25991;&#28040;&#32791;&#24773;&#20917;&#12290;<a href="https://x.com/iosartem">Artem Novichkov</a> &#31995;&#32479;&#20171;&#32461;&#20102;&#22235;&#20010;&#20851;&#38190;&#25351;&#26631;&#65306;&#27169;&#22411;&#19978;&#19979;&#25991;&#24635;&#23481;&#37327;&#65288;<code>contextSize</code>&#65289;&#12289;Instructions &#30340; token &#28040;&#32791;&#12289;&#21333;&#26465; Prompt &#30340;&#28040;&#32791;&#65292;&#20197;&#21450;&#23436;&#25972;&#23545;&#35805;&#35760;&#24405;&#65288;Transcript&#65289;&#30340;&#32047;&#35745;&#29992;&#37327;&#12290;&#25991;&#31456;&#36824;&#25581;&#31034;&#20102;&#19968;&#20010;&#23481;&#26131;&#34987;&#24573;&#35270;&#30340;&#32454;&#33410;&#65306;&#24403;&#24341;&#20837; Tool &#26102;&#65292;&#20854;&#21517;&#31216;&#12289;&#25551;&#36848;&#19982;&#21442;&#25968; Schema &#20250;&#34987;&#24207;&#21015;&#21270;&#24182;&#35745;&#20837; token&#65292;&#21516;&#19968;&#27573; Instructions &#22312;&#38468;&#21152; Tool &#21518; token &#25968;&#20174; 16 &#36291;&#21319;&#33267; 79&#12290;&#23545;&#20110;&#35774;&#22791;&#31471;&#27169;&#22411;&#32780;&#35328;&#65292;token &#30340;&#21487;&#35266;&#27979;&#24615;&#23558;&#25104;&#20026;&#20248;&#21270;&#20307;&#39564;&#30340;&#22522;&#30784;&#35774;&#26045;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0124-08">App Store Connect CLI</a></strong></h3><p>App Store Connect CLI &#26159;&#30001; <a href="https://x.com/rudrank">Rudrank Riyam</a> &#24320;&#21457;&#30340;&#38750;&#23448;&#26041; App Store Connect &#21629;&#20196;&#34892;&#24037;&#20855;&#65292;&#21151;&#33021;&#35206;&#30422; TestFlight &#31649;&#29702;&#12289;&#26500;&#24314;&#19978;&#20256;&#12289;&#20195;&#30721;&#31614;&#21517;&#12289;&#25130;&#22270;&#33258;&#21160;&#21270;&#12289;&#26412;&#22320;&#21270;&#21516;&#27493;&#12289;&#24212;&#29992;&#23457;&#26680;&#25552;&#20132;&#12289;notarization&#65292;&#20197;&#21450;&#36130;&#21153;&#25253;&#21578;&#19979;&#36733;&#31561;&#23436;&#25972;&#21457;&#24067;&#38142;&#36335;&#12290;&#23427;&#20174;&#35774;&#35745;&#38454;&#27573;&#23601;&#24378;&#35843; Agent &#22330;&#26223;&#65292;&#24182;&#25552;&#20379;&#20102;&#38754;&#21521; Agent &#30340;&#23454;&#36341;&#25991;&#26723;&#12290;&#33509;&#20320;&#30340;&#21457;&#24067;&#27969;&#31243;&#37325;&#24515;&#22312; TestFlight&#12289;&#20803;&#25968;&#25454;&#12289;&#25552;&#23457;&#12289;&#31614;&#21517;&#19982; CI &#33258;&#21160;&#21270;&#65292;ASC &#21487;&#20197;&#20316;&#20026; fastlane &#30340;&#36731;&#37327;&#26367;&#20195;&#26041;&#26696;&#20043;&#19968;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-09">GRDB 7.10.0: &#26032;&#22686; Android&#12289;Linux&#12289;Windows &#25903;&#25345;</a></strong></h3><p>GRDB 7.10.0 &#26159;&#19968;&#20010;&#20855;&#26377;&#37324;&#31243;&#30865;&#24847;&#20041;&#30340;&#29256;&#26412;&#26356;&#26032;&#65306;&#26412;&#27425;&#27491;&#24335;&#24341;&#20837;&#23545; Android&#12289;Linux&#12289;Windows &#30340;&#25903;&#25345;&#65292;&#24182;&#26032;&#22686;&#36890;&#36807; Swift Package Manager &#20351;&#29992; SQLCipher&#65288;&#21152;&#23494;&#25968;&#25454;&#24211;&#65289;&#30340;&#33021;&#21147;&#8212;&#8212;&#36825;&#20004;&#39033;&#21151;&#33021;&#37117;&#38271;&#26399;&#21463;&#21040;&#31038;&#21306;&#26399;&#24453;&#12290;&#36825;&#24847;&#21619;&#30528;&#36825;&#20010; Swift &#29983;&#24577;&#20013;&#26368;&#25104;&#29087;&#30340; SQLite &#23553;&#35013;&#24211;&#65292;&#27491;&#22312;&#20174; Apple &#24179;&#21488;&#24037;&#20855;&#28436;&#36827;&#20026;&#30495;&#27491;&#30340;&#36328;&#24179;&#21488;&#25968;&#25454;&#23618;&#35299;&#20915;&#26041;&#26696;&#12290;</p><p><a href="https://x.com/groue">Gwendal Rou&#233;</a> &#22312; <a href="https://forums.swift.org/t/grdb-v7-10-0-android-linux-windows-and-sqlcipher-swiftpm/84754">&#29256;&#26412;&#20844;&#21578;</a> &#20013;&#20063;&#29305;&#21035;&#35828;&#26126;&#65292;&#30001;&#20110; Xcode &#23578;&#26410;&#25903;&#25345; package traits&#65292;SwiftPM &#30446;&#21069;&#20173;&#20250;&#19979;&#36733;&#26410;&#23454;&#38469;&#20351;&#29992;&#30340;&#20381;&#36182;&#65307;&#22312;&#30456;&#20851;&#38382;&#39064;&#35299;&#20915;&#20043;&#21069;&#65292;SQLCipher &#25903;&#25345;&#23558;&#20197; fork &#24418;&#24335;&#38271;&#26399;&#32500;&#25252;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0124-10">Swift System Metrics</a></strong></h3><p>Swift System Metrics &#20026; Swift &#24212;&#29992;&#65288;&#23588;&#20854;&#26159;&#26381;&#21153;&#31471;&#39033;&#30446;&#65289;&#25552;&#20379;&#20102;&#32479;&#19968;&#30340;&#31995;&#32479;&#32423;&#25351;&#26631;&#37319;&#38598;&#33021;&#21147;&#65292;&#20363;&#22914; CPU &#20351;&#29992;&#29575;&#12289;&#20869;&#23384;&#21344;&#29992;&#12289;&#25991;&#20214;&#25551;&#36848;&#31526;&#25968;&#37327;&#31561;&#65292;&#24182;&#36890;&#36807;&#26631;&#20934;&#21270;&#30340; Metrics &#25509;&#21475;&#23545;&#22806;&#26292;&#38706;&#65292;&#20415;&#20110;&#25509;&#20837; Prometheus &#31561;&#29616;&#26377;&#30417;&#25511;&#20307;&#31995;&#12290;&#23427;&#24182;&#38750;&#19968;&#20010;&#29420;&#31435;&#30340;&#30417;&#25511;&#31995;&#32479;&#65292;&#32780;&#26159;&#30001; Swift Server Work Group &#25512;&#21160;&#30340;&#22522;&#30784;&#35774;&#26045;&#32452;&#20214;&#65292;&#26088;&#22312;&#19982; Swift Metrics &#29983;&#24577;&#23545;&#40784;&#65292;&#20351;&#31995;&#32479;&#36164;&#28304;&#25351;&#26631;&#19982;&#24212;&#29992;&#32423;&#25351;&#26631;&#32435;&#20837;&#21516;&#19968;&#21487;&#35266;&#27979;&#20307;&#31995;&#12290;1.0 &#30340;&#21457;&#24067;&#24847;&#21619;&#30528; API &#24050;&#36235;&#20110;&#31283;&#23450;&#65292;&#20855;&#22791;&#29983;&#20135;&#29615;&#22659;&#20351;&#29992;&#26465;&#20214;&#12290;&#23545;&#27491;&#22312;&#26500;&#24314; Swift &#21518;&#31471;&#26381;&#21153;&#12289;&#25110;&#25345;&#32493;&#23436;&#21892; Swift &#21487;&#35266;&#27979;&#24615;&#33021;&#21147;&#30340;&#22242;&#38431;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20010;&#22522;&#30784;&#35774;&#26045;&#23618;&#38754;&#30340;&#20851;&#38190;&#25340;&#22270;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #123]]></title><description><![CDATA[Wishing Everyone a Happy Year of the Horse!]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-123</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-123</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 16 Feb 2026 02:00:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!nb3y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nb3y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nb3y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 424w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 848w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 1272w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nb3y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:94730,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/188014594?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nb3y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 424w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 848w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 1272w, https://substackcdn.com/image/fetch/$s_!nb3y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5937d52-2c9a-4021-8eb4-b360a12becd0_1400x933.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Wishing Everyone a Happy Year of the Horse!</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-123/">Read on web &#8594;</a></p><p>This Chinese New Year ushers in the <strong>Bingwu Year (&#19993;&#21320;)</strong> &#8212; a once&#8209;in&#8209;60&#8209;years <strong>&#8220;Red Horse Year&#8221; (&#36196;&#39532;&#24180;)</strong> .</p><p>In the traditional Chinese stem&#8209;branch calendar, the Heavenly Stem Bing (&#19993;) and the Earthly Branch Wu (&#21320;) both belong to the Fire element. This double&#8209;fire combination creates an exceptionally rare <strong>&#8220;Fire Horse&#8221; pattern</strong>. Since fire is associated with the colour red, this Year of the Horse is also called the <strong>&#8220;Red Horse Year&#8221; (&#32418;&#39532;&#24180;)</strong> . This red horse embodies pure vitality and soaring spirits, symbolising a year full of boundless energy and enterprising drive.</p><p>At this once&#8209;in&#8209;60&#8209;years auspicious moment, I wish all my readers: good health (CPU at full power), a soaring career (performance optimised), smooth sailing in everything (bug&#8209;free runtime), and immediate success (compilation passed)! &#127881;</p><p><a href="https://fatbobman.com/en/weekly/issue-122/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0123-01">Swift Concurrency from Zero to Hero | Reading List</a></strong></h3><p>Setting AI aside&#8212;since it still struggles to handle complex Swift 6 concurrency code at an expert level&#8212;even as tools rapidly evolve, you shouldn&#8217;t remain a passive observer. A systematic and comprehensive understanding of Swift Concurrency&#8212;its concepts, usage patterns, and historical evolution&#8212;is essential for building safer and more resilient applications from the ground up. In this article, <a href="https://x.com/AlexOzun">Alex Ozun</a> organizes a structured learning roadmap for Swift Concurrency, divided by difficulty levels. Each stage is accompanied by publicly available, free resources, with complexity gradually increasing. The goal is simple: complete the journey and move from Zero to Hero.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-02">A Modern iOS Project Setup in 15 Steps</a></strong></h3><p>For many developers, starting a new project means repeating a series of tedious setup steps. In this thread, <a href="https://x.com/ertembiyik">Ertem Biyik</a> outlines a modern engineering baseline for iOS projects in 15 steps: using <a href="https://l.fatbobman.com/sb-tuist-substack">Tuist</a> to manage dependencies and project generation, centralizing configuration through <code>xcconfig</code>, simplifying onboarding with a Makefile, and validating builds with GitHub Actions. He also recommends standardizing AI context with <code>AGENTS.md</code> and leveraging <a href="https://sosumi.ai/">sosumi.ai</a> for LLM-friendly Apple documentation.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-04">Micelio: Growing Software Like Nature Grows Forests</a></strong></h3><p>As AI becomes deeply embedded in development workflows, many traditional tools are starting to show their limitations. Using the metaphor of a mycelium network, <a href="https://x.com/pepicrft">Pedro Pi&#241;era</a> argues that Git&#8217;s model&#8212;capturing <strong>what changed</strong> but rarely preserving <strong>why it changed</strong>&#8212;may no longer be sufficient in an AI-first world. This article presents his systematic reflection on a &#8220;post-Git era&#8221; and introduces an experimental approach to agent-first collaboration. The accompanying open-source forge project, <a href="https://github.com/pepicrft/micelio">Micelio</a>, centers around sessions as the core unit to capture context and reasoning, shifting code hosting from storing diffs to storing decisions. Though still early-stage, the problem framing and engineering direction are worth watching.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-05">Copy-on-Write in Swift - How It Works and Why It Optimizes Memory</a></strong></h3><p>Copy-on-Write (COW) is a fundamental mechanism in Swift and a key reason value types can achieve strong semantics without sacrificing performance. <a href="https://x.com/sagarunagar_">Sagar Unagar</a> explains how Swift balances value semantics and runtime efficiency through a &#8220;struct wrapper + reference storage&#8221; model: reads share storage, while writes trigger a real copy only when the reference is no longer unique, detected via <code>isKnownUniquelyReferenced</code>. The article also demonstrates how to implement COW in custom types.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-06">Taking First Steps into Metal Shaders</a></strong></h3><p>For many SwiftUI developers, Metal can feel distant and complex. In this article, <a href="https://www.linkedin.com/in/letizia-granata/">Letizia Granata</a> walks through the basics of working with shaders&#8212;from understanding CPU/GPU responsibilities to adding a <code>.metal</code> file in Xcode and applying a simple shader effect in SwiftUI. Rather than diving into rendering pipelines or graphics theory, the focus is on getting something running, lowering the barrier to entry for experimentation.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-07">Setting Up a Backend Server for Our Landmarks App</a></strong></h3><p>Landmarks is Apple&#8217;s classic SwiftUI tutorial app, but its reliance on local JSON data leaves a gap between example and real-world architecture. <a href="https://linkedin.com/in/kyle-browning-eng-manager">Kyle Browning</a> builds a simple backend using Vapor to serve data via API, transforming the static demo into a client-server structure. The article covers model definition, routing, data responses, and integration with SwiftUI&#8212;less about complex business logic and more about extending a teaching example into something closer to production reality.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-08">In the Background: Spotlight Indexing</a></strong></h3><p>After a system update, Macs often run hot and sluggish for a few days&#8212;commonly attributed to Spotlight reindexing. But how exactly does Spotlight scan files, decide when to rebuild its index, and manage system resources in the background? <a href="https://x.com/howardnoakley">Howard Oakley</a> analyzes logs and empirical data to explore Spotlight&#8217;s triggering mechanisms, process behavior, and impact on I/O and performance, offering a deeper technical look at macOS internals.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0123-09">ScreenStateKit: A Better MVVM for the SwiftUI Concurrency Era</a></strong></h3><p>If you appreciate TCA&#8217;s unidirectional data flow and predictable state management but don&#8217;t want to fully refactor your existing MVVM architecture, ScreenStateKit may offer a pragmatic middle ground. <a href="https://www.linkedin.com/in/quang-tran-7780a962/">Anthony Tran</a> splits the traditional ViewModel into two clearly defined components: a <code>@MainActor</code>-isolated <code>ScreenState</code> that holds UI state, and a Swift actor-based <code>ScreenActionStore</code> that handles business logic and async tasks. All mutations flow through strongly typed Actions, bringing compile-time concurrency safety and TCA-like discipline to MVVM. Built-in loading/error handling, duplicate request prevention (ActionLocker), parent-child state propagation, and pagination support round out the design. Anthony also provides a detailed design <a href="https://medium.com/@qquang269/screenstatekit-a-better-mvvm-for-the-swiftui-concurrency-era-0b25d2793d30">article</a> explaining the architecture and its rationale.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-10">GitHub Directory Downloader</a></strong></h3><p>If you&#8217;ve ever cloned an entire repository just to download a single folder from GitHub, this tool is for you. Developed by <a href="https://x.com/StewartLynch">Stewart Lynch</a>, this native macOS app lets you paste any GitHub repository or directory URL (including <code>tree/branch/path</code> formats), automatically detect the default branch, recursively download the selected directory, and preserve its original structure.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-11">SimTag: Branch Context for Your iOS Simulators</a></strong></h3><p>In parallel development workflows, it&#8217;s easy to lose track of which branch is running in which iOS Simulator. Developed by <a href="https://www.linkedin.com/in/aryaman-sharda-12753168/">Aryaman Sharda</a>, SimTag overlays a lightweight label on each Simulator window, showing the git branch and commit corresponding to the running build. For developers using worktrees, reviewing PRs, or collaborating with AI tools, it helps reduce cognitive friction and prevents debugging the wrong branch.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-123?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-123?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#31069;&#22823;&#23478;&#39532;&#24180;&#26032;&#26149;&#24555;&#20048;&#65281;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-123/">&#32593;&#39029;&#29256;</a></strong></p><p>&#20170;&#24180;&#30340;&#20013;&#22269;&#20892;&#21382;&#24180;&#26159;&#19993;&#21320;&#24180;&#65292;&#26159;&#19968;&#20010;60&#24180;&#19968;&#36935;&#30340;&#8220;&#36196;&#39532;&#24180;&#8221;&#12290;</p><p>&#22312;&#24178;&#25903;&#32426;&#24180;&#20013;&#65292;&#22825;&#24178;&#8220;&#19993;&#8221;&#19982;&#22320;&#25903;&#8220;&#21320;&#8221;&#20116;&#34892;&#30342;&#23646;&#28779;&#65292;&#21452;&#28779;&#21472;&#21152;&#65292;&#24418;&#25104;&#20102;&#26497;&#20026;&#32597;&#35265;&#30340;&#8220;&#28779;&#39532;&#8221;&#26684;&#23616;&#12290;&#22240;&#28779;&#33394;&#20026;&#36196;&#65292;&#25925;&#27492;&#39532;&#24180;&#21448;&#31216;&#8220;&#32418;&#39532;&#24180;&#8221;&#12290;&#36825;&#21305;&#8220;&#32418;&#39532;&#8221;&#25215;&#36733;&#30528;&#26368;&#32431;&#31929;&#30340;&#38451;&#21018;&#20043;&#27668;&#19982;&#34028;&#21187;&#27963;&#21147;&#65292;&#39044;&#31034;&#30528;&#25509;&#19979;&#26469;&#30340;&#19968;&#24180;&#23558;&#20805;&#28385;&#22868;&#25918;&#30340;&#33021;&#37327;&#19982;&#26114;&#25196;&#30340;&#36827;&#21462;&#24515;&#12290;</p><p>&#22312;&#36825;&#20010; 60 &#24180;&#19968;&#36935;&#30340;&#21513;&#24198;&#33410;&#28857;&#65292;&#25105;&#22312;&#27492;&#31069;&#21508;&#20301;&#35835;&#32773;&#26032;&#30340;&#19968;&#24180;&#65306;<strong>&#36523;&#20307;&#20581;&#24247;&#65288;CPU &#28385;&#34880;&#65289;&#65292;&#20107;&#19994;&#39536;&#39563;&#65288;&#24615;&#33021;&#20248;&#21270;&#65289;&#65292;&#19975;&#20107;&#39034;&#36930;&#65288;&#26080; Bug &#36816;&#34892;&#65289;&#65292;&#39532;&#21040;&#25104;&#21151;&#65288;&#32534;&#35793;&#36890;&#36807;&#65289;&#65281;</strong> &#127881;</p><p><a href="https://fatbobman.com/zh/weekly/issue-122/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0123-01">Swift &#24182;&#21457;&#36827;&#38454;&#38405;&#35835;&#36335;&#32447;&#22270; (Swift Concurrency from Zero to Hero | Reading List)</a></strong></h3><p>&#26242;&#19981;&#35828; AI &#30446;&#21069;&#36824;&#24456;&#38590;&#20687;&#19987;&#23478;&#19968;&#26679;&#22788;&#29702; Swift 6 &#24182;&#21457;&#30456;&#20851;&#30340;&#22797;&#26434;&#20195;&#30721;&#65292;&#21363;&#20415;&#24037;&#20855;&#33021;&#21147;&#31361;&#39134;&#29467;&#36827;&#65292;&#20316;&#20026;&#20351;&#29992;&#32773;&#30340;&#20320;&#20063;&#19981;&#35813;&#21482;&#24403;&#26049;&#35266;&#32773;&#65306;&#31995;&#32479;&#12289;&#20840;&#38754;&#22320;&#29702;&#35299; Swift &#24182;&#21457;&#30340;&#27010;&#24565;&#12289;&#29992;&#27861;&#19982;&#21382;&#21490;&#33033;&#32476;&#65292;&#25165;&#33021;&#20174;&#28304;&#22836;&#26500;&#24314;&#26356;&#23433;&#20840;&#12289;&#26356;&#24378;&#20581;&#30340;&#24212;&#29992;&#12290;<a href="https://x.com/AlexOzun">Alex Ozun</a> &#22312;&#26412;&#25991;&#20013;&#25353;&#38590;&#24230;&#21010;&#20998;&#20851;&#21345;&#65292;&#25972;&#29702;&#20102;&#19968;&#20221;&#8220;&#20174;&#20837;&#38376;&#21040;&#36827;&#38454;&#8221;&#30340; Swift Concurrency &#38405;&#35835;&#36335;&#32447;&#22270;&#65306;&#27599;&#19968;&#20851;&#37117;&#37197;&#22871;&#20102;&#20844;&#24320;&#19988;&#20813;&#36153;&#30340;&#21442;&#32771;&#36164;&#26009;&#65292;&#38590;&#24230;&#20063;&#20250;&#36880;&#32423;&#36882;&#22686;&#65292;&#24076;&#26395;&#20320;&#22312;&#23436;&#25104;&#36825;&#26465;&#20027;&#32447;&#20043;&#21518;&#65292;&#33021;&#20174; Zero &#36208;&#21040; Hero&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-02">15 &#27493;&#25171;&#36896;&#29616;&#20195; iOS &#39033;&#30446; (A Modern iOS Project Setup in 15 Steps)</a></strong></h3><p>&#23545;&#20110;&#19981;&#23569;&#24320;&#21457;&#32773;&#32780;&#35328;&#65292;&#26032;&#39033;&#30446;&#30340;&#24320;&#22987;&#24448;&#24448;&#20276;&#38543;&#30528;&#37325;&#22797;&#32780;&#29712;&#30862;&#30340;&#37197;&#32622;&#24037;&#20316;&#12290;<a href="https://x.com/ertembiyik">Ertem Biyik</a> &#22312;&#36825;&#26465;&#20018;&#36148;&#20013;&#29992; 15 &#20010;&#27493;&#39588;&#26803;&#29702;&#20102;&#19968;&#22871;&#29616;&#20195; iOS &#39033;&#30446;&#30340;&#24037;&#31243;&#21270;&#22522;&#32447;&#65306;&#20197; <a href="https://l.fatbobman.com/sb-tuist-substack">Tuist</a> &#20026;&#26680;&#24515;&#31649;&#29702;&#20381;&#36182;&#19982;&#29983;&#25104;&#65292;&#36890;&#36807; <code>xcconfig</code> &#32479;&#19968;&#29615;&#22659;&#37197;&#32622;&#19982;&#26500;&#24314;&#21442;&#25968;&#65292;&#20511;&#21161; Makefile &#31616;&#21270;&#21021;&#22987;&#21270;&#27969;&#31243;&#65292;&#24182;&#22312; GitHub Actions &#20013;&#23436;&#25104; lint &#19982;&#26500;&#24314;&#26657;&#39564;&#65307;&#21516;&#26102;&#65292;&#20182;&#36824;&#24314;&#35758;&#20351;&#29992; <code>AGENTS.md</code> &#32479;&#19968; AI &#19978;&#19979;&#25991;&#65292;&#24182;&#37197;&#21512; <a href="https://sosumi.ai/">sosumi.ai</a> &#33719;&#21462;&#26356;&#21033;&#20110; LLM &#38405;&#35835;&#30340; Apple &#25991;&#26723;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-04">Micelio&#65306;&#21518; Git &#26102;&#20195;&#30340;&#20195;&#30721;&#25176;&#31649;&#24037;&#20855; (Micelio: Growing Software Like Nature Grows Forests)</a></strong></h3><p>AI &#28145;&#24230;&#21442;&#19982;&#24320;&#21457;&#27969;&#31243;&#21518;&#65292;&#35768;&#22810;&#20256;&#32479;&#24037;&#20855;&#24320;&#22987;&#26174;&#38706;&#20986;&#8220;&#27700;&#22303;&#19981;&#26381;&#8221;&#12290;<a href="https://x.com/pepicrft">Pedro Pi&#241;era</a> &#20197;&#8220;&#33740;&#19997;&#32593;&#32476;&#65288;mycelium&#65289;&#8221;&#20026;&#38544;&#21947;&#65292;&#25351;&#20986;&#38543;&#30528; AI agent &#21442;&#19982;&#24320;&#21457;&#30340;&#35268;&#27169;&#19982;&#39057;&#29575;&#19981;&#26029;&#25552;&#21319;&#65292;Git &#36825;&#31181;&#21482;&#35760;&#24405; <strong>what changed</strong>&#12289;&#21364;&#38590;&#20197;&#20445;&#30041; <strong>why it changed</strong> &#30340;&#21382;&#21490;&#27169;&#22411;&#65292;&#27491;&#22312;&#21464;&#24471;&#19981;&#22815;&#20805;&#20998;&#12290;&#26412;&#25991;&#26159;&#20182;&#23545;&#8220;&#21518; Git &#26102;&#20195;&#8221;&#30340;&#19968;&#27425;&#31995;&#32479;&#24615;&#24605;&#32771;&#65292;&#20063;&#26159;&#23545;&#8220;agent-first &#21327;&#20316;&#26041;&#24335;&#8221;&#30340;&#20844;&#24320;&#23454;&#39564;&#12290;&#37197;&#22871;&#30340;&#24320;&#28304; git forge <a href="https://github.com/pepicrft/micelio">Micelio</a> &#39033;&#30446;&#23581;&#35797;&#20197; session &#20026;&#26680;&#24515;&#21333;&#20803;&#25429;&#33719;&#19978;&#19979;&#25991;&#19982;&#25512;&#29702;&#65292;&#23558;&#20195;&#30721;&#25176;&#31649;&#30340;&#37325;&#24515;&#20174;&#8220;&#23384; diff&#8221;&#36716;&#21521;&#8220;&#23384;&#20915;&#31574;&#8221;&#12290;&#39033;&#30446;&#20173;&#22788;&#20110;&#26089;&#26399;&#38454;&#27573;&#65292;&#20294;&#20854;&#38382;&#39064;&#24847;&#35782;&#19982;&#24037;&#31243;&#26041;&#21521;&#65292;&#37117;&#20540;&#24471;&#25345;&#32493;&#20851;&#27880;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-05">Swift &#20889;&#26102;&#22797;&#21046; (Copy-on-Write in Swift - How It Works and Why It Optimizes Memory)</a></strong></h3><p>&#20889;&#26102;&#22797;&#21046;&#65288;COW&#65289;&#26159; Swift &#30340;&#26680;&#24515;&#26426;&#21046;&#20043;&#19968;&#65292;&#20063;&#26159;&#20540;&#31867;&#22411;&#22312;&#20445;&#35777;&#35821;&#20041;&#19968;&#33268;&#24615;&#30340;&#21516;&#26102;&#33719;&#24471;&#33391;&#22909;&#24615;&#33021;&#30340;&#20851;&#38190;&#12290;<a href="https://x.com/sagarunagar_">Sagar Unagar</a> &#32467;&#21512;&#38598;&#21512;&#31867;&#22411;&#30340;&#20869;&#37096;&#23454;&#29616;&#65292;&#35299;&#37322;&#20102; Swift &#22914;&#20309;&#36890;&#36807;&#8220;&#32467;&#26500;&#20307;&#22806;&#22771; + &#24341;&#29992;&#23384;&#20648;&#8221;&#30340;&#26041;&#24335;&#23454;&#29616;&#35835;&#20849;&#20139;&#12289;&#20889;&#20998;&#31163;&#65306;&#21482;&#26377;&#22312;&#21457;&#29983;&#20889;&#20837;&#19988;&#26816;&#27979;&#21040;&#38750;&#21807;&#19968;&#24341;&#29992;&#26102;&#65292;&#25165;&#20250;&#20511;&#21161; <code>isKnownUniquelyReferenced</code> &#35302;&#21457;&#30495;&#27491;&#30340;&#25335;&#36125;&#12290;&#25991;&#31456;&#21516;&#26102;&#23637;&#31034;&#20102;&#33258;&#23450;&#20041;&#31867;&#22411;&#23454;&#29616; COW &#30340;&#22522;&#26412;&#27169;&#24335;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-06">Metal Shader &#20837;&#38376; (Taking First Steps into Metal Shaders)</a></strong></h3><p>&#23545;&#20110;&#22823;&#22810;&#25968; SwiftUI &#24320;&#21457;&#32773;&#32780;&#35328;&#65292;Metal &#24448;&#24448;&#26174;&#24471;&#36965;&#36828;&#32780;&#22797;&#26434;&#12290;<a href="https://www.linkedin.com/in/letizia-granata/">Letizia Granata</a> &#36890;&#36807;&#26412;&#25991;&#24102;&#20320;&#20174; 0 &#24320;&#22987;&#25509;&#35302; Shader&#65306;&#20174;&#29702;&#35299; GPU &#19982; CPU &#30340;&#20998;&#24037;&#65292;&#21040;&#22312; Xcode &#20013;&#28155;&#21152; <code>.metal</code> &#25991;&#20214;&#65292;&#20877;&#21040;&#32534;&#20889;&#24182;&#22312; SwiftUI &#20013;&#24212;&#29992;&#19968;&#20010;&#26368;&#31616;&#21333;&#30340; shader &#25928;&#26524;&#12290;Letizia &#27809;&#26377;&#28145;&#20837;&#28210;&#26579;&#31649;&#32447;&#25110;&#22270;&#24418;&#23398;&#32454;&#33410;&#65292;&#32780;&#26159;&#32858;&#28966;&#8220;&#22914;&#20309;&#30495;&#27491;&#36305;&#36215;&#26469;&#8221;&#65292;&#24110;&#21161;&#35835;&#32773;&#36328;&#36807;&#20837;&#38376;&#38376;&#27099;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-07">&#20026; Landmarks &#26500;&#24314; Vapor &#21518;&#31471; (Setting Up a Backend Server for Our Landmarks App)</a></strong></h3><p>Landmarks &#26159; Apple &#22312; SwiftUI &#25945;&#31243;&#20013;&#25552;&#20379;&#30340;&#32463;&#20856;&#31034;&#20363;&#24212;&#29992;&#65292;&#20294;&#30001;&#20110;&#23427;&#20351;&#29992;&#26412;&#22320; JSON &#25968;&#25454;&#65292;&#19982;&#30495;&#23454;&#39033;&#30446;&#30340;&#23458;&#25143;&#31471;&#8212;&#26381;&#21153;&#22120;&#26550;&#26500;&#20173;&#23384;&#22312;&#24046;&#36317;&#12290;<a href="https://linkedin.com/in/kyle-browning-eng-manager">Kyle Browning</a> &#20351;&#29992; Vapor &#20026; Landmarks &#26500;&#24314;&#20102;&#19968;&#20010;&#31616;&#21333;&#30340;&#21518;&#31471;&#26381;&#21153;&#65292;&#23558;&#38745;&#24577;&#31034;&#20363;&#21319;&#32423;&#20026;&#36890;&#36807; API &#33719;&#21462;&#25968;&#25454;&#30340;&#23436;&#25972;&#32467;&#26500;&#12290;&#25991;&#31456;&#22260;&#32469;&#27169;&#22411;&#23450;&#20041;&#12289;&#36335;&#30001;&#37197;&#32622;&#12289;&#25968;&#25454;&#21709;&#24212;&#20197;&#21450;&#19982; SwiftUI &#21069;&#31471;&#30340;&#23545;&#25509;&#23637;&#24320;&#65292;&#37325;&#28857;&#19981;&#22312;&#22797;&#26434;&#19994;&#21153;&#36923;&#36753;&#65292;&#32780;&#22312;&#20110;&#31034;&#33539;&#22914;&#20309;&#25226;&#19968;&#20010;&#8220;&#25945;&#23398;&#31034;&#20363;&#8221;&#25193;&#23637;&#20026;&#26356;&#36148;&#36817;&#30495;&#23454;&#19990;&#30028;&#30340;&#39033;&#30446;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-08">Spotlight &#21518;&#21488;&#32034;&#24341;&#26426;&#21046;&#35299;&#26512; (In the Background: Spotlight Indexing)</a></strong></h3><p>&#31995;&#32479;&#26356;&#26032;&#21518;&#30340;&#20960;&#22825;&#37324;&#26426;&#22120;&#21457;&#28909;&#12289;&#21345;&#39039;&#65292;&#24456;&#22810;&#20154;&#37117;&#30693;&#36947;&#36825;&#19982; Spotlight &#30340;&#37325;&#26032;&#32034;&#24341;&#26377;&#20851;&#65292;&#20294;&#23427;&#22312;&#21518;&#21488;&#22914;&#20309;&#25195;&#25551;&#25991;&#20214;&#12289;&#20309;&#26102;&#35302;&#21457;&#37325;&#24314;&#32034;&#24341;&#12289;&#21448;&#22914;&#20309;&#35843;&#24230;&#31995;&#32479;&#36164;&#28304;&#65292;&#21364;&#40092;&#23569;&#34987;&#31995;&#32479;&#24615;&#26803;&#29702;&#12290;<a href="https://x.com/howardnoakley">Howard Oakley</a> &#22522;&#20110;&#26085;&#24535;&#19982;&#23454;&#27979;&#25968;&#25454;&#65292;&#23545; Spotlight &#32034;&#24341;&#30340;&#35302;&#21457;&#26426;&#21046;&#12289;&#36827;&#31243;&#34892;&#20026;&#20197;&#21450;&#23545; I/O &#19982;&#24615;&#33021;&#30340;&#24433;&#21709;&#36827;&#34892;&#20102;&#32454;&#33268;&#20998;&#26512;&#65292;&#25552;&#20379;&#20102;&#19968;&#27425;&#20851;&#20110; macOS &#20869;&#37096;&#36816;&#34892;&#26426;&#21046;&#30340;&#28145;&#20837;&#25216;&#26415;&#35266;&#23519;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0123-09">ScreenStateKit&#65306;&#24182;&#21457;&#26102;&#20195;&#30340; MVVM &#28436;&#36827;</a></strong></h3><p>&#22914;&#26524;&#20320;&#27427;&#36175; TCA &#30340;&#21333;&#21521;&#25968;&#25454;&#27969;&#19982;&#21487;&#39044;&#27979;&#29366;&#24577;&#31649;&#29702;&#65292;&#21364;&#21448;&#19981;&#24819;&#22312;&#29616;&#26377; MVVM &#39033;&#30446;&#20013;&#24443;&#24213;&#37325;&#26500;&#26550;&#26500;&#65292;&#37027;&#20040; ScreenStateKit &#29366;&#24577;&#31649;&#29702;&#24211;&#20063;&#35768;&#26159;&#19968;&#20010;&#25240;&#20013;&#26041;&#26696;&#12290;&#20316;&#32773; <a href="https://www.linkedin.com/in/quang-tran-7780a962/">Anthony Tran</a> &#23558;&#20256;&#32479; ViewModel &#25286;&#20998;&#20026;&#20004;&#20010;&#32844;&#36131;&#28165;&#26224;&#30340;&#37096;&#20998;&#65306;&#19968;&#20010;&#36816;&#34892;&#22312; <code>@MainActor</code> &#19978;&#12289;&#21482;&#36127;&#36131;&#25345;&#26377; UI &#29366;&#24577;&#30340; <code>ScreenState</code>&#65292;&#20197;&#21450;&#19968;&#20010;&#20197; Swift actor &#23454;&#29616;&#12289;&#19987;&#38376;&#22788;&#29702;&#19994;&#21153;&#36923;&#36753;&#19982;&#24322;&#27493;&#20219;&#21153;&#30340; <code>ScreenActionStore</code>&#65292;&#25152;&#26377;&#29366;&#24577;&#21464;&#26356;&#37117;&#36890;&#36807;&#24378;&#31867;&#22411; Action &#20316;&#20026;&#21807;&#19968;&#20837;&#21475;&#65292;&#20174;&#32780;&#22312;&#20445;&#25345; MVVM &#32467;&#26500;&#30452;&#35266;&#24615;&#30340;&#21516;&#26102;&#65292;&#24341;&#20837;&#31867;&#20284; TCA &#30340;&#21333;&#21521;&#25968;&#25454;&#27969;&#19982;&#32534;&#35793;&#26399;&#24182;&#21457;&#23433;&#20840;&#12290;&#37197;&#21512;&#20869;&#24314;&#30340;&#21152;&#36733;&#19982;&#38169;&#35823;&#29366;&#24577;&#31649;&#29702;&#12289;&#37325;&#22797;&#35831;&#27714;&#38450;&#25252;&#65288;ActionLocker&#65289;&#12289;&#29238;&#23376;&#29366;&#24577;&#20256;&#25773;&#19982;&#20998;&#39029;&#25903;&#25345;&#12290;Anthony &#20134;&#25776;&#20889;&#20102;&#19968;&#31687;&#35814;&#23613;&#30340;&#35774;&#35745;&#35828;&#26126;<a href="https://medium.com/@qquang269/screenstatekit-a-better-mvvm-for-the-swiftui-concurrency-era-0b25d2793d30">&#25991;&#31456;</a>&#65292;&#23545;&#20854;&#26550;&#26500;&#29702;&#24565;&#19982;&#23454;&#36341;&#32454;&#33410;&#36827;&#34892;&#20102;&#31995;&#32479;&#38416;&#36848;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-10">GitHub &#23376;&#30446;&#24405;&#19979;&#36733;&#24037;&#20855;</a></strong></h3><p>&#22914;&#26524;&#20320;&#26366;&#20026;&#20102;&#19979;&#36733; GitHub &#19978;&#30340;&#26576;&#20010;&#31034;&#20363;&#30446;&#24405;&#32780;&#34987;&#36843; <code>git clone</code> &#25972;&#20010;&#20179;&#24211;&#65292;&#36825;&#27454; GitHub Downloader &#26174;&#28982;&#27491;&#26159;&#20026;&#27492;&#32780;&#29983;&#12290;&#23427;&#26159; <a href="https://x.com/StewartLynch">Stewart Lynch</a> &#24320;&#21457;&#30340;&#19968;&#27454;&#21407;&#29983; macOS &#24212;&#29992;&#65292;&#20801;&#35768;&#20320;&#31896;&#36148;&#20219;&#24847; GitHub &#20179;&#24211;&#25110;&#23376;&#30446;&#24405; URL&#65288;&#21253;&#25324; <code>tree/branch/path</code> &#24418;&#24335;&#65289;&#65292;&#33258;&#21160;&#35782;&#21035;&#40664;&#35748;&#20998;&#25903;&#65292;&#36882;&#24402;&#19979;&#36733;&#25152;&#36873;&#30446;&#24405;&#20869;&#23481;&#65292;&#24182;&#23436;&#25972;&#20445;&#30041;&#20854;&#21407;&#22987;&#23618;&#32423;&#32467;&#26500;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0123-11">SimTag&#65306;&#20026;&#27169;&#25311;&#22120;&#26631;&#27880;&#20998;&#25903;&#19978;&#19979;&#25991;</a></strong></h3><p>&#22312;&#24182;&#34892;&#24320;&#21457;&#25104;&#20026;&#24120;&#24577;&#30340;&#20170;&#22825;&#65292;&#38754;&#23545;&#22810;&#20010;&#22806;&#35266;&#20960;&#20046;&#30456;&#21516;&#30340; iOS Simulator&#65292;&#24320;&#21457;&#32773;&#24456;&#23481;&#26131;&#36855;&#22833;&#65306;&#21040;&#24213;&#21738;&#20010;&#20998;&#25903;&#27491;&#22312;&#36816;&#34892;&#65311;&#26159;&#21542;&#35843;&#35797;&#20102;&#38169;&#35823;&#30340;&#26500;&#24314;&#29256;&#26412;&#65311;<a href="https://www.linkedin.com/in/aryaman-sharda-12753168/">Aryaman Sharda</a> &#24320;&#21457;&#30340; SimTag &#20250;&#22312;&#27599;&#20010; Simulator &#31383;&#21475;&#19978;&#21472;&#21152;&#19968;&#20010;&#36731;&#37327;&#26631;&#35782;&#65292;&#26174;&#31034;&#24403;&#21069;&#26500;&#24314;&#23545;&#24212;&#30340; git &#20998;&#25903;&#19982;&#25552;&#20132;&#20449;&#24687;&#12290;&#23545;&#20110;&#20064;&#24815;&#20351;&#29992; worktrees&#12289;&#36827;&#34892; PR &#23457;&#26597;&#25110;&#32467;&#21512; AI &#21327;&#20316;&#24320;&#21457;&#30340;&#22242;&#38431;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20010;&#33021;&#22815;&#26174;&#33879;&#20943;&#23569;&#35748;&#30693;&#25705;&#25830;&#12289;&#36991;&#20813;&#8220;&#35843;&#38169;&#20998;&#25903;&#8221;&#30340;&#23454;&#29992;&#23567;&#24037;&#20855;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #122]]></title><description><![CDATA[Xcode Enters the Agent Era]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-122</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-122</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 09 Feb 2026 12:02:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9DDu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9DDu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9DDu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 424w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 848w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 1272w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9DDu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp" width="1400" height="931" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:931,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87284,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/187341335?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9DDu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 424w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 848w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 1272w, https://substackcdn.com/image/fetch/$s_!9DDu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc60fecf0-96c8-475b-b818-a0005826a824_1400x931.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@tinkerman?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Immo Wegmann</a> on <a href="https://unsplash.com/photos/a-piece-of-cardboard-with-a-keyboard-appearing-through-it-vi1HXPw6hyw?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Xcode Enters the Agent Era</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-122/">Read on web &#8594;</a></p><p>Although Apple had already incorporated AI-assisted programming capabilities in the initial version of Xcode 26, the experience felt more like ChatGPT being awkwardly embedded into the IDE: the functionality existed, but felt disconnected. Compared to the then-popular Cursor, it seemed like a product from a different era. As AI CLI tools like Claude Code gradually matured, Xcode appeared to fall further behind, leading many developers to question whether it could still serve as a &#8220;primary IDE&#8221; in the AI age.</p><p>The arrival of version 26.3, with almost no advance notice, responded to these doubts with concrete action. By integrating Claude Code/Codex, Apple&#8217;s answer was direct: with the right strategy, Xcode remains a highly promising development environment within the Apple ecosystem. This time, Xcode didn&#8217;t simply add a CLI tool panel; instead, it introduced a native set of Xcode Tools (MCP), coordinated with official technical documentation for Swift 6, SwiftUI, SwiftData, and more, creating a highly consistent experience aligned with the latest practices. Even for developers already proficient with CLI + XcodeBuildMCP + various Skills, this native solution remains highly competitive&#8212;especially with its near-zero configuration cost, which is significant for the vast majority of developers.</p><p>More notably, the Xcode Tools provided in this update don&#8217;t just serve Xcode itself; they can also function as standard MCP to provide capabilities for other AI tools. This open approach doesn&#8217;t entirely align with the outside world&#8217;s impression of Apple&#8217;s usual style.</p><p>Of course, from today&#8217;s vantage point, we cannot yet assert that Xcode has returned to the first tier. But what&#8217;s certain is that 26.3 has sent a very clear signal: Apple is willing to collaborate with mainstream tools and services to create development experiences that truly align with the times. For this reason, I have higher expectations for the next iteration of Siri&#8212;likely in iOS 27, Apple will provide more standardized interfaces for the system and apps beyond the existing Intent framework, allowing AI to integrate more naturally into the entire ecosystem.</p><p>Xcode + Agent is just the beginning.</p><p>Apple + Agent is the future worth paying more attention to.</p><p><a href="https://fatbobman.com/en/weekly/issue-121/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Original</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/xcode-263-claude/?utm_source=fatbobman%20weekly%20issue%20122&amp;utm_medium=web">Xcode 26.3 + Claude Agent: Model Swapping, MCP, Skills, and Adaptive Configuration</a></strong></h3><p>Xcode 26.3 directly provides support for Claude Code/Codex. Finally, developers can conveniently use native AI Agents in Xcode. Over the past few days, I&#8217;ve conducted a series of experiments with the new version, including how to use the latest models, configure MCPs/Skills/Commands, and write adaptive <code>CLAUDE.md</code>. This article uses Claude Code as an example to share some tips beyond the documentation.</p><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/screensage-from-pixel-to-meta/?utm_source=fatbobman%20weekly%20issue%20122&amp;utm_medium=web">From Pixel Capture to Metadata: Reimagining Screen Recording Architecture on macOS</a></strong></h3><p>Video is replacing text as a more popular form of expression, and good tools accelerate creation. <a href="https://x.com/s1ntone">Sintone</a>, developer of the macOS screen recording software <a href="https://screensage.pro/">ScreenSage Pro</a>, provides an in-depth retrospective on implementing &#8220;finished editing upon recording completion&#8221; based on ScreenCaptureKit and Metal. From solving the cryptic SCK -3821 error to migrating from ObservableObject to @Observable to optimize timeline performance, this article openly shares the entire process from pixel capture to high-performance composition.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-05">Which Method is Fastest for Checking if a String is in a Whitelist: Set, Array, Enum, Dictionary, or Switch?</a></strong></h3><p>In Swift, checking whether a string belongs to a set of keys can be written as <code>Set.contains</code>, <code>Array.contains</code>, RawRepresentable enum&#8217;s <code>init?(rawValue:)</code>, <code>switch</code> with multiple cases, or even using a <code>Dictionary</code> for mapping. They may look similar, but when placed in performance-sensitive paths, the results might not fully align with intuition. <a href="https://mastodon.social/@helge">Helge He&#223;</a> conducted a simple benchmark test: <code>Set.contains</code> leads without suspense, followed by <code>enum(rawValue:)</code> and <code>Dictionary</code> (very close to each other); while <code>switch</code>, which many would instinctively overestimate, actually ranks after <code>enum</code>, with <code>Array.contains</code> finishing last. As a small experiment, these results might be just what we need to calibrate our intuition about Swift performance.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-01">Migrating an iOS app from Paid up Front to Freemium</a></strong></h3><p>Paid download and free + in-app purchase are two fundamentally different business models, and as apps evolve, developers may need to transition between them. In this article, <a href="https://x.com/donnywals">Donny Wals</a> shares his complete experience converting the Practical Core Data app from a $4.99 paid download to freemium. The article not only covers StoreKit 2 technical implementation details (purchase flow, state management, family sharing), but more valuably, his deep thinking on business decisions: while the paid barrier can filter for serious users, it also blocks many potential users from experiencing the product&#8217;s value. For educational or utility indie apps, freemium may be a better balance between user growth and revenue.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-02">On-demand resources in iOS app</a></strong></h3><p>App size has always been a concern for developers, especially when apps contain large amounts of images, audio, or other resources. Although Apple introduced On-Demand Resources (ODR) in iOS early on to address this challenge, this feature has a weak presence and is often overlooked by developers. In this article, <a href="https://twitter.com/mecid">Majid Jabrayilov</a> systematically reviews ODR&#8217;s working mechanism and usage, including resource grouping, tag management, download lifecycle, and collaboration with system caching strategies.</p><p>While Apple is promoting Background Assets as a more modern solution, ODR still has unique value in scenarios requiring immediate response for on-demand downloads and fine-grained resource control.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-03">Objectively Better, Observably Trickier</a></strong></h3><p>When fully embracing the Observation framework, developers need to be aware that its working mechanism differs from Combine&#8217;s <code>@Published</code>, and simple replacement often introduces subtle issues. <a href="https://x.com/dbolella">Danny Bolella</a> summarizes four common pitfalls during migration: non-lazy initialization when <code>@State</code> holds reference types, update loss caused by nested <code>@Observable</code> objects, changes in array element binding methods, and conflicts with other property wrappers. The article provides solutions through clear code examples and repeatedly emphasizes a core principle: updates only trigger when properties currently being accessed (getter called) by the view change. Understanding and adapting to this &#8220;lazy observation&#8221; mindset is key to correctly using the Observation framework.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-04">Add an Open Recent Menu to a SwiftUI app</a></strong></h3><p>&#8220;Open Recent&#8221; is a standard macOS app feature, but for SwiftUI developers, correctly implementing this functionality is not intuitive. In this article, <a href="https://mastodon.world/@swiftdevjournal">Mark Szymczyk</a> demonstrates through a concise example how to use <code>NSDocumentController</code> to integrate system-level recent file management capabilities into your app: automatic list maintenance, menu updates, and seamless coordination with document lifecycle. For document or utility apps, this is a low-cost detail optimization that can significantly enhance the &#8220;native feel.&#8221;</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0122-06">Radioform: A Native, Open-Source macOS Audio Equalizer</a></strong></h3><p>macOS has long lacked a system-level audio equalizer. Radioform, developed by <a href="https://www.linkedin.com/in/matthew-porteous-23847a2b2/">Matthew Porteous</a>, fills this gap. The project employs a layered architecture of SwiftUI menu bar App + Swift Host + CoreAudio HAL Driver + C++ DSP, completely decoupling UI from real-time audio processing. The DSP portion implements 10-band parametric EQ, parameter smoothing, limiting, and real-time safety control; the engineering also includes complete CI, code signing notarization, and DMG release workflow. This isn&#8217;t a &#8220;just make it work&#8221; demo, but a production-grade audio engineering template approaching long-term maintainability.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-07">CircuitPro: Native macOS PCB Design Tool</a></strong></h3><p>This is a domain rarely explored by macOS native apps: PCB design. CircuitPro is a PCB EDA tool for macOS, aiming to make schematic, layout, and component library workflows more aligned with Apple platform conventions. (The project is still in early development stages)</p><p>What attracts me most about the project is the custom-built CanvasKit. It&#8217;s more like a 2D interaction engine for EDA scenarios rather than just a regular canvas component: the top layer is declarative <code>CanvasView</code>, the middle layer is the state hub <code>CanvasController</code>, and the bottom layer is input routing, render tree, and tool system. More critically, snapping, input handling, and wiring engine are all made into protocol-based pluggable points, allowing schematics and layout to share the same infrastructure while retaining their respective routing rules.</p><p>Even if you&#8217;re not interested in PCB design itself, CircuitPro is worth attention, especially for its engineering practices in SwiftUI + AppKit hybrid architecture.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-122?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-122?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>Xcode &#36808;&#20837; Agent &#26102;&#20195;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-122/">&#32593;&#39029;&#29256;</a></strong></p><p>&#23613;&#31649;&#22312; Xcode 26 &#30340;&#26368;&#21021;&#29256;&#26412;&#20013;&#65292;&#33529;&#26524;&#23601;&#24050;&#32463;&#21152;&#20837;&#20102;&#19968;&#23450;&#30340; AI &#36741;&#21161;&#32534;&#31243;&#33021;&#21147;&#65292;&#20294;&#24403;&#26102;&#30340;&#20307;&#39564;&#26356;&#20687;&#26159;&#25226; ChatGPT &#29983;&#30828;&#22320;&#23884;&#20837;&#21040; IDE &#20013;&#65306;&#21151;&#33021;&#23384;&#22312;&#65292;&#21364;&#24444;&#27492;&#21106;&#35010;&#12290;&#19982;&#24403;&#26102;&#39118;&#22836;&#27491;&#30427;&#30340; Cursor &#30456;&#27604;&#65292;&#23427;&#26356;&#20687;&#26159;&#20004;&#20010;&#26102;&#20195;&#30340;&#20135;&#29289;&#12290;&#38543;&#30528; Claude Code &#31561; AI CLI &#24037;&#20855;&#36880;&#28176;&#25104;&#29087;&#65292;Xcode &#26356;&#26174;&#24471;&#27493;&#20240;&#36831;&#32531;&#65292;&#29978;&#33267;&#35753;&#19981;&#23569;&#24320;&#21457;&#32773;&#24320;&#22987;&#24576;&#30097;&#65306;&#22312; AI &#26102;&#20195;&#65292;&#23427;&#26159;&#21542;&#36824;&#33021;&#32988;&#20219;&#8220;&#20027;&#21147; IDE&#8221;&#30340;&#35282;&#33394;&#12290;</p><p>26.3 &#29256;&#26412;&#30340;&#21040;&#26469;&#65292;&#20960;&#20046;&#27809;&#26377;&#20219;&#20309;&#39044;&#28909;&#65292;&#21364;&#29992;&#23454;&#38469;&#34892;&#21160;&#22238;&#24212;&#20102;&#36825;&#20123;&#36136;&#30097;&#12290;&#36890;&#36807;&#38598;&#25104; Claude Code / Codex&#65292;&#33529;&#26524;&#32473;&#20986;&#30340;&#31572;&#26696;&#24456;&#30452;&#25509;&#65306;&#21482;&#35201;&#31574;&#30053;&#24471;&#24403;&#65292;Xcode &#20381;&#28982;&#26159;&#33529;&#26524;&#29983;&#24577;&#20013;&#26497;&#20855;&#28508;&#21147;&#30340;&#24320;&#21457;&#29615;&#22659;&#12290;&#36825;&#19968;&#27425;&#65292;Xcode &#24182;&#27809;&#26377;&#31616;&#21333;&#22320;&#22622;&#36827;&#19968;&#20010; CLI &#24037;&#20855;&#38754;&#26495;&#65292;&#32780;&#26159;&#24341;&#20837;&#20102;&#19968;&#22871;&#21407;&#29983;&#30340; Xcode Tools&#65288;MCP&#65289;&#65292;&#24182;&#37197;&#21512; Swift 6&#12289;SwiftUI&#12289;SwiftData &#31561;&#23448;&#26041;&#25216;&#26415;&#25991;&#26723;&#65292;&#24418;&#25104;&#20102;&#39640;&#24230;&#19968;&#33268;&#12289;&#36148;&#21512;&#26368;&#26032;&#23454;&#36341;&#30340;&#25972;&#20307;&#20307;&#39564;&#12290;&#21363;&#20415;&#23545;&#20110;&#24050;&#32463;&#29087;&#32451;&#20351;&#29992; CLI + XcodeBuildMCP + &#21508;&#31867; Skills &#30340;&#24320;&#21457;&#32773;&#32780;&#35328;&#65292;&#36825;&#22871;&#21407;&#29983;&#26041;&#26696;&#20381;&#28982;&#20855;&#22791;&#24456;&#24378;&#30340;&#31454;&#20105;&#21147;&#8212;&#8212;&#23588;&#20854;&#26159;&#20960;&#20046;&#20026;&#38646;&#30340;&#37197;&#32622;&#25104;&#26412;&#65292;&#36825;&#23545;&#32477;&#22823;&#22810;&#25968;&#24320;&#21457;&#32773;&#26469;&#35828;&#24847;&#20041;&#37325;&#22823;&#12290;</p><p>&#26356;&#20540;&#24471;&#27880;&#24847;&#30340;&#26159;&#65292;&#36825;&#27425;&#25552;&#20379;&#30340; Xcode Tools &#24182;&#19981;&#21482;&#26159;&#26381;&#21153;&#20110; Xcode &#26412;&#36523;&#65292;&#23427;&#20204;&#21516;&#26679;&#21487;&#20197;&#20316;&#20026;&#26631;&#20934; MCP&#65292;&#20026;&#20854;&#20182; AI &#24037;&#20855;&#25552;&#20379;&#33021;&#21147;&#25903;&#25345;&#12290;&#36825;&#31181;&#24320;&#25918;&#23039;&#24577;&#65292;&#24182;&#19981;&#23436;&#20840;&#31526;&#21512;&#22806;&#30028;&#23545;&#33529;&#26524;&#19968;&#36143;&#39118;&#26684;&#30340;&#21360;&#35937;&#12290;</p><p>&#24403;&#28982;&#65292;&#31449;&#22312;&#20170;&#22825;&#36825;&#20010;&#26102;&#38388;&#28857;&#65292;&#25105;&#20204;&#36824;&#19981;&#33021;&#26029;&#35328; Xcode &#24050;&#32463;&#37325;&#26032;&#22238;&#21040;&#20102;&#31532;&#19968;&#38453;&#33829;&#12290;&#20294;&#21487;&#20197;&#32943;&#23450;&#30340;&#26159;&#65292;26.3 &#37322;&#25918;&#20102;&#19968;&#20010;&#38750;&#24120;&#26126;&#30830;&#30340;&#20449;&#21495;&#65306;&#33529;&#26524;&#24895;&#24847;&#19982;&#20027;&#27969;&#24037;&#20855;&#21644;&#26381;&#21153;&#21327;&#20316;&#65292;&#21435;&#25171;&#36896;&#30495;&#27491;&#31526;&#21512;&#26102;&#20195;&#30340;&#24320;&#21457;&#20307;&#39564;&#12290;&#20063;&#27491;&#22240;&#20026;&#22914;&#27492;&#65292;&#25105;&#23545;&#19979;&#19968;&#38454;&#27573;&#30340; Siri &#25265;&#26377;&#26356;&#39640;&#30340;&#26399;&#24453;&#8212;&#8212;&#24456;&#21487;&#33021;&#22312; iOS 27 &#20013;&#65292;&#33529;&#26524;&#20250;&#22312;&#29616;&#26377; Intent &#20307;&#31995;&#20043;&#22806;&#65292;&#20026;&#31995;&#32479;&#21644;&#24212;&#29992;&#25552;&#20379;&#26356;&#22810;&#26631;&#20934;&#21270;&#25509;&#21475;&#65292;&#35753; AI &#26356;&#33258;&#28982;&#22320;&#34701;&#20837;&#25972;&#20010;&#29983;&#24577;&#12290;</p><p>Xcode + Agent &#21482;&#26159;&#36215;&#28857;&#12290;</p><p>Apple + Agent&#65292;&#25165;&#26159;&#26356;&#20540;&#24471;&#20851;&#27880;&#30340;&#26410;&#26469;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-121/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#21407;&#21019;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/xcode-263-claude/?utm_source=fatbobman%20weekly%20issue%20122&amp;utm_medium=web">Xcode 26.3 + Claude Agent&#65306;&#27169;&#22411;&#26367;&#25442;&#12289;MCP&#12289;Skill &#19982;&#33258;&#36866;&#24212;&#37197;&#32622;</a></strong></h3><p>Xcode 26.3 &#29256;&#26412;&#20013;&#33529;&#26524;&#30452;&#25509;&#25552;&#20379;&#20102;&#23545; Claude Code/Codex &#30340;&#25903;&#25345;&#12290;&#33258;&#27492;&#65292;&#24320;&#21457;&#32773;&#32456;&#20110;&#21487;&#20197;&#22312; Xcode &#20013;&#26041;&#20415;&#30340;&#20351;&#29992;&#21407;&#29983; AI Agent &#20102;&#12290; &#36825;&#20004;&#22825;&#25105;&#38024;&#23545;&#26032;&#29256;&#26412;&#36827;&#34892;&#20102;&#19968;&#31995;&#21015;&#23581;&#35797;&#65292;&#21253;&#25324;&#22914;&#20309;&#20351;&#29992;&#26368;&#26032;&#27169;&#22411;&#12289;&#37197;&#32622; MCPs/Skill/Command&#12289;&#20197;&#21450;&#32534;&#20889;&#33258;&#36866;&#24212;&#30340; <code>CLAUDE.md</code>&#12290;&#26412;&#25991;&#20197; Claude Code &#20026;&#20363;&#65292;&#20998;&#20139;&#19968;&#20123;&#25991;&#26723;&#20043;&#22806;&#30340;&#25216;&#24039;&#12290;</p><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/screensage-from-pixel-to-meta/?utm_source=fatbobman%20weekly%20issue%20122&amp;utm_medium=web">macOS &#24405;&#23631;&#36719;&#20214;&#24320;&#21457;&#23454;&#24405;&#65306;&#20174;&#20687;&#32032;&#25235;&#21462;&#21040;&#20803;&#25968;&#25454;&#37325;&#29616;</a></strong></h3><p>&#35270;&#39057;&#27491;&#22312;&#21462;&#20195;&#25991;&#23383;&#25104;&#20026;&#26356;&#21463;&#27426;&#36814;&#30340;&#34920;&#36798;&#26041;&#24335;&#65292;&#32780;&#22909;&#24037;&#20855;&#26159;&#21019;&#20316;&#30340;&#21152;&#36895;&#22120;&#12290;macOS &#24405;&#23631;&#36719;&#20214; <a href="https://screensage.pro/zh">ScreenSage Pro</a> &#30340;&#24320;&#21457;&#32773; <a href="https://x.com/s1ntone">Sintone</a> &#28145;&#24230;&#22797;&#30424;&#20102;&#22914;&#20309;&#22522;&#20110; ScreenCaptureKit &#21644; Metal &#23454;&#29616;&#8220;&#24405;&#23436;&#21363;&#21098;&#23436;&#8221;&#12290;&#20174;&#35299;&#20915; SCK -3821 &#35809;&#24322;&#25253;&#38169;&#65292;&#21040;&#30001; ObservableObject &#36801;&#31227;&#33267; @Observable &#20248;&#21270;&#26102;&#38388;&#32447;&#24615;&#33021;&#65292;&#26412;&#25991;&#27627;&#26080;&#20445;&#30041;&#22320;&#20998;&#20139;&#20102;&#20174;&#20687;&#32032;&#25235;&#21462;&#21040;&#39640;&#24615;&#33021;&#21512;&#25104;&#30340;&#20840;&#36807;&#31243;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-05">&#21738;&#31181;&#26041;&#24335;&#21028;&#26029;&#23383;&#31526;&#20018;&#26159;&#21542;&#22312;&#30333;&#21517;&#21333;&#37324;&#26368;&#24555;&#65306;Set&#12289;Array&#12289;Enum&#12289;Dictionary &#36824;&#26159; switch?</a></strong></h3><p>&#22312; Swift &#37324;&#65292;&#21028;&#26029;&#19968;&#20010;&#23383;&#31526;&#20018;&#26159;&#21542;&#23646;&#20110;&#26576;&#20010;&#38190;&#38598;&#21512;&#65292;&#21487;&#20197;&#20889;&#25104; <code>Set.contains</code>&#12289;<code>Array.contains</code>&#12289;RawRepresentable enum &#30340; <code>init?(rawValue:)</code>&#12289;<code>switch</code> &#22810;&#20998;&#25903;&#65292;&#29978;&#33267;&#29992; <code>Dictionary</code> &#26469;&#20570;&#26144;&#23556;&#12290;&#30475;&#36215;&#26469;&#24046;&#21035;&#19981;&#22823;&#65292;&#20294;&#30495;&#35201;&#25918;&#36827;&#24615;&#33021;&#25935;&#24863;&#36335;&#24452;&#65292;&#32467;&#26524;&#21487;&#33021;&#24182;&#19981;&#23436;&#20840;&#31526;&#21512;&#30452;&#35273;&#12290;<a href="https://mastodon.social/@helge">Helge He&#223;</a> &#20570;&#20102;&#19968;&#27425;&#31616;&#21333;&#30340;&#22522;&#20934;&#27979;&#35797;&#65306;<code>Set.contains</code> &#27627;&#26080;&#24748;&#24565;&#22320;&#39046;&#20808;&#65292;&#20854;&#27425;&#26159; <code>enum(rawValue:)</code>&#21644; <code>Dictionary</code>&#65288;&#20004;&#32773;&#38750;&#24120;&#25509;&#36817;&#65289;&#65307;&#32780;&#24456;&#22810;&#20154;&#19979;&#24847;&#35782;&#20250;&#39640;&#20272;&#30340; <code>switch</code>&#65292;&#21453;&#32780;&#25490;&#22312; <code>enum</code> &#20043;&#21518;&#65292;<code>Array.contains</code> &#21017;&#22443;&#24213;&#25910;&#22330;&#12290;&#20316;&#20026;&#19968;&#20010;&#23567;&#23454;&#39564;&#65292;&#36825;&#20010;&#32467;&#26524;&#25110;&#35768;&#27491;&#22909;&#21487;&#20197;&#25343;&#26469;&#26657;&#20934;&#19968;&#19979;&#25105;&#20204;&#23545; Swift &#24615;&#33021;&#30340;&#30452;&#35273;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-01">&#20174;&#19968;&#27425;&#24615;&#20184;&#36153;&#21040; Freemium (Migrating an iOS app from Paid up Front to Freemium)</a></strong></h3><p>&#20184;&#36153;&#19979;&#36733;&#21644;&#20813;&#36153; + &#24212;&#29992;&#20869;&#36141;&#20080;&#26159;&#20004;&#31181;&#25130;&#28982;&#19981;&#21516;&#30340;&#21830;&#19994;&#27169;&#24335;&#65292;&#38543;&#30528;&#24212;&#29992;&#21457;&#23637;&#65292;&#24320;&#21457;&#32773;&#21487;&#33021;&#38656;&#35201;&#22312;&#20004;&#32773;&#20043;&#38388;&#36716;&#25442;&#12290;<a href="https://x.com/donnywals">Donny Wals</a> &#22312;&#26412;&#25991;&#20013;&#20998;&#20139;&#20102;&#20182;&#23558; Practical Core Data &#24212;&#29992;&#20174; $4.99 &#20184;&#36153;&#19979;&#36733;&#36716;&#20026; freemium &#30340;&#23436;&#25972;&#32463;&#21382;&#12290;&#25991;&#31456;&#19981;&#20165;&#28085;&#30422;&#20102; StoreKit 2 &#30340;&#25216;&#26415;&#23454;&#29616;&#32454;&#33410;&#65288;&#36141;&#20080;&#27969;&#31243;&#12289;&#29366;&#24577;&#31649;&#29702;&#12289;&#23478;&#24237;&#20849;&#20139;&#65289;&#65292;&#26356;&#26377;&#20215;&#20540;&#30340;&#26159;&#20182;&#23545;&#21830;&#19994;&#20915;&#31574;&#30340;&#28145;&#20837;&#24605;&#32771;&#65306;&#20184;&#36153;&#38376;&#27099;&#34429;&#28982;&#33021;&#31579;&#36873;&#20986;&#35748;&#30495;&#30340;&#29992;&#25143;&#65292;&#20294;&#20063;&#38459;&#25377;&#20102;&#22823;&#37327;&#28508;&#22312;&#29992;&#25143;&#20307;&#39564;&#20135;&#21697;&#20215;&#20540;&#30340;&#26426;&#20250;&#12290;&#23545;&#20110;&#25945;&#32946;&#31867;&#25110;&#24037;&#20855;&#31867;&#29420;&#31435;&#24212;&#29992;&#65292;freemium &#21487;&#33021;&#26159;&#29992;&#25143;&#22686;&#38271;&#21644;&#25910;&#20837;&#20043;&#38388;&#26356;&#22909;&#30340;&#24179;&#34913;&#28857;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-02">iOS &#24212;&#29992;&#20013;&#30340;&#25353;&#38656;&#36164;&#28304; (On-demand resources in iOS app)</a></strong></h3><p>&#24212;&#29992;&#20307;&#31215;&#19968;&#30452;&#26159;&#24320;&#21457;&#32773;&#38656;&#35201;&#20851;&#27880;&#30340;&#38382;&#39064;&#65292;&#23588;&#20854;&#26159;&#22312;&#24212;&#29992;&#21253;&#21547;&#22823;&#37327;&#22270;&#29255;&#12289;&#38899;&#39057;&#25110;&#20854;&#20182;&#36164;&#28304;&#26102;&#12290;&#23613;&#31649;&#33529;&#26524;&#24456;&#26089;&#23601;&#22312; iOS &#20013;&#25552;&#20379;&#20102; On-Demand Resources&#65288;ODR&#65289;&#26469;&#24212;&#23545;&#36825;&#19968;&#25361;&#25112;&#65292;&#20294;&#36825;&#19968;&#21151;&#33021;&#30340;&#23384;&#22312;&#24863;&#24182;&#19981;&#24378;&#65292;&#24120;&#34987;&#24320;&#21457;&#32773;&#24573;&#30053;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://twitter.com/mecid">Majid Jabrayilov</a> &#31995;&#32479;&#24615;&#22320;&#22238;&#39038;&#20102; ODR &#30340;&#24037;&#20316;&#26426;&#21046;&#19982;&#20351;&#29992;&#26041;&#24335;&#65292;&#21253;&#25324;&#36164;&#28304;&#20998;&#32452;&#12289;&#26631;&#31614;&#31649;&#29702;&#12289;&#19979;&#36733;&#29983;&#21629;&#21608;&#26399;&#65292;&#20197;&#21450;&#19982;&#31995;&#32479;&#32531;&#23384;&#31574;&#30053;&#20043;&#38388;&#30340;&#21327;&#20316;&#20851;&#31995;&#12290;</p><p>&#34429;&#28982;&#33529;&#26524;&#22312;&#25512;&#24191; Background Assets &#20316;&#20026;&#26356;&#29616;&#20195;&#30340;&#26041;&#26696;&#65292;&#20294; ODR &#22312;&#38656;&#35201;&#21363;&#26102;&#21709;&#24212;&#30340;&#25353;&#38656;&#19979;&#36733;&#12289;&#32454;&#31890;&#24230;&#36164;&#28304;&#25511;&#21046;&#31561;&#22330;&#26223;&#19979;&#20173;&#26377;&#20854;&#29420;&#29305;&#20215;&#20540;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-03">Observation &#22235;&#20010;&#24120;&#35265;&#38519;&#38449; (Objectively Better, Observably Trickier)</a></strong></h3><p>&#22312;&#20840;&#38754;&#25317;&#25265; Observation &#26694;&#26550;&#26102;&#65292;&#24320;&#21457;&#32773;&#38656;&#35201;&#35686;&#24789;&#20854;&#24037;&#20316;&#26426;&#21046;&#19982; Combine &#30340; <code>@Published</code> &#24182;&#19981;&#30456;&#21516;&#65292;&#31616;&#21333;&#26367;&#25442;&#24448;&#24448;&#20250;&#24341;&#20837;&#38544;&#34109;&#30340;&#38382;&#39064;&#12290;<a href="https://x.com/dbolella">Danny Bolella</a> &#24635;&#32467;&#20102;&#36801;&#31227;&#36807;&#31243;&#20013;&#22235;&#20010;&#24120;&#35265;&#38519;&#38449;&#65306;<code>@State</code> &#25345;&#26377;&#24341;&#29992;&#31867;&#22411;&#26102;&#30340;&#38750;&#24816;&#24615;&#21021;&#22987;&#21270;&#12289;&#23884;&#22871; <code>@Observable</code> &#23545;&#35937;&#23548;&#33268;&#30340;&#26356;&#26032;&#20002;&#22833;&#12289;&#25968;&#32452;&#20803;&#32032;&#32465;&#23450;&#26041;&#24335;&#30340;&#21464;&#21270;&#65292;&#20197;&#21450;&#19982;&#20854;&#20182;&#23646;&#24615;&#21253;&#35013;&#22120;&#20135;&#29983;&#30340;&#20914;&#31361;&#12290;&#25991;&#31456;&#36890;&#36807;&#28165;&#26224;&#30340;&#20195;&#30721;&#31034;&#20363;&#36880;&#19968;&#32473;&#20986;&#35299;&#20915;&#26041;&#26696;&#65292;&#24182;&#21453;&#22797;&#24378;&#35843;&#19968;&#20010;&#26680;&#24515;&#21407;&#21017;&#65306;&#21482;&#26377;&#35270;&#22270;&#24403;&#21069;&#27491;&#22312;&#35775;&#38382;&#65288;&#35843;&#29992; getter&#65289;&#30340;&#23646;&#24615;&#21457;&#29983;&#21464;&#21270;&#26102;&#65292;&#25165;&#20250;&#35302;&#21457;&#26356;&#26032;&#12290;&#29702;&#35299;&#24182;&#39034;&#24212;&#36825;&#31181;&#8220;&#24816;&#24615;&#35266;&#23519;&#8221;&#30340;&#24605;&#32500;&#26041;&#24335;&#65292;&#26159;&#27491;&#30830;&#20351;&#29992; Observation &#26694;&#26550;&#30340;&#20851;&#38190;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-04">&#22312; macOS &#24212;&#29992;&#20013;&#23454;&#29616; Open Recent &#33756;&#21333; (Add an Open Recent Menu to a SwiftUI app)</a></strong></h3><p>&#8220;Open Recent&#8221; &#26159; macOS &#24212;&#29992;&#30340;&#26631;&#20934;&#21151;&#33021;&#65292;&#20294;&#23545;&#20110; SwiftUI &#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#27491;&#30830;&#23454;&#29616;&#36825;&#20010;&#21151;&#33021;&#24182;&#19981;&#30452;&#35266;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://mastodon.world/@swiftdevjournal">Mark Szymczyk</a> &#36890;&#36807;&#19968;&#20010;&#31616;&#27905;&#30340;&#31034;&#20363;&#65292;&#23637;&#31034;&#20102;&#22914;&#20309;&#21033;&#29992; <code>NSDocumentController</code> &#20026;&#24212;&#29992;&#25509;&#20837;&#31995;&#32479;&#32423;&#30340;&#26368;&#36817;&#25991;&#20214;&#31649;&#29702;&#33021;&#21147;&#65306;&#33258;&#21160;&#32500;&#25252;&#21015;&#34920;&#12289;&#26356;&#26032;&#33756;&#21333;&#65292;&#20197;&#21450;&#19982;&#25991;&#26723;&#29983;&#21629;&#21608;&#26399;&#30340;&#26080;&#32541;&#21327;&#20316;&#12290;&#23545;&#20110;&#25991;&#26723;&#22411;&#25110;&#24037;&#20855;&#31867;&#24212;&#29992;&#65292;&#36825;&#26159;&#19968;&#20010;&#20302;&#25104;&#26412;&#12289;&#21364;&#33021;&#26126;&#26174;&#25552;&#21319;&#8220;&#21407;&#29983;&#24863;&#8221;&#30340;&#32454;&#33410;&#20248;&#21270;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0122-06">Radioform&#65306;&#19968;&#20010;&#21407;&#29983;&#12289;&#24320;&#28304;&#30340; macOS &#38899;&#39057;&#22343;&#34913;&#22120;</a></strong></h3><p>macOS &#19968;&#30452;&#32570;&#23569;&#31995;&#32479;&#32423;&#30340;&#38899;&#39057;&#22343;&#34913;&#22120;&#65292;&#30001; <a href="https://www.linkedin.com/in/matthew-porteous-23847a2b2/">Matthew Porteous</a> &#24320;&#21457;&#30340; Radioform &#22635;&#34917;&#20102;&#36825;&#20010;&#31354;&#30333;&#12290;&#35813;&#39033;&#30446;&#37319;&#29992; SwiftUI &#33756;&#21333;&#26639; App + Swift Host + CoreAudio HAL Driver + C++ DSP &#30340;&#20998;&#23618;&#26550;&#26500;&#65292;&#25226; UI &#19982;&#23454;&#26102;&#38899;&#39057;&#22788;&#29702;&#24443;&#24213;&#35299;&#32806;&#12290;DSP &#37096;&#20998;&#23454;&#29616;&#20102; 10 &#27573;&#21442;&#25968; EQ&#12289;&#21442;&#25968;&#24179;&#28369;&#12289;&#38480;&#24133;&#19982;&#23454;&#26102;&#23433;&#20840;&#25511;&#21046;&#65307;&#24037;&#31243;&#19978;&#20063;&#26377;&#23436;&#25972; CI&#12289;&#31614;&#21517;&#20844;&#35777;&#19982; DMG &#21457;&#24067;&#27969;&#31243;&#12290;&#19981;&#26159;&#8220;&#33021;&#36305;&#23601;&#34892;&#8221;&#30340; Demo&#65292;&#32780;&#26159;&#25509;&#36817;&#21487;&#38271;&#26399;&#32500;&#25252;&#30340;&#29983;&#20135;&#32423;&#38899;&#39057;&#24037;&#31243;&#26679;&#26495;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0122-07">CircuitPro&#65306;macOS &#21407;&#29983;&#30340; PCB &#35774;&#35745;&#24037;&#20855;</a></strong></h3><p>&#36825;&#26159;&#19968;&#20010; macOS &#21407;&#29983;&#24212;&#29992;&#36739;&#23569;&#28041;&#36275;&#30340;&#39046;&#22495;&#65306;PCB &#35774;&#35745;&#12290;CircuitPro &#26159;&#19968;&#27454;&#38754;&#21521; macOS &#30340; PCB EDA &#24037;&#20855;&#65292;&#30446;&#26631;&#26159;&#25226;&#21407;&#29702;&#22270;&#12289;&#24067;&#23616;&#19982;&#20803;&#20214;&#24211;&#27969;&#31243;&#20570;&#25104;&#26356;&#31526;&#21512; Apple &#24179;&#21488;&#20064;&#24815;&#30340;&#20307;&#39564;&#12290;&#65288;&#39033;&#30446;&#20173;&#22788;&#20110;&#26089;&#26399;&#24320;&#21457;&#38454;&#27573;&#65289;</p><p>&#39033;&#30446;&#37324;&#26368;&#21560;&#24341;&#25105;&#30340;&#26159;&#33258;&#30740;&#30340; CanvasKit&#12290;&#23427;&#26356;&#20687;&#19968;&#20010;&#38754;&#21521; EDA &#22330;&#26223;&#30340; 2D &#20132;&#20114;&#24341;&#25806;&#65292;&#32780;&#19981;&#21482;&#26159;&#26222;&#36890;&#30011;&#24067;&#32452;&#20214;&#65306;&#19978;&#23618;&#26159;&#22768;&#26126;&#24335; <code>CanvasView</code>&#65292;&#20013;&#23618;&#26159;&#29366;&#24577;&#20013;&#26530; <code>CanvasController</code>&#65292;&#24213;&#23618;&#26159;&#36755;&#20837;&#36335;&#30001;&#12289;&#28210;&#26579;&#26641;&#19982;&#24037;&#20855;&#31995;&#32479;&#12290;&#26356;&#20851;&#38190;&#30340;&#26159;&#65292;&#21560;&#38468;&#12289;&#36755;&#20837;&#22788;&#29702;&#12289;&#36830;&#32447;&#24341;&#25806;&#37117;&#34987;&#20570;&#25104;&#20102;&#21327;&#35758;&#21270;&#25554;&#25300;&#28857;&#65292;&#35753;&#21407;&#29702;&#22270;&#21644;&#24067;&#23616;&#20849;&#20139;&#21516;&#19968;&#22522;&#30784;&#35774;&#26045;&#65292;&#21516;&#26102;&#20445;&#30041;&#21508;&#33258;&#30340;&#36335;&#30001;&#35268;&#21017;&#12290;</p><p>&#21363;&#20415;&#20320;&#23545; PCB &#35774;&#35745;&#26412;&#36523;&#19981;&#24863;&#20852;&#36259;&#65292;CircuitPro &#20063;&#24456;&#20540;&#24471;&#20851;&#27880;&#65292;&#23588;&#20854;&#26159;&#23427;&#22312; SwiftUI + AppKit &#34701;&#21512;&#26550;&#26500;&#19978;&#30340;&#24037;&#31243;&#23454;&#36341;&#12290;</p><h2><strong>&#27714;&#36132;</strong></h2><h3><strong><a href="mailto:xx2bab@gmail.com">&#20102;&#35299;&#20108;&#27425;&#20803;&#30340; iOS &#24037;&#31243;&#24072;</a></strong></h3><p>&#26412;&#20844;&#21496;&#26159;&#20108;&#27425;&#20803;&#25991;&#29983;&#22270;&#22836;&#37096;&#20225;&#19994;&#65288;&#24635;&#37096;&#26032;&#21152;&#22369;&#65289;&#65292;&#25307;&#32856;&#23703;&#20301;&#20026;&#22823;&#38470;&#20840;&#32844; remote&#12290;&#27714;&#32844;&#32773;&#38656;&#35201;&#20102;&#35299;&#20108;&#27425;&#20803;&#25991;&#21270;&#65292;&#25026;&#24471;&#20108;&#27425;&#20803;&#29992;&#35821;&#65288;&#40657;&#35805;&#65289;&#12290;</p><h4><strong>&#23703;&#20301;&#32844;&#36131; (Responsibilities):</strong></h4><ul><li><p>&#25105;&#20204;&#27491;&#22312;&#23547;&#25214;&#19968;&#20301;&#32463;&#39564;&#20016;&#23500;&#30340; iOS &#24037;&#31243;&#24072;&#65288;&#20013;&#39640;&#32423;&#65289;&#65292;&#36127;&#36131;&#20027;&#23548;&#25105;&#20204; iOS &#24212;&#29992;&#30340;&#24320;&#21457;&#19982;&#20248;&#21270;&#24037;&#20316;&#12290;</p></li><li><p>&#29702;&#24819;&#30340;&#20505;&#36873;&#20154;&#24212;&#20855;&#22791;&#28145;&#21402;&#30340; Swift &#25216;&#26415;&#21151;&#24213;&#65292;&#20986;&#33394;&#30340;&#27979;&#35797;&#19982;&#22242;&#38431;&#21327;&#20316;&#33021;&#21147;&#65292;&#24182;&#25317;&#26377;&#29616;&#20195; iOS &#26550;&#26500;&#21450;&#24037;&#20855;&#38142;&#30340;&#23454;&#25112;&#32463;&#39564;&#12290;</p></li></ul><h4><strong>&#20219;&#32844;&#35201;&#27714; (Requirements):</strong></h4><ul><li><p><strong>3 &#24180;&#20197;&#19978; iOS &#24320;&#21457;&#32463;&#39564;</strong>&#65292;&#20027;&#35201;&#20351;&#29992; Swift&#65292;&#21516;&#26102;&#20855;&#22791;&#19968;&#23450;&#30340; Objective-C &#20195;&#30721;&#32500;&#25252;&#33021;&#21147;&#12290;</p></li><li><p><strong>&#33267;&#23569; 1 &#24180;&#30340; SwiftUI &#21644; SPM (Swift Package Manager) &#23454;&#25112;&#32463;&#39564;</strong>&#65292;&#29087;&#24713;&#20854;&#29983;&#24577;&#31995;&#32479;&#21450;&#26368;&#20339;&#23454;&#36341;&#12290;</p></li><li><p><strong>&#29087;&#24713; iOS 15+ &#26032;&#29305;&#24615;</strong>&#65292;&#33021;&#22815;&#38024;&#23545;&#19981;&#21516;&#30340; iOS &#29256;&#26412;&#21644;&#35774;&#22791;&#23631;&#24149;&#23610;&#23544;&#36827;&#34892;&#36866;&#37197;&#21450;&#24615;&#33021;&#20248;&#21270;&#12290;</p></li><li><p><strong>&#25484;&#25569;&#21333;&#20803;&#27979;&#35797;&#21644; UI &#33258;&#21160;&#21270;&#27979;&#35797;</strong> (XCTest, XCUITest)&#65292;&#26377;&#33021;&#21147;&#32534;&#20889;&#21487;&#32500;&#25252;&#30340;&#20195;&#30721;&#65292;&#20197;&#30830;&#20445;&#39033;&#30446;&#30340;&#31283;&#23450;&#24615;&#21644;&#21487;&#25193;&#23637;&#24615;&#12290;</p></li><li><p><strong>&#31934;&#36890; Git &#24037;&#20316;&#27969;</strong>&#65288;Git Flow, &#20027;&#24178;&#24320;&#21457;/Trunk-Based Development&#65289;&#65292;&#24182;&#20855;&#22791;&#22522;&#26412;&#30340;&#20195;&#30721;&#23457;&#26597; (Code Review) &#25216;&#33021;&#12290;</p></li><li><p><strong>&#29702;&#35299;&#22522;&#30784;&#30340; iOS &#24212;&#29992;&#27169;&#22359;&#21270;&#35774;&#35745;&#12289;&#22810;&#31181;&#21333;&#39029;&#38754;&#26550;&#26500;&#27169;&#24335;</strong>&#20197;&#21450;&#24615;&#33021;&#20248;&#21270;&#26041;&#27861;&#65292;&#24182;&#20855;&#22791;&#22312;&#39033;&#30446;&#20013;&#33853;&#22320;&#30340;&#33021;&#21147;&#12290;</p></li></ul><h4><strong>&#21152;&#20998;&#39033;/&#20248;&#20808;&#32771;&#34385; (We will give priority to who):</strong></h4><ul><li><p><strong>&#25317;&#26377;&#36328;&#24179;&#21488;&#24320;&#21457;&#32463;&#39564;</strong>&#65288;&#28385;&#36275;&#20197;&#19979;&#20219;&#24847;&#19968;&#39033;&#21363;&#21487;&#65289;&#65306;</p><ul><li><p>6 &#20010;&#26376;&#20197;&#19978;&#30340;&#20219;&#24847;&#21069;&#31471;&#25216;&#26415;&#26632;&#32463;&#39564; (TypeScript/JavaScript, React, React Native)&#12290;</p></li><li><p>6 &#20010;&#26376;&#20197;&#19978;&#20351;&#29992; Kotlin &#21450;&#30456;&#20851;&#26694;&#26550;&#30340; Android &#24320;&#21457;&#32463;&#39564;&#12290;</p></li><li><p>6 &#20010;&#26376;&#20197;&#19978;&#30340;&#20219;&#24847;&#21518;&#31471;&#24320;&#21457;&#26694;&#26550;&#32463;&#39564;&#12290;</p></li></ul></li><li><p><strong>&#25317;&#26377;&#33267;&#23569; 6 &#20010;&#26376;&#30340; iOS &#22522;&#30784;&#35774;&#26045;&#24037;&#20855;&#25110;&#26694;&#26550;&#25645;&#24314;&#32463;&#39564;</strong>&#65292;&#21253;&#25324;&#20195;&#30721;&#36136;&#37327;&#25552;&#21319;&#65288;Linting, &#38745;&#24577;&#20998;&#26512;, CI/CD&#65289;&#12289;&#25928;&#29575;&#20248;&#21270;&#65288;&#27169;&#22359;&#21270;&#65292;Gradle &#32452;&#20214;&#21270;*&#65289;&#12289;&#20197;&#21450;&#24615;&#33021;&#35843;&#20248;&#65288;&#21551;&#21160;&#36895;&#24230;&#12289;&#24103;&#29575;&#12289;&#31163;&#32447;&#27169;&#24335;&#12289;&#22810;&#32447;&#31243;&#65289;&#12290;</p></li><li><p><strong>&#25317;&#26377; 1 &#24180;&#20197;&#19978; SDK &#24320;&#21457;&#32463;&#39564;</strong>&#65292;&#21253;&#25324;&#36890;&#29992;&#24211;&#24320;&#21457;&#65292;&#22914;&#22270;&#29255;&#21152;&#36733;&#24211; (SDWebImage, Kingfisher)&#12289;&#23500;&#25991;&#26412;&#32534;&#36753;&#22120;&#12289;&#32593;&#32476;&#23618;&#25110;&#25345;&#20037;&#21270;&#23618; (SQLite, Realm, Core Data)&#12290;</p></li><li><p><strong>&#20855;&#22791; UI/UX &#30456;&#20851;&#32463;&#39564;</strong>&#65306;</p><ul><li><p>&#29087;&#24713; Apple &#20154;&#26426;&#20132;&#20114;&#25351;&#21335; (HIG)&#65292;&#33021;&#22815;&#22312;&#29702;&#35299;&#36328;&#24179;&#21488;&#35774;&#35745;&#24046;&#24322;&#30340;&#21516;&#26102;&#65292;&#23454;&#29616;&#31526;&#21512; Apple &#35774;&#35745;&#26631;&#20934;&#30340; UI&#12290;</p></li><li><p>&#25317;&#26377;&#25166;&#23454;&#30340;&#21160;&#30011;&#21644;&#20132;&#20114;&#21160;&#25928;&#24320;&#21457;&#32463;&#39564;&#65292;&#29087;&#24713; Core Animation, UIKit Dynamics &#31561;&#12290;</p></li><li><p>&#26377;<strong>&#28145;&#33394;&#27169;&#24335; (Dark Mode)</strong> &#21450;&#20027;&#39064;&#20999;&#25442;&#21151;&#33021;&#30340;&#24320;&#21457;&#32463;&#39564;&#12290;</p></li></ul></li><li><p><strong>&#20855;&#22791;&#26497;&#24378;&#30340;&#23457;&#32654;&#24863;&#30693;&#21147;</strong>&#65292;&#25317;&#26377;&#32472;&#30011;&#12289;&#25668;&#24433;&#25110;&#35774;&#35745;&#30456;&#20851;&#30340;&#25216;&#33021;&#25110;&#29233;&#22909;&#65288;&#38468;&#24102;&#20316;&#21697;&#38598;&#32773;&#20248;&#20808;&#65289;&#12290;</p></li><li><p><strong>&#25317;&#26377;&#23436;&#25972;&#30340; App &#29983;&#21629;&#21608;&#26399;&#32463;&#39564;</strong>&#65306;&#26366;&#29420;&#31435;&#24320;&#21457;&#12289;&#21457;&#24067;&#24182;&#32500;&#25252;&#36807;&#25903;&#25345;&#22810;&#22269;/&#22810;&#35821;&#35328;&#30340; iOS &#24212;&#29992;&#12290;</p></li><li><p><strong>&#31215;&#26497;&#21442;&#19982;&#25216;&#26415;&#31038;&#21306;</strong>&#65292;&#20363;&#22914;&#65306;</p><ul><li><p>&#20855;&#26377;&#20027;&#21160;&#23398;&#20064;&#21644;&#20998;&#20139;&#30340;&#24515;&#24577;&#65292;&#26377;&#36827;&#34892;&#25216;&#26415;&#28436;&#35762;&#30340;&#32463;&#39564;&#12290;</p></li><li><p>&#26377;&#25216;&#26415;&#20889;&#20316;&#32463;&#39564;&#65288;&#21338;&#23458;&#12289;&#25991;&#31456;&#65289;&#12290;</p></li><li><p>&#26377;&#24320;&#28304;&#39033;&#30446;&#36129;&#29486;&#32463;&#21382;&#12290;</p></li></ul></li><li><p><strong>&#26377;&#20351;&#29992; AI &#32534;&#31243;&#24037;&#20855;&#30340;&#32463;&#39564;</strong>&#65292;&#22914; Claude, ChatGPT, GitHub Copilot, Cursor &#25110; Windsurf&#12290;</p></li><li><p><strong>&#20855;&#22791;&#27969;&#21033;&#30340;&#33521;&#35821;&#27807;&#36890;&#33021;&#21147;&#25110;&#25345;&#26377;&#26085;&#35821; N2 &#35777;&#20070;&#12290;</strong></p></li></ul><h4><strong>&#32852;&#31995;&#20154;</strong></h4><p><a href="mailto:xx2bab@gmail.com">xx2bab@gmail.com</a></p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #121]]></title><description><![CDATA[Shifting Light, Unchanging Haystacks]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-121</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-121</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 02 Feb 2026 12:03:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2lY2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2lY2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2lY2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 424w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 848w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 1272w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2lY2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp" width="1456" height="684" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:684,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47796,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/186581582?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2lY2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 424w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 848w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 1272w, https://substackcdn.com/image/fetch/$s_!2lY2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F927028ca-950c-40ea-91ac-181dd002a27a_1915x899.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Shifting Light, Unchanging Haystacks</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-121/">Read on web &#8594;</a></p><p>Two weeks ago, taking the opportunity of attending iOS Conf SG 2026, I visited the National Gallery Singapore and had the pleasure of viewing the special exhibition <em>&#8220;Into the Modern: Impressionism from the Museum of Fine Arts, Boston&#8221;</em>. Although I have seen many excellent exhibitions in the past, this experience resonated with me in a distinct and unexpected way.</p><p>The National Gallery Singapore is formed by merging two historically significant national monuments&#8212;the former Supreme Court and the City Hall. Architects connected these two classical structures with a minimalist metal and glass roof, creating a striking sense of place architecturally: history and modernity intertwined within the same physical space. The ongoing exhibition <em>&#8220;Into the Modern&#8221;</em>, which features over one hundred original works by masters such as Monet, Renoir, Manet, C&#233;zanne, and Degas, elevates this cross-temporal dialogue to the realm of art.</p><p>The exhibition does not simply follow a chronological timeline; instead, it uses &#8220;modernity&#8221; as its core narrative thread, unfolding layer by layer through themes like &#8220;Cities and Change&#8221;, &#8220;Light and Moments,&#8221; and &#8220;Class and Leisure&#8221;. Although the &#8220;modern&#8221; here refers to the late 19th century, the urban renewal of Paris, the evolution of lighting techniques, and the rise of new forms of leisure depicted in the paintings all demonstrate, from multiple dimensions, the rhythm of social progress in that era. In this space where time and geography cross, the exhibition goes far beyond the mere level of &#8220;viewing art.&#8221; For someone like me, who is swept along daily by the torrent of &#8220;new tech&#8221; information on social media, this was a rare moment of tranquility and introspection.</p><p>Returning to reality, in just the past few days, the names of the hottest AI projects have shifted from Clawdbot to Moltbot, and then rapidly evolved into OpenClaw. From a microscopic perspective, we seem to be living in an era of change measured in minutes and seconds. However, if we were to look back at the current AI fever from a longer time scale years from now, we might discover that the world did not undergo the radical, fundamental mutations that we perceive while caught in the current.</p><p>Immersed in this environment, it is inevitable that we feel excitement&#8212;or even anxiety&#8212;over the endless stream of new technologies and tools. Perhaps, beyond these emotions, what we need is a deeper sense of grounding. History repeatedly reminds us that any &#8220;high tech&#8221; has its temporal limitations. Just as Monet repeatedly depicted the same haystack under different times and lighting conditions: the painting techniques may evolve, but the core object remains unchanged. What truly changes is often the way of seeing, the depth of understanding, and the creator&#8217;s own state of mind.</p><p>When facing the &#8220;present and future&#8221;, perhaps we can afford to be less frantic in our pursuit of change, and more composed in our contemplation of the moment.</p><p><a href="https://fatbobman.com/en/weekly/issue-120/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-proxyman">Need to debug HTTPS on your iPhone?</a></strong></h3><p>Try Proxyman! The best-in-class macOS that helps you capture/debug HTTP(s) with a few clicks. Support iOS devices and Simulator.</p><p><a href="https://l.fatbobman.com/sb-proxyman">&#128640; Get Started Now &#8594;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0121-01">DebugReplaceableView and Swift 6.2&#8217;s Multiple Type Erasers</a></strong></h3><p>You may still find Xcode Previews less than ideal, but Apple has been actively optimizing this experience over the past few years with notable progress. Starting with Xcode 16, views are automatically converted to <code>AnyView</code> via <code>@_typeEraser</code> in preview and debug modes to provide richer debugging information. From Xcode 26 onwards, the enhanced <code>@_typeEraser</code>now supports multiple type erasers, converting views to <code>DebugReplaceableView</code> on macOS/iOS 26+ platforms. This enables hot-swapping of views without rebuilding the entire view hierarchy, further improving preview performance. In this article, <a href="https://x.com/KyleSwifter">Kyle Ye</a> dives deep into the compiler source code to analyze the implementation, explaining how the compiler automatically selects the appropriate type eraser based on platform availability.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-02">Tiered Caching in Swift</a></strong></h3><p>When you need to balance performance, memory footprint, and data consistency simultaneously, a single caching strategy often falls short. In this article, <a href="https://linkedin.com/in/kyle-browning-eng-manager">Kyle Browning</a> provides a practical guide to implementing tiered caching in Swift: organizing memory and disk caches into a clear hierarchical structure, combined with flexible cache policies (such as <code>cacheThenFetch</code>, <code>cacheElseFetch</code>, etc.) to enable data to flow smoothly between different access cost tiers.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-03">SwiftUI: Realtime, Multi-User Content Collaboration With CloudFlare +YJS-Swift</a></strong></h3><p>Despite the availability of numerous services and frameworks, implementing real-time collaborative editing remains a significant engineering challenge. In this article, <a href="https://x.com/itsuki68391179">Itsuki</a> demonstrates how to build a low-cost, scalable, multi-user real-time collaborative content editing system in SwiftUI using Cloudflare Durable Objects + WebSocket Hibernation API + YJS-Swift.</p><p>Particularly noteworthy is the author&#8217;s detailed explanation of how to properly maintain text cursor and selection positions when receiving remote content updates in SwiftUI&#8212;this is closely aligned with real-world product development and clearly represents hard-won experience from actual implementation.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-04">Swift Actors: 6 pitfalls that will catch even experienced developers</a></strong></h3><p>Actors are one of the most important&#8212;and most easily misunderstood&#8212;features in Swift&#8217;s concurrency model. Reality, however, is far more complex than it appears. In this article, <a href="https://pl.linkedin.com/in/rafa%C5%82-dubiel-86317013b">Rafa&#322; Dubiel</a> summarizes 6 Actor pitfalls that even experienced developers commonly encounter: state inconsistency caused by reentrancy, the performance cost of Actor hopping, thread-safety vulnerabilities when <code>@MainActor</code> interacts with Objective-C callbacks, the risks of misusing <code>@unchecked Sendable</code>, misconceptions about <code>nonisolated</code>, and the counterintuitive fact that Actors don&#8217;t guarantee execution order.</p><p>Rafa&#322; doesn&#8217;t stop at conceptual warnings&#8212;he explains through concrete scenarios why these issues genuinely exist and why they&#8217;re so easy to overlook.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-05">Designing a Scalable App-Wide Theming System in SwiftUI</a></strong></h3><p>Implementing app-wide theming in SwiftUI may seem like a simple &#8220;style management&#8221; problem, but it easily touches on deeper design decisions involving state propagation, dependency injection, and view refresh boundaries. <a href="https://x.com/SagarUnagar_">Sagar Unagar</a>approaches this from a real-world requirement, demonstrating a comprehensive theming system design based on SwiftUI&#8217;s Environment: using <code>EnvironmentKey</code> to make themes accessible like built-in environment values, and replacing scattered hardcoded values with semantic Design Tokens.</p><p>Sagar&#8217;s focus isn&#8217;t just on &#8220;how to do it,&#8221; but on &#8220;which approach is more maintainable in the long run&#8221;&#8212;this solution doesn&#8217;t depend on any specific library, with its core philosophy being &#8220;semantic + reactive,&#8221; easily extensible to fonts, spacing, corner radius, and other design elements.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-06">Call Once</a></strong></h3><p>&#8220;Ensuring a closure executes only once&#8221; sounds like a basic requirement, but in real systems, it&#8217;s often not as simple as adding a boolean flag. In this article, <a href="https://hachyderm.io/@paulio87">Paul Samuels</a> demonstrates how to encapsulate this behavior using <code>@propertyWrapper</code>, progressively evolving the solution: from a basic version supporting only <code>() -&gt; Void</code>, to introducing generics for return values, and finally leveraging Swift&#8217;s Parameter Packs (<code>each Argument</code>) to support arbitrary function signatures.</p><p>This is a thought-provoking article whose value lies not only in the final <code>CallOnce</code> implementation, but in demonstrating how to progressively combine multiple Swift language features to solve a seemingly simple yet representative engineering problem.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0121-07">SwiftUI-Agent-Skill: Making AI Write More Reliable SwiftUI Code</a></strong></h3><p>If you&#8217;re using AI coding assistants (like Claude Code, Cursor, or Codex), you&#8217;ve likely encountered this problem: AI-generated SwiftUI code uses <strong>deprecated APIs</strong>, or deviates from best practices in state management and view organization&#8212;even when you&#8217;ve repeatedly emphasized these requirements in your base rules.</p><p><strong>SwiftUI-Agent-Skill</strong>, released by <a href="https://x.com/twannl">Antoine van der Lee</a>, is designed to bridge this &#8220;last mile&#8221; gap. It provides AI tools with expert-level SwiftUI guidance covering state management trade-offs, modern API replacements, performance and maintainability checks, and iOS 26+ Liquid Glass usage boundaries&#8212;turning &#8220;the places where SwiftUI code most commonly goes wrong&#8221; into a reusable, executable review workflow.</p><blockquote><p>In addition to this skill, Antoine also provides skills for <a href="https://github.com/AvdLee/Swift-Concurrency-Agent-Skill">Swift Concurrency</a> and <a href="https://github.com/AvdLee/Core-Data-Agent-Skill">Core Data</a>.</p><p>I recommend that developers don&#8217;t just configure these into their AI environment and call it done&#8212;these skill documents themselves are structured summaries of practical experience in specific domains. Reading through them carefully benefits not just your AI, but elevates your own understanding as well.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-08">PierreDiffsSwift: Render Beautiful Code Diff Views in macOS Apps</a></strong></h3><p>PierreDiffsSwift, developed by <a href="https://x.com/jamesrochabrun">James Rochabrun</a>, helps developers render beautiful, syntax-highlighted code diff views in macOS applications.</p><p>The library provides an out-of-the-box solution: built on the <a href="https://www.npmjs.com/package/@pierre/diffs">@pierre/diffs</a> JavaScript library, wrapped into SwiftUI-native views via WKWebView, supporting syntax highlighting for 40+ languages, Split/Unified view modes, inline word-level change highlighting, and automatic dark/light theme switching.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-121?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-121?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#21464;&#24187;&#30340;&#20809;&#24433;&#65292;&#19981;&#21464;&#30340;&#24178;&#33609;&#22534;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-121/">&#32593;&#39029;&#29256;</a></strong></p><p>&#20004;&#21608;&#21069;&#65292;&#20511;&#30528;&#21442;&#21152; iOS Conf SG 2026 &#30340;&#22865;&#26426;&#65292;&#25105;&#36896;&#35775;&#20102;&#26032;&#21152;&#22369;&#22269;&#31435;&#32654;&#26415;&#39302;&#65292;&#24182;&#26377;&#24184;&#21442;&#35266;&#20102;&#12298;&#36208;&#36827;&#29616;&#20195;&#65306;&#27874;&#22763;&#39039;&#32654;&#26415;&#21338;&#29289;&#39302;&#21360;&#35937;&#27966;&#22823;&#24072;&#23637;&#12299;&#12290;&#23613;&#31649;&#27492;&#21069;&#20063;&#30475;&#36807;&#19981;&#23569;&#20248;&#31168;&#30340;&#23637;&#35272;&#65292;&#20294;&#36825;&#27425;&#32463;&#21382;&#20173;&#24102;&#26469;&#20102;&#26576;&#31181;&#19981;&#21516;&#23547;&#24120;&#30340;&#35302;&#21160;&#12290;</p><p>&#26032;&#21152;&#22369;&#22269;&#31435;&#32654;&#26415;&#39302;&#30001;&#20004;&#24231;&#26497;&#20855;&#21382;&#21490;&#20998;&#37327;&#30340;&#22269;&#23478;&#21476;&#36857;&#8212;&#8212;&#21069;&#26368;&#39640;&#27861;&#38498;&#19982;&#21069;&#24066;&#25919;&#21381;&#8212;&#8212;&#21512;&#24182;&#32780;&#25104;&#12290;&#35774;&#35745;&#24072;&#20197;&#26497;&#31616;&#30340;&#37329;&#23646;&#19982;&#29627;&#29827;&#23627;&#39030;&#23558;&#20004;&#24231;&#21476;&#20856;&#24314;&#31569;&#36830;&#25509;&#22312;&#19968;&#36215;&#65292;&#22312;&#24314;&#31569;&#23618;&#38754;&#20415;&#33829;&#36896;&#20986;&#19968;&#31181;&#24378;&#28872;&#30340;&#20020;&#22330;&#24863;&#65306;&#21382;&#21490;&#19982;&#29616;&#20195;&#22312;&#21516;&#19968;&#29289;&#29702;&#31354;&#38388;&#20013;&#24444;&#27492;&#20132;&#32455;&#12290;&#32780;&#27491;&#22312;&#23637;&#20986;&#30340;&#29305;&#23637;&#12298;Into the Modern&#12299;&#65292;&#27719;&#38598;&#20102;&#33707;&#22856;&#12289;&#38647;&#35834;&#38463;&#12289;&#39532;&#22856;&#12289;&#22622;&#23578;&#12289;&#24503;&#21152;&#31561; 25 &#20301;&#22823;&#24072;&#30340;&#19968;&#30334;&#20313;&#24133;&#21407;&#20316;&#65292;&#21017;&#23558;&#36825;&#31181;&#36328;&#36234;&#26102;&#38388;&#30340;&#23545;&#35805;&#36827;&#19968;&#27493;&#25512;&#21521;&#20102;&#33402;&#26415;&#23618;&#38754;&#12290;</p><p>&#23637;&#35272;&#24182;&#26410;&#31616;&#21333;&#20381;&#24490;&#26102;&#38388;&#32447;&#23637;&#24320;&#65292;&#32780;&#26159;&#20197;&#8220;&#29616;&#20195;&#24615;&#8221;&#20026;&#26680;&#24515;&#21465;&#20107;&#32447;&#32034;&#65292;&#36890;&#36807;&#8220;&#22478;&#24066;&#19982;&#21464;&#38761;&#8221;&#8220;&#20809;&#24433;&#19982;&#30636;&#38388;&#8221;&#8220;&#38454;&#32423;&#19982;&#20241;&#38386;&#8221;&#31561;&#20027;&#39064;&#23618;&#23618;&#38138;&#38472;&#12290;&#23613;&#31649;&#36825;&#37324;&#30340;&#8220;&#29616;&#20195;&#8221;&#25351;&#21521;&#30340;&#26159; 19 &#19990;&#32426;&#26411;&#65292;&#20294;&#30011;&#20316;&#20013;&#25152;&#21576;&#29616;&#30340;&#24052;&#40654;&#22478;&#24066;&#25913;&#36896;&#12289;&#20809;&#24433;&#25216;&#27861;&#30340;&#28436;&#21464;&#65292;&#20197;&#21450;&#26032;&#20852;&#20241;&#38386;&#19982;&#23089;&#20048;&#26041;&#24335;&#30340;&#20852;&#36215;&#65292;&#26080;&#19981;&#20174;&#22810;&#20010;&#32500;&#24230;&#23637;&#29616;&#20102;&#37027;&#20010;&#26102;&#20195;&#31038;&#20250;&#21069;&#34892;&#30340;&#33410;&#22863;&#12290;&#22312;&#36825;&#26679;&#19968;&#20010;&#26102;&#31354;&#20132;&#38169;&#30340;&#22330;&#22495;&#20013;&#65292;&#23637;&#35272;&#26089;&#24050;&#36229;&#36234;&#20102;&#21333;&#32431;&#8220;&#35266;&#30475;&#33402;&#26415;&#21697;&#8221;&#30340;&#23618;&#27425;&#12290;&#23545;&#20110;&#27599;&#22825;&#37117;&#34987;&#31038;&#20132;&#23186;&#20307;&#26102;&#38388;&#32447;&#20013;&#28023;&#37327;&#8220;&#26032;&#25216;&#26415;&#8221;&#20449;&#24687;&#35065;&#25375;&#30340;&#25105;&#32780;&#35328;&#65292;&#36825;&#26080;&#30097;&#26159;&#19968;&#27573;&#38590;&#24471;&#30340;&#24179;&#38745;&#19982;&#21453;&#24605;&#26102;&#21051;&#12290;</p><p>&#22238;&#21040;&#29616;&#23454;&#65292;&#20165;&#20165;&#22312;&#36807;&#21435;&#30340;&#20960;&#22825;&#37324;&#65292;&#22823;&#28909; AI &#39033;&#30446;&#30340;&#21517;&#23383;&#23601;&#20174; Clawdbot &#21464;&#25104; Moltbot&#65292;&#21448;&#36805;&#36895;&#28436;&#21270;&#20026; OpenClaw&#12290;&#20174;&#24494;&#35266;&#35270;&#35282;&#30475;&#65292;&#25105;&#20204;&#20223;&#20315;&#27491;&#36523;&#22788;&#19968;&#20010;&#20197;&#20998;&#31186;&#35745;&#37327;&#30340;&#21464;&#38761;&#26102;&#20195;&#65307;&#20294;&#33509;&#22312;&#33509;&#24178;&#24180;&#21518;&#65292;&#20174;&#26356;&#38271;&#30340;&#26102;&#38388;&#23610;&#24230;&#37325;&#26032;&#23457;&#35270;&#24403;&#19979;&#30340; AI &#28909;&#28526;&#65292;&#25110;&#35768;&#20250;&#21457;&#29616;&#65292;&#19990;&#30028;&#24182;&#26410;&#22914;&#27946;&#27969;&#20043;&#20013;&#30340;&#25105;&#20204;&#25152;&#24863;&#30693;&#30340;&#37027;&#26679;&#65292;&#21457;&#29983;&#30528;&#26412;&#36136;&#19978;&#30340;&#31361;&#21464;&#12290;</p><p>&#36523;&#22788;&#20854;&#20013;&#65292;&#25105;&#20204;&#38590;&#20813;&#20250;&#22240;&#23618;&#20986;&#19981;&#31351;&#30340;&#26032;&#25216;&#26415;&#12289;&#26032;&#24037;&#20855;&#32780;&#20852;&#22859;&#65292;&#29978;&#33267;&#28966;&#34385;&#12290;&#25110;&#35768;&#65292;&#22312;&#36825;&#31181;&#24773;&#32490;&#20043;&#22806;&#65292;&#26356;&#38656;&#35201;&#19968;&#31181;&#26356;&#28145;&#23618;&#30340;&#23450;&#21147;&#12290;&#21382;&#21490;&#21453;&#22797;&#25552;&#37266;&#25105;&#20204;&#65292;&#20219;&#20309;&#8220;&#39640;&#25216;&#26415;&#8221;&#37117;&#20855;&#26377;&#20854;&#26102;&#38388;&#23616;&#38480;&#24615;&#12290;&#27491;&#22914;&#33707;&#22856;&#22312;&#19981;&#21516;&#26102;&#38388;&#12289;&#19981;&#21516;&#20809;&#32447;&#19979;&#21453;&#22797;&#25551;&#32472;&#21516;&#19968;&#24231;&#24178;&#33609;&#22534;&#65306;&#32472;&#30011;&#25216;&#27861;&#22312;&#21464;&#21270;&#65292;&#20294;&#26680;&#24515;&#23545;&#35937;&#22987;&#32456;&#26410;&#21464;&#65307;&#30495;&#27491;&#21457;&#29983;&#21464;&#21270;&#30340;&#65292;&#24448;&#24448;&#26159;&#35266;&#30475;&#26041;&#24335;&#12289;&#29702;&#35299;&#23618;&#27425;&#19982;&#21019;&#20316;&#32773;&#33258;&#36523;&#30340;&#24515;&#22659;&#12290;</p><p>&#22312;&#38754;&#23545;&#8220;&#29616;&#22312;&#19982;&#26410;&#26469;&#8221;&#26102;&#65292;&#20063;&#35768;&#25105;&#20204;&#21487;&#20197;&#23569;&#19968;&#20123;&#36861;&#36880;&#21464;&#38761;&#30340;&#24908;&#24352;&#65292;&#22810;&#19968;&#20123;&#20957;&#35270;&#30636;&#38388;&#30340;&#20174;&#23481;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-120/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-proxyman">&#35843;&#35797; iOS &#32593;&#32476;&#35831;&#27714;&#24635;&#26159;&#34987;&#35777;&#20070;&#37197;&#32622;&#38590;&#20303;&#65311;</a></strong></h3><p>Proxyman &#26159;&#19968;&#27454;&#20026; iOS &#24320;&#21457;&#32773;&#25171;&#36896;&#30340;&#29616;&#20195; HTTP &#25235;&#21253;&#24037;&#20855;&#12290;&#25903;&#25345; SSL &#20195;&#29702;&#12289;GraphQL&#12289;WebSocket &#21450;&#24378;&#22823;&#30340;&#33050;&#26412;&#27880;&#20837;&#21151;&#33021;&#12290;&#21578;&#21035;&#31528;&#37325;&#30340;&#20256;&#32479;&#24037;&#20855;&#65292;&#20307;&#39564;&#19987;&#20026; macOS &#20248;&#21270;&#30340;&#26497;&#33268;&#35843;&#35797;&#25928;&#29575;&#12290;</p><p><a href="https://l.fatbobman.com/sb-proxyman">&#128640; &#31435;&#21363;&#35797;&#29992; &#8594;</a></p><div><hr></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0121-01">SwiftUI &#35843;&#35797;&#32972;&#21518;&#30340;&#22810;&#37325;&#31867;&#22411;&#25830;&#38500;&#26426;&#21046; (DebugReplaceableView and Swift 6.2&#8217;s Multiple Type Erasers)</a></strong></h3><p>&#25110;&#35768;&#20320;&#21487;&#33021;&#23545; Xcode &#30340; Preview &#20173;&#19981;&#29978;&#28385;&#24847;&#65292;&#20294;&#20854;&#23454;&#22312;&#36807;&#21435;&#20960;&#24180;&#38388;&#65292;&#33529;&#26524;&#19968;&#30452;&#22312;&#36825;&#26041;&#38754;&#31215;&#26497;&#22320;&#36827;&#34892;&#30528;&#20248;&#21270;&#24037;&#20316;&#65292;&#24182;&#19988;&#21462;&#24471;&#20102;&#19981;&#23569;&#30340;&#36827;&#23637;&#12290;&#27604;&#22914;&#65292;&#20174; Xcode 16 &#24320;&#22987;&#65292;&#20415;&#22312;&#39044;&#35272;&#21644;&#35843;&#35797;&#27169;&#24335;&#19979;&#65292;&#36890;&#36807; <code>@_typeEraser</code> &#33258;&#21160;&#23558;&#35270;&#22270;&#36716;&#25442;&#20026; <code>AnyView</code> &#20197;&#22686;&#21152;&#26356;&#22810;&#30340;&#35843;&#35797;&#20449;&#24687;&#12290;&#32780;&#20174; Xcode 26 &#24320;&#22987;&#65292;&#36890;&#36807;&#22686;&#24378; <code>@_typeEraser</code> &#20351;&#20854;&#25903;&#25345;&#22810;&#37325;&#31867;&#22411;&#25830;&#38500;&#22120;&#65292;&#22312; macOS/iOS 26+ &#24179;&#21488;&#19978;&#23558;&#35270;&#22270;&#36716;&#25442;&#25104; <code>DebugReplaceableView</code>&#65292;&#23454;&#29616;&#35270;&#22270;&#30340;&#28909;&#26367;&#25442;&#32780;&#26080;&#38656;&#37325;&#24314;&#25972;&#20010;&#35270;&#22270;&#23618;&#32423;&#65292;&#36827;&#19968;&#27493;&#25913;&#21892;&#39044;&#35272;&#24615;&#33021;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/KyleSwifter">Kyle Ye</a> &#20174;&#32534;&#35793;&#22120;&#28304;&#30721;&#23618;&#38754;&#28145;&#20837;&#21078;&#26512;&#20102;&#36825;&#19968;&#26426;&#21046;&#30340;&#23454;&#29616;&#21407;&#29702;&#65292;&#35299;&#37322;&#20102;&#32534;&#35793;&#22120;&#22914;&#20309;&#26681;&#25454;&#24179;&#21488;&#21487;&#29992;&#24615;&#33258;&#21160;&#36873;&#25321;&#21512;&#36866;&#30340;&#31867;&#22411;&#25830;&#38500;&#22120;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-02">Swift &#20013;&#30340;&#20998;&#23618;&#32531;&#23384;&#35774;&#35745; (Tiered Caching in Swift)</a></strong></h3><p>&#22312;&#38656;&#35201;&#21516;&#26102;&#20860;&#39038;&#24615;&#33021;&#12289;&#20869;&#23384;&#21344;&#29992;&#19982;&#25968;&#25454;&#19968;&#33268;&#24615;&#30340;&#22330;&#26223;&#20013;&#65292;&#21333;&#19968;&#32531;&#23384;&#31574;&#30053;&#24448;&#24448;&#24456;&#24555;&#23601;&#20250;&#25417;&#35167;&#35265;&#32920;&#12290;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://linkedin.com/in/kyle-browning-eng-manager">Kyle Browning</a> &#20197;&#23454;&#36341;&#35270;&#35282;&#31995;&#32479;&#20171;&#32461;&#20102;&#20998;&#23618;&#32531;&#23384;&#65288;Tiered Caching&#65289;&#22312; Swift &#20013;&#30340;&#23454;&#29616;&#24605;&#36335;&#65306;&#36890;&#36807;&#23558;&#20869;&#23384;&#32531;&#23384;&#19982;&#30913;&#30424;&#32531;&#23384;&#32452;&#32455;&#25104;&#28165;&#26224;&#30340;&#23618;&#32423;&#32467;&#26500;&#65292;&#37197;&#21512;&#28789;&#27963;&#30340;&#32531;&#23384;&#31574;&#30053;&#65288;&#22914; <code>cacheThenFetch</code>&#12289;<code>cacheElseFetch</code> &#31561;&#65289;&#65292;&#35753;&#25968;&#25454;&#22312;&#19981;&#21516;&#35775;&#38382;&#25104;&#26412;&#20043;&#38388;&#26377;&#24207;&#27969;&#21160;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-03">&#22522;&#20110; Cloudflare &#30340; SwiftUI &#23454;&#26102;&#21327;&#20316;&#32534;&#36753;&#23454;&#36341; (SwiftUI: Realtime, Multi-User Content Collaboration With CloudFlare +YJS-Swift)</a></strong></h3><p>&#23613;&#31649;&#24066;&#38754;&#19978;&#24050;&#32463;&#23384;&#22312;&#19981;&#23569;&#29616;&#25104;&#30340;&#26381;&#21153;&#19982;&#26694;&#26550;&#65292;&#23454;&#26102;&#21327;&#20316;&#32534;&#36753;&#22312;&#24037;&#31243;&#23618;&#38754;&#20381;&#28982;&#26159;&#19968;&#36947;&#19981;&#20302;&#30340;&#38376;&#27099;&#12290;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/itsuki68391179">Itsuki</a> &#31995;&#32479;&#24615;&#22320;&#23637;&#31034;&#20102;&#22914;&#20309;&#22312; SwiftUI &#20013;&#65292;&#20511;&#21161; Cloudflare Durable Objects + WebSocket Hibernation API + YJS-Swift&#65292;&#26500;&#24314;&#19968;&#20010;&#20302;&#25104;&#26412;&#12289;&#21487;&#25193;&#23637;&#12289;&#25903;&#25345;&#22810;&#29992;&#25143;&#23454;&#26102;&#21327;&#20316;&#30340;&#20869;&#23481;&#32534;&#36753;&#31995;&#32479;&#12290;</p><p>&#23588;&#20854;&#20540;&#24471;&#19968;&#25552;&#30340;&#26159;&#65292;&#20316;&#32773;&#35814;&#32454;&#20998;&#20139;&#20102;&#22312; SwiftUI &#25509;&#25910;&#36828;&#31243;&#20869;&#23481;&#26356;&#26032;&#26102;&#65292;&#22914;&#20309;&#27491;&#30830;&#32500;&#25252;&#25991;&#26412;&#20809;&#26631;&#19982;&#36873;&#21306;&#20301;&#32622;&#30340;&#22788;&#29702;&#25216;&#24039;&#8212;&#8212;&#36825;&#19968;&#37096;&#20998;&#38750;&#24120;&#36148;&#36817;&#30495;&#23454;&#20135;&#21697;&#24320;&#21457;&#65292;&#26126;&#26174;&#23646;&#20110;&#8220;&#36393;&#36807;&#22353;&#20043;&#21518;&#25165;&#20250;&#20889;&#20986;&#26469;&#8221;&#30340;&#32463;&#39564;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-04">Swift Actor &#30340; 6 &#20010;&#24120;&#35265;&#38519;&#38449; (Swift Actors: 6 pitfalls that will catch even experienced developers)</a></strong></h3><p>Actor &#26159; Swift &#24182;&#21457;&#27169;&#22411;&#20013;&#26368;&#37325;&#35201;&#12289;&#20063;&#26368;&#23481;&#26131;&#34987;&#8220;&#24819;&#24403;&#28982;&#8221;&#20351;&#29992;&#30340;&#35821;&#35328;&#29305;&#24615;&#20043;&#19968;&#65292;&#28982;&#32780;&#29616;&#23454;&#36828;&#27604;&#36825;&#22797;&#26434;&#12290;<a href="https://pl.linkedin.com/in/rafa%C5%82-dubiel-86317013b">Rafa&#322; Dubiel</a> &#22312;&#26412;&#25991;&#20013;&#24635;&#32467;&#20102; 6 &#20010;&#21363;&#20351;&#26159;&#36164;&#28145;&#24320;&#21457;&#32773;&#20063;&#24120;&#36393;&#30340; Actor &#38519;&#38449;&#65306;&#21487;&#37325;&#20837;&#24615;&#23548;&#33268;&#30340;&#29366;&#24577;&#19981;&#19968;&#33268;&#12289;Actor Hopping &#30340;&#24615;&#33021;&#20195;&#20215;&#12289;<code>@MainActor</code> &#19982; Objective-C &#22238;&#35843;&#20132;&#20114;&#26102;&#30340;&#32447;&#31243;&#23433;&#20840;&#28431;&#27934;&#12289;<code>@unchecked Sendable</code> &#30340;&#28389;&#29992;&#39118;&#38505;&#12289;<code>nonisolated</code> &#30340;&#35823;&#35299;&#65292;&#20197;&#21450; Actor &#24182;&#19981;&#20445;&#35777;&#25191;&#34892;&#39034;&#24207;&#36825;&#19968;&#21453;&#30452;&#35273;&#30340;&#20107;&#23454;&#12290;</p><p>Rafa&#322; &#24182;&#26410;&#20572;&#30041;&#22312;&#27010;&#24565;&#23618;&#38754;&#30340;&#25552;&#37266;&#65292;&#32780;&#26159;&#32467;&#21512;&#20855;&#20307;&#22330;&#26223;&#35299;&#37322;&#36825;&#20123;&#38382;&#39064;&#20026;&#20309;&#30495;&#23454;&#23384;&#22312;&#12289;&#21448;&#20026;&#20309;&#23481;&#26131;&#34987;&#24573;&#35270;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-05">SwiftUI &#20840;&#23616;&#20027;&#39064;&#31995;&#32479;&#30340;&#21487;&#25193;&#23637;&#35774;&#35745; (Designing a Scalable App-Wide Theming System in SwiftUI)</a></strong></h3><p>&#22312; SwiftUI &#20013;&#23454;&#29616;&#20840;&#23616;&#20027;&#39064;&#65288;Theming&#65289;&#65292;&#30475;&#20284;&#26159;&#20010;&#8220;&#26679;&#24335;&#31649;&#29702;&#8221;&#38382;&#39064;&#65292;&#23454;&#21017;&#24456;&#23481;&#26131;&#29301;&#25199;&#21040;&#29366;&#24577;&#20256;&#25773;&#12289;&#20381;&#36182;&#27880;&#20837;&#20197;&#21450;&#35270;&#22270;&#21047;&#26032;&#36793;&#30028;&#31561;&#26356;&#28145;&#23618;&#30340;&#35774;&#35745;&#36873;&#25321;&#12290;<a href="https://x.com/SagarUnagar_">Sagar Unagar</a> &#20174;&#19968;&#20010;&#29616;&#23454;&#38656;&#27714;&#20986;&#21457;&#65292;&#31995;&#32479;&#23637;&#31034;&#20102;&#19968;&#22871;&#22522;&#20110; SwiftUI Environment &#30340;&#20840;&#23616;&#20027;&#39064;&#31995;&#32479;&#35774;&#35745;&#65306;&#36890;&#36807; <code>EnvironmentKey</code> &#35753;&#20027;&#39064;&#20687;&#20869;&#32622;&#29615;&#22659;&#20540;&#19968;&#26679;&#35775;&#38382;&#65292;&#20197;&#35821;&#20041;&#21270;&#30340; Design Tokens &#21462;&#20195;&#25955;&#33853;&#21508;&#22788;&#30340;&#30828;&#32534;&#30721;&#20540;&#12290;</p><p>Sagar &#20851;&#27880;&#30340;&#24182;&#19981;&#20165;&#26159;&#8220;&#22914;&#20309;&#20570;&#8221;&#65292;&#32780;&#26159;&#8220;&#21738;&#31181;&#26041;&#24335;&#22312;&#38271;&#26399;&#26356;&#21487;&#25511;&#8221;&#8212;&#8212;&#36825;&#22871;&#26041;&#26696;&#19981;&#20381;&#36182;&#29305;&#23450;&#24211;&#65292;&#26680;&#24515;&#24605;&#24819;&#26159;&#8220;&#35821;&#20041;&#21270; + &#21709;&#24212;&#24335;&#8221;&#65292;&#21487;&#20197;&#36731;&#26494;&#25193;&#23637;&#21040;&#23383;&#20307;&#12289;&#38388;&#36317;&#12289;&#22278;&#35282;&#31561;&#35774;&#35745;&#35201;&#32032;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-06">&#22312; Swift &#20013;&#23454;&#29616;&#8220;&#21482;&#25191;&#34892;&#19968;&#27425;&#8221;&#30340;&#20248;&#38597;&#26041;&#24335; (Call Once)</a></strong></h3><p>&#8220;&#30830;&#20445;&#38381;&#21253;&#21482;&#25191;&#34892;&#19968;&#27425;&#8221;&#21548;&#36215;&#26469;&#20687;&#26159;&#19968;&#20010;&#20877;&#22522;&#30784;&#19981;&#36807;&#30340;&#38656;&#27714;&#65292;&#20294;&#22312;&#30495;&#23454;&#31995;&#32479;&#37324;&#65292;&#36825;&#24448;&#24448;&#24182;&#19981;&#21482;&#26159;&#21152;&#19968;&#20010;&#24067;&#23572;&#20540;&#37027;&#20040;&#31616;&#21333;&#12290;<a href="https://hachyderm.io/@paulio87">Paul Samuels</a> &#22312;&#26412;&#25991;&#20013;&#23637;&#31034;&#20102;&#22914;&#20309;&#29992; <code>@propertyWrapper</code> &#23553;&#35013;&#36825;&#19968;&#34892;&#20026;&#65292;&#24182;&#36880;&#27493;&#28436;&#36827;&#65306;&#20174;&#21482;&#25903;&#25345; <code>() -&gt; Void</code> &#30340;&#22522;&#30784;&#29256;&#26412;&#65292;&#21040;&#24341;&#20837;&#27867;&#22411;&#25903;&#25345;&#36820;&#22238;&#20540;&#65292;&#26368;&#32456;&#20511;&#21161; Swift &#30340; Parameter Packs&#65288;<code>each Argument</code>&#65289;&#23454;&#29616;&#23545;&#20219;&#24847;&#20989;&#25968;&#31614;&#21517;&#30340;&#25903;&#25345;&#12290;</p><p>&#36825;&#26159;&#19968;&#31687;&#20559;&#24605;&#32771;&#22411;&#30340;&#25991;&#31456;&#65292;&#20854;&#20215;&#20540;&#19981;&#20165;&#22312;&#20110;&#26368;&#32456;&#30340; <code>CallOnce</code> &#23454;&#29616;&#65292;&#26356;&#22312;&#20110;&#23637;&#31034;&#20102;&#22914;&#20309;&#23558;&#22810;&#20010; Swift &#35821;&#35328;&#29305;&#24615;&#36880;&#27493;&#32452;&#21512;&#36215;&#26469;&#65292;&#35299;&#20915;&#19968;&#20010;&#30475;&#20284;&#31616;&#21333;&#21364;&#39047;&#20855;&#20195;&#34920;&#24615;&#30340;&#24037;&#31243;&#38382;&#39064;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0121-07">SwiftUI-Agent-Skill&#65306;&#35753; AI &#20889;&#20986;&#26356;&#8220;&#38752;&#35889;&#8221;&#30340; SwiftUI &#20195;&#30721;</a></strong></h3><p>&#22914;&#26524;&#20320;&#27491;&#22312;&#20351;&#29992; AI &#32534;&#31243;&#21161;&#25163;&#65288;&#22914; Claude Code&#12289;Cursor&#12289;Codex&#65289;&#65292;&#24456;&#21487;&#33021;&#36935;&#21040;&#36807;&#31867;&#20284;&#30340;&#38382;&#39064;&#65306;AI &#29983;&#25104;&#30340; SwiftUI &#20195;&#30721;&#20351;&#29992;&#20102;<strong>&#36807;&#26102;&#30340; API</strong>&#65292;&#25110;&#22312;&#29366;&#24577;&#31649;&#29702;&#12289;&#35270;&#22270;&#32452;&#32455;&#19978;&#20559;&#31163;&#26368;&#20339;&#23454;&#36341;&#8212;&#8212;&#21363;&#20415;&#20320;&#24050;&#32463;&#22312;&#22522;&#30784;&#35268;&#21017;&#20013;&#21453;&#22797;&#24378;&#35843;&#36807;&#36825;&#20123;&#35201;&#27714;&#12290;</p><p><a href="https://x.com/twannl">Antoine van der Lee</a> &#21457;&#24067;&#30340; <strong>SwiftUI-Agent-Skill</strong>&#65292;&#27491;&#26159;&#20026;&#20102;&#35299;&#20915;&#36825;&#19968;&#8220;&#26368;&#21518;&#19968;&#20844;&#37324;&#8221;&#30340;&#33853;&#24046;&#12290;&#23427;&#20026; AI &#24037;&#20855;&#25552;&#20379;&#20102;&#19968;&#22871;&#19987;&#23478;&#32423;&#30340; SwiftUI &#25351;&#23548;&#35268;&#33539;&#65292;&#28085;&#30422;&#29366;&#24577;&#31649;&#29702;&#21462;&#33293;&#12289;&#29616;&#20195; API &#26367;&#25442;&#12289;&#24615;&#33021;&#19982;&#21487;&#32500;&#25252;&#24615;&#26816;&#26597;&#65292;&#20197;&#21450; iOS 26+ &#30340; Liquid Glass &#20351;&#29992;&#36793;&#30028;&#31561;&#20869;&#23481;&#65292;&#25226;&#8220;SwiftUI &#26368;&#23481;&#26131;&#20889;&#27498;&#30340;&#22320;&#26041;&#8221;&#25972;&#29702;&#25104;&#21487;&#22797;&#29992;&#12289;&#21487;&#25191;&#34892;&#30340;&#23457;&#26597;&#27969;&#31243;&#12290;</p><blockquote><p>&#38500;&#20102;&#36825;&#22871; skill &#22806;&#65292;Antoine &#36824;&#25552;&#20379;&#20102;&#38754;&#21521; <a href="https://github.com/AvdLee/Swift-Concurrency-Agent-Skill">Swift Concurrency</a> &#21644; <a href="https://github.com/AvdLee/Core-Data-Agent-Skill">Core Data</a> &#30340; skill&#12290;</p><p>&#25105;&#24314;&#35758;&#24320;&#21457;&#32773;&#19981;&#35201;&#21482;&#26159;&#25226;&#23427;&#20204;&#31616;&#21333;&#37197;&#32622;&#36827; AI &#29615;&#22659;&#20013;&#23601;&#32467;&#26463;&#20102;&#8212;&#8212;&#36825;&#20123; skill &#25991;&#26723;&#26412;&#36523;&#23601;&#26159;&#23545;&#26576;&#19968;&#39046;&#22495;&#23454;&#36341;&#32463;&#39564;&#30340;&#32467;&#26500;&#21270;&#24635;&#32467;&#12290;&#35748;&#30495;&#35835;&#19968;&#36941;&#65292;&#21463;&#30410;&#30340;&#19981;&#21482;&#26159; AI&#65292;&#20320;&#33258;&#24049;&#20063;&#20250;&#38543;&#20043;&#36827;&#38454;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0121-08">PierreDiffsSwift&#65306;&#22312; macOS &#24212;&#29992;&#20013;&#28210;&#26579;&#31934;&#32654;&#30340;&#20195;&#30721; Diff &#35270;&#22270;</a></strong></h3><p><a href="https://x.com/jamesrochabrun">James Rochabrun</a> &#24320;&#21457;&#30340; PierreDiffsSwift&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#22312; macOS &#24212;&#29992;&#20013;&#28210;&#26579;&#28418;&#20142;&#30340;&#12289;&#24102;&#35821;&#27861;&#39640;&#20142;&#30340;&#20195;&#30721; Diff &#35270;&#22270;&#12290;</p><p>&#35813;&#24211;&#25552;&#20379;&#20102;&#19968;&#20010;&#24320;&#31665;&#21363;&#29992;&#30340;&#35299;&#20915;&#26041;&#26696;&#65306;&#22522;&#20110; <a href="https://www.npmjs.com/package/@pierre/diffs">@pierre/diffs</a> JavaScript &#24211;&#65292;&#36890;&#36807; WKWebView &#23553;&#35013;&#25104; SwiftUI &#21407;&#29983;&#35270;&#22270;&#65292;&#25903;&#25345; 40+ &#31181;&#35821;&#35328;&#30340;&#35821;&#27861;&#39640;&#20142;&#12289;Split/Unified &#20004;&#31181;&#35270;&#22270;&#27169;&#24335;&#12289;&#34892;&#20869;&#21333;&#35789;&#32423;&#21464;&#26356;&#39640;&#20142;&#65292;&#20197;&#21450;&#28145;&#33394;/&#27973;&#33394;&#20027;&#39064;&#33258;&#21160;&#20999;&#25442;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #120]]></title><description><![CDATA[Skip Goes Open Source: A High-Stakes Bet from &#8220;Selling Tools&#8221; to &#8220;Selling Trust&#8221;]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-120</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-120</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 26 Jan 2026 12:03:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!YdV4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YdV4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YdV4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 424w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 848w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 1272w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YdV4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp" width="1456" height="873" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:873,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54068,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/185721747?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YdV4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 424w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 848w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 1272w, https://substackcdn.com/image/fetch/$s_!YdV4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6888d7b-2cf7-48bf-b0c6-b757ec77f7a0_1530x917.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@markuswinkler?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Markus Winkler</a> on <a href="https://unsplash.com/photos/a-typewriter-on-a-table-NdhQbeGTA58?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Skip Goes Open Source: A High-Stakes Bet from &#8220;Selling Tools&#8221; to &#8220;Selling Trust&#8221;</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-120/">Read on web &#8594;</a></p><p>Just two months after announcing that <a href="https://fatbobman.com/en/weekly/issue-110/">the Fuse edition would be free for indie developers</a>, Skip Tools made another bold move: <a href="https://skip.dev/blog/skip-is-free/?utm_source=fatbobman%20weekly%20issue%20120&amp;utm_medium=web">making its core engine, skipstone, completely free and open source</a>. This decision marks a fundamental shift in Skip&#8217;s business model&#8212;from selling a product to relying on services and community sponsorships. The change reflects both the pressure of an underperforming commercial strategy and the team&#8217;s willingness to take risks. In an era dominated by AI and a largely entrenched developer tooling landscape, Skip chose to actively pivot rather than stand still.</p><p>Many technically strong and distinctive products fail to gain traction not because of their technology, but because of a lack of trust. As Skip itself points out, companies fear a &#8220;rug pull&#8221;: if the vendor shuts down or gets acquired, the products and tech stacks built on top of that tool may need to be rebuilt from scratch. By going open source, Skip aims to eliminate this trust barrier&#8212;placing itself on equal footing with other cross-platform tools, while also activating the community to help grow the ecosystem.</p><p>That said, while the community has largely praised Skip&#8217;s open-source decision, concerns remain. After giving up license keys as a stable revenue stream, can sponsorship alone sustain long-term development? History shows that while some open-source business models succeed, many do not. This concern is hardly unfounded. At the time of writing this issue&#8212;just days after the open-source announcement&#8212;discussion on social media was lively, yet Skip had only a handful of individual sponsors on GitHub. The gap between enthusiastic conversation and real financial support appears wider than expected. This may also explain why Skip ultimately chose to go open source: if developers cannot be convinced to pay for the tool, at least they might be persuaded to use it.</p><p>An interesting shift has emerged amid this mix of optimism and anxiety. The conversation has quietly moved from &#8220;Why pay for Skip instead of using free KMP?&#8221; to &#8220;Do you prefer writing Swift or Kotlin?&#8221; This change is significant. It suggests that Skip has successfully reframed the competition&#8212;from a debate over business models to one centered on language ecosystems. In doing so, the competitive arena expands from a single company to the entire Swift community. In this language-level contest, Skip has&#8212;perhaps intentionally, perhaps not&#8212;repositioned itself from a central protagonist to underlying infrastructure.</p><p>From the beginning, Skip was driven by the belief that there was a real commercial opportunity with sufficient returns. Without such expectations, it is unlikely that either the company or the community alone could have pushed Swift forward on non-Apple platforms so quickly. This path closely resembles how The Browser Company aggressively promoted Swift on Windows in pursuit of building the Arc browser.</p><p>As a Swift developer, I sincerely hope this pivot delivers the results Skip is aiming for. Open source is both an experiment in trust and an investment in the ecosystem. If you, too, hope to see Swift thrive beyond iOS, consider starting by <a href="https://github.com/sponsors/skiptools">becoming a individual sponsor</a> ($10/month). This is not just support for Skip&#8212;it is a vote for the broader Swift cross-platform ecosystem. How far open-source Skip can go ultimately depends on how many people are willing to move from being observers to active participants.</p><p><a href="https://fatbobman.com/en/weekly/issue-119/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Original</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/letting-swift-closures-automatically-inherit-isolation/?utm_source=fatbobman%20weekly%20issue%20120&amp;utm_medium=web">isolated(any) and #isolation: Letting Swift Closures Automatically Inherit Isolation</a></strong></h3><p>Swift 6 introduces many new features and keywords to its concurrency model. While some of them may rarely be used in day-to-day development, lacking an understanding of these concepts can leave you stuck in specific scenarios&#8212;even with AI assistance. This article walks through a real concurrency issue encountered during development and testing, demonstrating how <code>@isolated(any)</code> and the <code>#isolation</code> macro can be used to let functions inherit isolation automatically, allowing the compiler to infer the execution context of closures.</p><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0120-01">A Deep Dive into SwiftData migrations</a></strong></h3><p>As apps evolve, changes to data models are almost inevitable, and performing safe data migrations remains a significant challenge for many developers. In this article, <a href="https://x.com/donnywals">Donny Wals</a> provides a comprehensive overview of SwiftData&#8217;s migration system, covering everything from basic versioning to complex custom migration strategies. He also shares several particularly valuable recommendations: even a V1 model should be wrapped in a <code>VersionedSchema</code> to prepare for future changes; new schema versions should be introduced only between App Store release cycles, rather than being modified repeatedly during development; and for lightweight migrations, even when SwiftData can handle them automatically, it is still advisable to explicitly define them in a <code>SchemaMigrationPlan</code> to make intentions clearer and easier to test.</p><p>One of the highlights of the article is its detailed explanation of when to use <code>willMigrate</code> versus <code>didMigrate</code> in <code>MigrationStage.custom</code>, along with a &#8220;bridge version&#8221; strategy for handling complex refactors, such as splitting entities.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-02">Why MVVM-C with Coordinators does Scale -&gt; A real-world SwiftUI perspective</a></strong></h3><p>Despite the title referencing &#8220;MVVM-C,&#8221; this is not simply an article defending a specific architectural pattern. <a href="https://www.linkedin.com/in/valentebruno/">Bruno Valente Pimentel</a> redefines what &#8220;scalability&#8221; really means&#8212;arguing that it should not be measured by the number of screens or files, but by how well an architecture supports efficient collaboration and independent feature evolution. As the author puts it, &#8220;architecture is not about patterns, but about reducing fear&#8221;&#8212;the fear of changing code, collaborating with others, and evolving features.</p><blockquote><p>No matter which architecture you prefer, when building SwiftUI apps you should seriously ask yourself: are we leveraging SwiftUI&#8217;s strengths, or trying to bend SwiftUI into the shape of UIKit as we know it?</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-03">TCA (Composable Architecture): The Honest Review</a></strong></h3><p>Following Bruno&#8217;s reevaluation of MVVM-C, <a href="https://www.linkedin.com/in/chandrawelim/">Chandra Welim</a> offers an objective assessment of another highly debated architecture: TCA. The article summarizes five key strengths of TCA (predictable state management, excellent testability, time-travel debugging, composability, and strong type safety) alongside five major challenges (learning curve, boilerplate, team adoption, overengineering for simple apps, and third-party dependencies). It also provides pragmatic guidance: TCA is a powerful tool, but it is not suitable for every scenario. For simple MVPs or teams without a functional programming background, traditional MVVM may be a more practical choice; for large-scale projects with complex state and a need for time-travel debugging, TCA can offer unmatched control. The core takeaway: TCA is worth it when you truly need it&#8212;but most apps don&#8217;t.</p><blockquote><p>There is no silver bullet in architecture&#8212;only trade-offs in a specific context.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-04">Improving the usability of C libraries in Swift</a></strong></h3><p>Although Swift is designed to interoperate with C, calling C APIs directly often results in a poor developer experience&#8212;exposing raw pointers, requiring manual memory management, and using naming conventions that feel foreign to Swift. To achieve a more &#8220;native&#8221; experience, developers often have to write and maintain cumbersome wrapper layers. In this article, <a href="https://sfba.social/@dgregor79">Doug Gregor</a> explains how API Notes and Clang Attributes can be used to &#8220;guide&#8221; the Swift compiler into generating Swift-friendly interfaces without modifying the underlying C library implementation.</p><p>The significance of this improvement lies in shifting the cost of &#8220;wrapping C libraries&#8221; from the logic layer (writing Swift glue code) to the declaration layer (authoring API Notes or adding annotations to headers). This is particularly important for the adoption of Embedded Swift, where existing C libraries are fundamental to the ecosystem. As the toolchain matures, developers may eventually need only a few annotations to use C libraries in Swift as if they were native. The article also provides regex-based automation scripts for generating API Notes in bulk from structured C headers.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-05">Introduction to Building Swift for Yocto</a></strong></h3><p>For most iOS developers, Yocto may be unfamiliar, but it is the de facto standard in the embedded Linux world&#8212;offering precise control over every component included in a system. As Embedded Swift advances, integrating Swift into the Yocto ecosystem becomes a key challenge. <a href="https://x.com/xtremekforever">Jesse L. Zamora</a> demonstrates how to build a Swift runtime for Yocto using the recently revived <code>meta-swift</code> layer. Using a Raspberry Pi Zero 2 as an example, the article walks through the entire workflow, from setting up a Docker environment and building Yocto, to flashing the image and running Swift code on the device.</p><p>It is worth noting that a full build can take several hours and requires some familiarity with Yocto&#8217;s build system. However, the provided <a href="https://github.com/swift-embedded-linux/meta-swift-examples">meta-swift-examples</a> repository includes a Dockerized environment and one-click scripts that significantly lower the barrier to entry.</p><blockquote><p><a href="https://github.com/jeremy-prater/meta-swift">meta-swift</a> is the Yocto layer for Swift. It had long been stalled at Swift 5.7, but thanks to community efforts, it now supports Swift 6.1.3.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-06">TIL how to auto-move Xcode DEBUG builds to Applications</a></strong></h3><p>When developing apps that include App Intents, you may run into this issue: App Intents only appear in Shortcuts.app when the app is located in the <code>/Applications</code> directory. Since DEBUG builds are placed in DerivedData by default, this makes testing Shortcuts integration difficult. <a href="https://norden.social/@czottmann">Carlo Zottmann</a> previously relied on complex post-build scripts to move apps around, but in this article he shares a more &#8220;native&#8221; solution&#8212;using just three lines of <code>.xcconfig</code> to have Xcode automatically deploy build artifacts to a specified directory and clean them up properly when builds are removed.</p><blockquote><p>This trick is useful not only for testing App Intents, but for any scenario where DEBUG builds need to live in a specific location.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-07">Visualise anything with SwiftUI Charts</a></strong></h3><p>If you needed to build a custom, animated, and interactive circular stress indicator in SwiftUI, how would you approach it&#8212;using <code>Shape</code>, or <code>Canvas</code>? In this article, <a href="https://www.linkedin.com/in/kyryl-horbushko-67936bb5/">Kyryl Horbushko</a> presents a creative solution by leveraging Swift Charts&#8217; <code>SectorMark</code> to implement the component elegantly and efficiently.</p><p>Kyryl&#8217;s approach challenges the common assumption that Swift Charts are only suitable for traditional data visualization. For developers building complex dashboards in health or finance apps, this represents a highly instructive &#8220;dimensionality reduction&#8221; strategy&#8212;solving custom UI problems with a data visualization framework, while benefiting from built-in animations and interaction support.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0120-08">Commander: A Focused Yet Flexible AI Coding Experience</a></strong></h3><p>I enjoy using CLI tools on macOS (such as Claude Code and Codex), but the visual experience of native terminal apps leaves much to be desired, so I usually rely on VS Code extensions to improve the workflow. However, one design choice in VS Code has consistently bothered me: even when the Claude Code panel is maximized, any file modifications made by the AI will still open new editor tabs or windows, disrupting the existing interaction flow.</p><p><a href="https://x.com/krzyzanowskim">Marcin Krzy&#380;anowski</a>&#8217;s macOS-native app Commander offers a compelling alternative. It provides a more polished interface than the terminal while preserving my &#8220;flow&#8221;&#8212;files are opened only when needed, and system-default apps can be used for viewing. Commander currently supports Claude Code and Codex, includes Git worktrees and code diff features, and is completely free. It occupies a sweet spot between the &#8220;focus&#8221; of the terminal and the &#8220;flexibility&#8221; of VS Code.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-09">Oh My Agents: Centrally Managing Configuration for All AI Coding Assistants</a></strong></h3><p>With the rise of AI coding assistants like Claude Code, Cursor, Codex, and Windsurf, developers are facing a new challenge: managing scattered prompts, skills, and rules across multiple projects. Each agent has its own configuration format (<code>CLAUDE.md</code>, <code>CURSOR.md</code>, etc.), and manual copying is both inefficient and error-prone. Oh My Agents, created by <a href="https://x.com/onevcat">Wei Wang (onevcat)</a>, addresses this problem directly.</p><p>Core features:</p><ul><li><p>Centralized management of all AI agent configurations</p></li><li><p>Rule-based distribution with one-click syncing across projects</p></li><li><p>Bidirectional sync, allowing project-level improvements to flow back into the central repository</p></li><li><p>Change previews to prevent accidental overwrites</p></li></ul><p>Note: Currently macOS-only (Windows/Linux support in progress). Free during the beta period.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-120?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-120?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>Skip &#24320;&#28304;&#65306;&#20174;&#8220;&#21334;&#24037;&#20855;&#8221;&#21040;&#8220;&#21334;&#20449;&#20219;&#8221;&#30340;&#35946;&#36172;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-120/">&#32593;&#39029;&#29256;</a></strong></p><p>&#22312;&#23459;&#24067; <a href="https://fatbobman.com/zh/weekly/issue-110/">Fuse &#29256;&#26412;&#23545;&#29420;&#31435;&#24320;&#21457;&#32773;&#20813;&#36153;</a> &#20165;&#20004;&#20010;&#26376;&#21518;&#65292;Skip Tools &#20877;&#27425;&#20570;&#20986;&#24778;&#20154;&#20043;&#20030;&#8212;&#8212;<a href="https://skip.dev/blog/skip-is-free/?utm_source=fatbobman%20weekly%20issue%20120&amp;utm_medium=web">&#20840;&#38754;&#20813;&#36153;&#24182;&#24320;&#28304;&#26680;&#24515;&#24341;&#25806; skipstone</a>&#12290;&#36825;&#24847;&#21619;&#30528; Skip &#24443;&#24213;&#25913;&#21464;&#20102;&#32463;&#33829;&#26041;&#24335;&#65306;&#20174;&#8220;&#21334;&#20135;&#21697;&#8221;&#36716;&#21521;&#8220;&#21334;&#26381;&#21153;+&#31038;&#21306;&#36190;&#21161;&#8221;&#12290;&#36825;&#27425;&#21464;&#21270;&#65292;&#26082;&#26377;&#23545;&#20043;&#21069;&#21830;&#19994;&#27169;&#24335;&#25191;&#34892;&#19981;&#20339;&#32780;&#34987;&#36843;&#35843;&#25972;&#30340;&#26080;&#22856;&#65292;&#20063;&#20307;&#29616;&#20102; Skip &#22242;&#38431;&#30340;&#26524;&#25954;&#8212;&#8212;&#22312;&#24403;&#21069; AI &#30427;&#34892;&#12289;&#24320;&#21457;&#24037;&#20855;&#26684;&#23616;&#22266;&#21270;&#30340;&#32972;&#26223;&#19979;&#65292;&#20027;&#21160;&#27714;&#21464;&#65292;&#21147;&#27714;&#31361;&#30772;&#12290;</p><p>&#24456;&#22810;&#20248;&#31168;&#19988;&#26377;&#29305;&#28857;&#30340;&#20135;&#21697;&#27809;&#33021;&#33719;&#24471;&#24212;&#26377;&#30340;&#20351;&#29992;&#37327;&#65292;&#26368;&#22823;&#30340;&#38459;&#30861;&#24448;&#24448;&#19981;&#26159;&#25216;&#26415;&#65292;&#32780;&#26159;&#8220;&#20449;&#20219;&#8221;&#12290;&#27491;&#22914; Skip &#23448;&#26041;&#25152;&#35328;&#65292;&#20225;&#19994;&#26368;&#25285;&#24515;&#30340;&#26159;&#8220;rug pull&#8221;&#8212;&#8212;&#19975;&#19968;&#20844;&#21496;&#20498;&#38381;&#25110;&#34987;&#25910;&#36141;&#65292;&#25276;&#27880;&#22312;&#36825;&#20010;&#24037;&#20855;&#19978;&#30340;&#20135;&#21697;&#21644;&#25216;&#26415;&#26632;&#23558;&#38754;&#20020;&#25512;&#20498;&#37325;&#26469;&#30340;&#39118;&#38505;&#12290;Skip &#24076;&#26395;&#36890;&#36807;&#24320;&#28304;&#28040;&#38500;&#36825;&#31181;&#20449;&#20219;&#21361;&#26426;&#65292;&#35753;&#33258;&#24049;&#21644;&#20854;&#20182;&#36328;&#24179;&#21488;&#24037;&#20855;&#31449;&#22312;&#21516;&#19968;&#36215;&#36305;&#32447;&#19978;&#65292;&#21516;&#26102;&#28608;&#27963;&#31038;&#21306;&#21147;&#37327;&#65292;&#21152;&#36895;&#29983;&#24577;&#24314;&#35774;&#12290;</p><p>&#23613;&#31649;&#31038;&#21306;&#23545; Skip &#30340;&#24320;&#28304;&#20915;&#23450;&#32473;&#20104;&#20102;&#20805;&#20998;&#32943;&#23450;&#65292;&#20294;&#20063;&#26377;&#19981;&#23569;&#20154;&#25285;&#24515;&#65306;&#22312;&#25918;&#24323;&#20102; license key &#36825;&#19968;&#31283;&#23450;&#25910;&#20837;&#26469;&#28304;&#21518;&#65292;&#20165;&#38752;&#36190;&#21161;&#27169;&#24335;&#33021;&#21542;&#25903;&#25745;&#25345;&#32493;&#24320;&#21457;&#25104;&#26412;&#65311;&#27605;&#31455;&#65292;&#25104;&#21151;&#30340;&#24320;&#28304;&#21830;&#19994;&#26696;&#20363;&#34429;&#26377;&#65292;&#20294;&#22833;&#36133;&#30340;&#20063;&#19981;&#23569;&#12290;&#36825;&#31181;&#25285;&#24551;&#24182;&#38750;&#26462;&#20154;&#24551;&#22825;&#12290;&#22312;&#25105;&#25776;&#20889;&#26412;&#26399;&#21608;&#25253;&#26102;&#65288;&#23459;&#24067;&#24320;&#28304;&#25968;&#22825;&#21518;&#65289;&#65292;&#23613;&#31649;&#24320;&#28304;&#28040;&#24687;&#22312;&#31038;&#20132;&#23186;&#20307;&#19978;&#24341;&#21457;&#20102;&#28909;&#35758;&#65292;&#20294;&#22312; GitHub &#19978;&#65292;Skip &#30340;&#20010;&#20154;&#36190;&#21161;&#32773;&#20165;&#26377;&#21313;&#20960;&#20301;&#12290;&#20174;&#8220;&#28909;&#38393;&#30340;&#35752;&#35770;&#8221;&#21040;&#8220;&#30495;&#37329;&#30333;&#38134;&#30340;&#25903;&#25345;&#8221;&#65292;&#20013;&#38388;&#30340;&#40511;&#27807;&#20284;&#20046;&#27604;&#24819;&#35937;&#20013;&#36824;&#35201;&#28145;&#12290;&#36825;&#25110;&#35768;&#20063;&#35299;&#37322;&#20102;&#20026;&#20160;&#20040; Skip &#26368;&#32456;&#36873;&#25321;&#20102;&#24320;&#28304;&#8212;&#8212;&#22312;&#26080;&#27861;&#35828;&#26381;&#24320;&#21457;&#32773;&#8221;&#20184;&#36153;&#20351;&#29992;&#8221;&#26102;&#65292;&#33267;&#23569;&#35201;&#20105;&#21462;&#21040;&#20182;&#20204;&#8221;&#20813;&#36153;&#20351;&#29992;&#8221;&#30340;&#26426;&#20250;&#12290;</p><p>&#19968;&#20010;&#26377;&#36259;&#30340;&#29616;&#35937;&#26159;&#65292;&#22312;&#32943;&#23450;&#19982;&#24551;&#34385;&#24182;&#23384;&#30340;&#24773;&#32490;&#20013;&#65292;&#35752;&#35770;&#30340;&#28966;&#28857;&#24708;&#28982;&#21457;&#29983;&#20102;&#21464;&#21270;&#65306;&#20174;&#8220;&#20026;&#20160;&#20040;&#35201;&#33457;&#38065;&#20080; Skip &#32780;&#19981;&#26159;&#29992;&#20813;&#36153;&#30340; KMP?&#8221;&#21464;&#25104;&#20102;&#8220;&#20320;&#26159;&#26356;&#21916;&#27426;&#20889; Swift &#36824;&#26159; Kotlin?&#8221;&#12290;&#36825;&#20010;&#36716;&#21464;&#24847;&#20041;&#37325;&#22823;&#8212;&#8212;&#23427;&#24847;&#21619;&#30528; Skip &#24050;&#32463;&#25104;&#21151;&#23558;&#31454;&#20105;&#32500;&#24230;&#20174;&#8220;&#21830;&#19994;&#27169;&#24335;&#8221;&#36716;&#31227;&#21040;&#20102;&#8220;&#35821;&#35328;&#29983;&#24577;&#8221;&#65292;&#32780;&#21442;&#19982;&#31454;&#20105;&#30340;&#20027;&#20307;&#20063;&#20174;&#8220;&#19968;&#23478;&#23567;&#20844;&#21496;&#8221;&#25193;&#23637;&#20026;&#8220;&#25972;&#20010; Swift &#31038;&#21306;&#8221;&#12290;&#22312;&#36825;&#22330;&#35821;&#35328;&#20043;&#20105;&#20013;&#65292;Skip &#32874;&#26126;&#22320;&#65288;&#25110;&#35768;&#26159;&#26080;&#24847;&#38388;&#65289;&#23558;&#33258;&#24049;&#30340;&#35282;&#33394;&#20174;&#8220;&#20027;&#35282;&#8221;&#21464;&#25104;&#20102;&#8220;&#22522;&#30784;&#35774;&#26045;&#8221;&#12290;</p><p>Skip &#26368;&#26089;&#30340;&#20986;&#21457;&#28857;&#26159;&#30475;&#21040;&#20102;&#19968;&#20010;&#21830;&#19994;&#26426;&#20250;&#65292;&#35748;&#20026;&#26377;&#36275;&#22815;&#30340;&#21830;&#19994;&#22238;&#25253;&#12290;&#22914;&#26524;&#19981;&#26159;&#26377;&#36825;&#26679;&#30340;&#39044;&#26399;&#65292;&#20165;&#38752;&#23448;&#26041;&#25110;&#31038;&#21306;&#30340;&#21147;&#37327;&#65292;Swift &#21487;&#33021;&#26080;&#27861;&#24555;&#36895;&#25512;&#36827;&#22312;&#20854;&#20182;&#24179;&#21488;&#19978;&#30340;&#36827;&#23637;&#12290;&#36825;&#19968;&#36335;&#24452;&#19982; The Browser Company &#20026;&#20102;&#25171;&#36896; Arc &#27983;&#35272;&#22120;&#32780;&#22823;&#21147;&#25512;&#21160; Swift &#22312; Windows &#24179;&#21488;&#19978;&#30340;&#36866;&#37197;&#22914;&#20986;&#19968;&#36761;&#12290;</p><p>&#20316;&#20026;&#19968;&#20010; Swift &#24320;&#21457;&#32773;&#65292;&#25105;&#30001;&#34935;&#24076;&#26395; Skip &#30340;&#36825;&#27425;&#35843;&#25972;&#33021;&#22815;&#21462;&#24471;&#39044;&#26399;&#25928;&#26524;&#12290;&#24320;&#28304;&#26159;&#19968;&#22330;&#20449;&#20219;&#30340;&#23454;&#39564;&#65292;&#20063;&#26159;&#19968;&#27425;&#29983;&#24577;&#30340;&#25237;&#36164;&#12290;&#22914;&#26524;&#20320;&#20063;&#26399;&#24453; Swift &#33021;&#22312; iOS &#20043;&#22806;&#30340;&#24179;&#21488;&#19978;&#25317;&#26377;&#26356;&#22810;&#21487;&#33021;&#65292;&#19981;&#22952;&#20174;&#25104;&#20026;&#19968;&#20010;<a href="https://github.com/sponsors/skiptools">&#29420;&#31435;&#36190;&#21161;&#32773;</a>($10/&#26376;)&#20570;&#36215;&#8212;&#8212;&#36825;&#19981;&#20165;&#26159;&#23545; Skip &#30340;&#25903;&#25345;&#65292;&#26356;&#26159;&#23545;&#25972;&#20010; Swift &#36328;&#24179;&#21488;&#29983;&#24577;&#30340;&#25237;&#31080;&#12290;&#24320;&#28304;&#30340; Skip &#33021;&#36208;&#22810;&#36828;&#65292;&#21462;&#20915;&#20110;&#26377;&#22810;&#23569;&#20154;&#24895;&#24847;&#20174;&#26049;&#35266;&#32773;&#21464;&#25104;&#21442;&#19982;&#32773;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-119/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#21407;&#21019;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/letting-swift-closures-automatically-inherit-isolation/?utm_source=fatbobman%20weekly%20issue%20120&amp;utm_medium=web">isolated(any) &#19982; #isolation&#65306;&#35753; Swift &#38381;&#21253;&#33258;&#21160;&#32487;&#25215;&#38548;&#31163;&#22495;</a></strong></h3><p>Swift 6 &#20026;&#24182;&#21457;&#24341;&#20837;&#20102;&#35768;&#22810;&#26032;&#21151;&#33021;&#19982;&#20851;&#38190;&#23383;&#12290;&#34429;&#28982;&#20854;&#20013;&#19981;&#23569;&#20869;&#23481;&#22312;&#26085;&#24120;&#24320;&#21457;&#20013;&#21487;&#33021;&#40092;&#23569;&#29992;&#21040;&#65292;&#20294;&#19968;&#26086;&#36973;&#36935;&#29305;&#23450;&#22330;&#26223;&#65292;&#33509;&#23545;&#36825;&#20123;&#26032;&#27010;&#24565;&#32570;&#20047;&#20102;&#35299;&#65292;&#21363;&#20415;&#26377; AI &#36741;&#21161;&#20063;&#21487;&#33021;&#38519;&#20837;&#20725;&#23616;&#12290;&#26412;&#25991;&#23558;&#36890;&#36807;&#19968;&#20010;&#22312;&#24320;&#21457;&#27979;&#35797;&#20013;&#36935;&#21040;&#30340;&#23454;&#38469;&#24182;&#21457;&#38382;&#39064;&#65292;&#26469;&#20171;&#32461;&#22914;&#20309;&#21033;&#29992; <code>@isolated(any)</code> &#20197;&#21450; <code>#isolation</code> &#23439;&#65292;&#23454;&#29616;&#20989;&#25968;&#30340;&#38548;&#31163;&#22495;&#32487;&#25215;&#65292;&#20174;&#32780;&#35753;&#32534;&#35793;&#22120;&#33258;&#21160;&#25512;&#26029;&#38381;&#21253;&#30340;&#36816;&#34892;&#29615;&#22659;&#12290;</p><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0120-01">SwiftData &#25968;&#25454;&#36801;&#31227;&#20840;&#35299;&#26512; (A Deep Dive into SwiftData migrations)</a></strong></h3><p>&#38543;&#30528;&#24212;&#29992;&#30340;&#21457;&#23637;&#65292;&#25968;&#25454;&#27169;&#22411;&#20960;&#20046;&#26080;&#21487;&#36991;&#20813;&#22320;&#20250;&#20986;&#29616;&#21464;&#21270;&#65292;&#22914;&#20309;&#23433;&#20840;&#22320;&#36827;&#34892;&#25968;&#25454;&#36801;&#31227;&#23545;&#24456;&#22810;&#24320;&#21457;&#32773;&#26469;&#35828;&#37117;&#26159;&#19968;&#20010;&#19981;&#23567;&#30340;&#25361;&#25112;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/donnywals">Donny Wals</a> &#20840;&#38754;&#35762;&#35299;&#20102; SwiftData &#30340;&#25968;&#25454;&#36801;&#31227;&#26426;&#21046;&#65292;&#20174;&#22522;&#30784;&#30340;&#29256;&#26412;&#25511;&#21046;&#21040;&#22797;&#26434;&#30340;&#33258;&#23450;&#20041;&#36801;&#31227;&#31574;&#30053;&#12290;&#20854;&#20013;&#65292;Donny &#32473;&#20986;&#20102;&#20960;&#20010;&#29305;&#21035;&#26377;&#20215;&#20540;&#30340;&#24314;&#35758;&#65306;&#21363;&#20351;&#26159; V1 &#29256;&#26412;&#20063;&#24212;&#35813;&#20351;&#29992; <code>VersionedSchema</code> &#36827;&#34892;&#23553;&#35013;&#65292;&#20026;&#26410;&#26469;&#30340;&#36801;&#31227;&#25171;&#22909;&#22522;&#30784;&#65307;&#21482;&#22312; App Store &#21457;&#24067;&#21608;&#26399;&#20043;&#38388;&#24341;&#20837;&#26032;&#30340; Schema &#29256;&#26412;&#65292;&#32780;&#19981;&#26159;&#22312;&#24320;&#21457;&#36807;&#31243;&#20013;&#39057;&#32321;&#20462;&#25913;&#65307;&#23545;&#20110;&#36731;&#37327;&#36801;&#31227;&#65292;&#21363;&#20351; SwiftData &#21487;&#20197;&#33258;&#21160;&#23436;&#25104;&#65292;&#20063;&#24314;&#35758;&#26174;&#24335;&#22320;&#20889;&#20837; <code>SchemaMigrationPlan</code> &#20013;&#65292;&#20351;&#24847;&#22270;&#26356;&#21152;&#26126;&#30830;&#19988;&#26131;&#20110;&#27979;&#35797;&#12290;</p><p>&#25991;&#31456;&#30340;&#19968;&#22823;&#20142;&#28857;&#26159;&#35814;&#32454;&#35299;&#37322;&#20102; <code>MigrationStage.custom</code> &#20013; <code>willMigrate</code> &#19982; <code>didMigrate</code> &#30340;&#36866;&#29992;&#22330;&#26223;&#65292;&#24182;&#25552;&#20986;&#20102;&#24212;&#23545;&#22797;&#26434;&#37325;&#26500;&#65288;&#20363;&#22914;&#25286;&#20998;&#23454;&#20307;&#65289;&#30340;&#8220;&#26725;&#25509;&#29256;&#26412;&#65288;Bridge Version&#65289;&#8221;&#31574;&#30053;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-02">&#20026;&#20160;&#20040; MVVM-C &#22312; SwiftUI &#39033;&#30446;&#20013;&#20381;&#28982;&#33021;&#25193;&#23637; (Why MVVM-C with Coordinators does Scale -&gt; A real-world SwiftUI perspective)</a></strong></h3><p>&#23613;&#31649;&#26631;&#39064;&#20013;&#21253;&#21547;&#8220;MVVM-C&#8221;&#65292;&#20294;&#36825;&#24182;&#38750;&#19968;&#31687;&#21333;&#32431;&#20026;&#26576;&#31181;&#26550;&#26500;&#27169;&#24335;&#36777;&#25252;&#30340;&#25991;&#31456;&#12290;<a href="https://www.linkedin.com/in/valentebruno/">Bruno Valente Pimentel</a> &#22312;&#25991;&#20013;&#37325;&#26032;&#23450;&#20041;&#20102;&#8220;&#25193;&#23637;&#24615;&#8221;&#30340;&#20869;&#28085;&#8212;&#8212;&#23427;&#19981;&#24212;&#20165;&#20197;&#23631;&#24149;&#25110;&#25991;&#20214;&#30340;&#25968;&#37327;&#26469;&#34913;&#37327;&#65292;&#32780;&#24212;&#30475;&#20854;&#26159;&#21542;&#25903;&#25345;&#39640;&#25928;&#30340;&#22810;&#20154;&#21327;&#20316;&#21450;&#21151;&#33021;&#30340;&#29420;&#31435;&#28436;&#36827;&#12290;&#27491;&#22914;&#20316;&#32773;&#25152;&#35328;&#65306;&#8220;&#26550;&#26500;&#26080;&#20851;&#20046;&#27169;&#24335;&#65292;&#32780;&#20851;&#20046;&#20943;&#23569;&#24656;&#24807;&#8221;&#8212;&#8212;&#20943;&#23569;&#20462;&#25913;&#20195;&#30721;&#12289;&#22242;&#38431;&#21327;&#20316;&#20197;&#21450;&#21151;&#33021;&#28436;&#36827;&#26102;&#30340;&#24656;&#24807;&#12290;</p><blockquote><p>&#26080;&#35770;&#20320;&#20542;&#21521;&#20110;&#21738;&#31181;&#26550;&#26500;&#27169;&#24335;&#65292;&#22312;&#29992;&#23427;&#26500;&#24314; SwiftUI &#39033;&#30446;&#26102;&#65292;&#37117;&#24212;&#35813;&#35748;&#30495;&#24605;&#32771;&#65306;&#25105;&#20204;&#21040;&#24213;&#26159;&#22312;&#21033;&#29992; SwiftUI &#30340;&#29305;&#24615;&#65292;&#36824;&#26159;&#22312;&#35797;&#22270;&#25226; SwiftUI &#25913;&#36896;&#25104;&#25105;&#20204;&#29087;&#24713;&#30340; UIKit&#65311;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-03">TCA &#26550;&#26500;&#30340;&#30495;&#23454;&#35780;&#20272; (TCA (Composable Architecture): The Honest Review)</a></strong></h3><p>&#32487; Bruno &#20026; MVVM-C &#8220;&#27491;&#21517;&#8221;&#21518;&#65292;<a href="https://www.linkedin.com/in/chandrawelim/">Chandra Welim</a> &#23545;&#21478;&#19968;&#20010;&#26497;&#20855;&#20105;&#35758;&#30340;&#26550;&#26500;&#8212;&#8212;TCA &#36827;&#34892;&#20102;&#23458;&#35266;&#35780;&#20272;&#12290;&#20316;&#32773;&#24635;&#32467;&#20102; TCA &#30340;&#20116;&#22823;&#20248;&#21183;&#65288;&#21487;&#39044;&#27979;&#30340;&#29366;&#24577;&#31649;&#29702;&#12289;&#20248;&#31168;&#30340;&#21487;&#27979;&#35797;&#24615;&#12289;&#26102;&#38388;&#26053;&#34892;&#35843;&#35797;&#12289;&#32452;&#21512;&#24615;&#12289;&#24378;&#31867;&#22411;&#23433;&#20840;&#65289;&#21644;&#20116;&#22823;&#25361;&#25112;&#65288;&#23398;&#20064;&#26354;&#32447;&#12289;&#26679;&#26495;&#20195;&#30721;&#12289;&#22242;&#38431;&#37319;&#32435;&#12289;&#23545;&#31616;&#21333;&#24212;&#29992;&#36807;&#24230;&#35774;&#35745;&#12289;&#31532;&#19977;&#26041;&#20381;&#36182;&#65289;&#65292;&#21516;&#26102;&#32473;&#20986;&#20102;&#21153;&#23454;&#30340;&#24314;&#35758;&#65306;TCA &#26159;&#19968;&#20010;&#24378;&#22823;&#30340;&#24037;&#20855;&#65292;&#20294;&#32477;&#38750;&#36866;&#29992;&#20110;&#25152;&#26377;&#22330;&#26223;&#12290;&#23545;&#20110;&#31616;&#21333;&#30340; MVP &#25110;&#32570;&#20047;&#20989;&#25968;&#24335;&#32534;&#31243;&#32972;&#26223;&#30340;&#22242;&#38431;&#65292;&#20256;&#32479;&#30340; MVVM &#25110;&#35768;&#26159;&#26356;&#21153;&#23454;&#30340;&#36873;&#25321;&#65307;&#32780;&#23545;&#20110;&#29366;&#24577;&#38169;&#32508;&#22797;&#26434;&#12289;&#38656;&#35201;&#8220;&#26102;&#38388;&#26053;&#34892;&#8221;&#35843;&#35797;&#30340;&#22823;&#22411;&#39033;&#30446;&#65292;TCA &#21017;&#33021;&#25552;&#20379;&#26080;&#19982;&#20262;&#27604;&#30340;&#25484;&#25511;&#21147;&#12290;&#26680;&#24515;&#32467;&#35770;&#65306;TCA &#22312;&#20320;&#38656;&#35201;&#26102;&#24456;&#20540;&#24471;&#65292;&#20294;&#22823;&#22810;&#25968;&#24212;&#29992;&#24182;&#19981;&#38656;&#35201;&#23427;&#12290;</p><blockquote><p>&#26550;&#26500;&#36873;&#25321;&#27809;&#26377;&#38134;&#24377;&#65292;&#21482;&#26377;&#22312;&#29305;&#23450;&#19978;&#19979;&#25991;&#20013;&#30340;&#26435;&#34913;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-04">&#35753; C &#24211;&#22312; Swift &#20013;&#8220;&#20687;&#21407;&#29983; API &#19968;&#26679;&#22909;&#29992;&#8221; (Improving the usability of C libraries in Swift)</a></strong></h3><p>Swift &#34429;&#28982;&#29983;&#26469;&#23601;&#20860;&#23481; C&#65292;&#20294;&#30452;&#25509;&#35843;&#29992; C API &#24448;&#24448;&#20307;&#39564;&#19981;&#20339;&#8212;&#8212;&#24320;&#21457;&#32773;&#36890;&#24120;&#38656;&#35201;&#38754;&#23545;&#35064;&#25351;&#38024;&#12289;&#25163;&#21160;&#20869;&#23384;&#31649;&#29702;&#20197;&#21450;&#19981;&#31526;&#21512; Swift &#21629;&#21517;&#20064;&#24815;&#30340;&#20989;&#25968;&#12290;&#20026;&#20102;&#33719;&#24471;&#8220;&#21407;&#29983;&#8221;&#20307;&#39564;&#65292;&#24320;&#21457;&#32773;&#19981;&#24471;&#19981;&#32534;&#20889;&#21644;&#32500;&#25252;&#32321;&#29712;&#30340; Wrapper &#23618;&#12290;&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://sfba.social/@dgregor79">Doug Gregor</a> &#35814;&#32454;&#20171;&#32461;&#20102;&#22914;&#20309;&#21033;&#29992; API Notes &#21644; Clang Attributes &#26426;&#21046;&#65292;&#22312;&#19981;&#20462;&#25913; C &#24211;&#23454;&#29616;&#20195;&#30721;&#30340;&#21069;&#25552;&#19979;&#65292;&#8220;&#25351;&#23548;&#8221; Swift &#32534;&#35793;&#22120;&#29983;&#25104;&#31526;&#21512; Swift &#39118;&#26684;&#30340;&#25509;&#21475;&#12290;</p><p>&#36825;&#39033;&#25913;&#36827;&#30340;&#24847;&#20041;&#22312;&#20110;&#65292;&#23427;&#23558;&#8220;&#23553;&#35013; C &#24211;&#8221;&#30340;&#25104;&#26412;&#20174;&#36923;&#36753;&#23618;&#65288;&#32534;&#20889; Swift &#33014;&#27700;&#20195;&#30721;&#65289;&#36716;&#31227;&#21040;&#20102;&#22768;&#26126;&#23618;&#65288;&#32534;&#20889; API Notes &#25110;&#28155;&#21152;&#22836;&#25991;&#20214;&#27880;&#35299;&#65289;&#12290;&#36825;&#23545;&#20110; Embedded Swift &#30340;&#26222;&#21450;&#33267;&#20851;&#37325;&#35201;&#65292;&#22240;&#20026;&#23884;&#20837;&#24335;&#24320;&#21457;&#39640;&#24230;&#20381;&#36182;&#29616;&#26377;&#30340; C &#24211;&#29983;&#24577;&#12290;&#38543;&#30528;&#24037;&#20855;&#38142;&#30340;&#23436;&#21892;&#65292;&#26410;&#26469;&#24320;&#21457;&#32773;&#21487;&#33021;&#21482;&#38656;&#35201;&#32473; C &#24211;&#21152;&#20960;&#20010;&#27880;&#35299;&#65292;&#23601;&#33021;&#30452;&#25509;&#22312; Swift &#20013;&#20687;&#20351;&#29992;&#21407;&#29983;&#24211;&#19968;&#26679;&#35843;&#29992;&#23427;&#12290;&#25991;&#31456;&#36824;&#25552;&#20379;&#20102;&#22522;&#20110;&#27491;&#21017;&#34920;&#36798;&#24335;&#30340;&#33258;&#21160;&#21270;&#33050;&#26412;&#65292;&#21487;&#20197;&#20026;&#32467;&#26500;&#21270;&#30340; C &#22836;&#25991;&#20214;&#25209;&#37327;&#29983;&#25104; API Notes&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-05">&#22312; Yocto &#31995;&#32479;&#20013;&#26500;&#24314; Swift (Introduction to Building Swift for Yocto)</a></strong></h3><p>&#23545;&#20110;&#22823;&#22810;&#25968; iOS &#24320;&#21457;&#32773;&#26469;&#35828;&#65292;Yocto &#21487;&#33021;&#27604;&#36739;&#38476;&#29983;&#65292;&#20294;&#23427;&#26159;&#23884;&#20837;&#24335; Linux &#39046;&#22495;&#30340;&#20107;&#23454;&#26631;&#20934;&#8212;&#8212;&#23427;&#33021;&#22815;&#31934;&#30830;&#25511;&#21046;&#31995;&#32479;&#20013;&#21253;&#21547;&#30340;&#27599;&#19968;&#20010;&#32452;&#20214;&#12290;&#38543;&#30528; Embedded Swift &#30340;&#25512;&#36827;&#65292;&#22914;&#20309;&#22312; Yocto &#29983;&#24577;&#20013;&#38598;&#25104; Swift &#25104;&#20026;&#20102;&#19968;&#20010;&#20851;&#38190;&#38382;&#39064;&#12290;<a href="https://x.com/xtremekforever">Jesse L. Zamora</a> &#35814;&#32454;&#28436;&#31034;&#20102;&#22914;&#20309;&#20351;&#29992;&#36817;&#26399;&#37325;&#33719;&#26356;&#26032;&#30340; <code>meta-swift</code> &#22312; Yocto &#31995;&#32479;&#20013;&#26500;&#24314; Swift &#36816;&#34892;&#29615;&#22659;&#12290;&#25991;&#31456;&#20197; Raspberry Pi Zero 2 &#20026;&#20363;&#65292;&#20174; Docker &#29615;&#22659;&#25645;&#24314;&#12289;Yocto &#26500;&#24314;&#12289;&#38236;&#20687;&#28903;&#24405;&#21040;&#23454;&#38469;&#36816;&#34892;&#65292;&#28436;&#31034;&#20102;&#23436;&#25972;&#30340;&#24037;&#20316;&#27969;&#12290;</p><p>&#38656;&#35201;&#27880;&#24847;&#30340;&#26159;&#65292;&#23436;&#25972;&#26500;&#24314;&#36807;&#31243;&#38656;&#35201;&#25968;&#23567;&#26102;&#65292;&#19988;&#35201;&#27714;&#23545; Yocto &#26500;&#24314;&#31995;&#32479;&#26377;&#22522;&#26412;&#20102;&#35299;&#12290;&#19981;&#36807;&#65292;&#25991;&#31456;&#25552;&#20379;&#30340; <a href="https://github.com/swift-embedded-linux/meta-swift-examples">meta-swift-examples</a> &#20179;&#24211;&#24050;&#32463;&#21253;&#21547;&#20102; Docker &#21270;&#30340;&#26500;&#24314;&#29615;&#22659;&#21644;&#19968;&#38190;&#33050;&#26412;&#65292;&#22823;&#22823;&#38477;&#20302;&#20102;&#19978;&#25163;&#38376;&#27099;&#12290;</p><blockquote><p><a href="https://github.com/jeremy-prater/meta-swift">meta-swift</a> &#26159; Swift &#35821;&#35328;&#30340; Yocto &#23618;&#65292;&#27492;&#21069;&#26366;&#38271;&#26399;&#20572;&#28382;&#20110; Swift 5.7&#65292;&#20294;&#22312;&#31038;&#21306;&#30340;&#21162;&#21147;&#19979;&#65292;&#30446;&#21069;&#24050;&#25903;&#25345;&#21040; Swift 6.1.3&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-06">&#35753; Xcode &#30340; DEBUG &#26500;&#24314;&#33258;&#21160;&#37096;&#32626;&#21040; /Applications (TIL how to auto-move Xcode DEBUG builds to Applications)</a></strong></h3><p>&#24320;&#21457;&#21253;&#21547; App Intents &#30340;&#24212;&#29992;&#26102;&#65292;&#20320;&#21487;&#33021;&#36935;&#21040;&#36807;&#36825;&#20010;&#38382;&#39064;&#65306;App Intents &#24517;&#39035;&#22312; <code>/Applications</code> &#30446;&#24405;&#19979;&#25165;&#33021;&#22312; Shortcuts.app &#20013;&#26174;&#31034;&#12290;&#36825;&#24847;&#21619;&#30528; DEBUG &#26500;&#24314;&#40664;&#35748;&#25918;&#22312; DerivedData &#20013;&#26102;&#65292;&#24320;&#21457;&#32773;&#26080;&#27861;&#27979;&#35797; Shortcuts &#38598;&#25104;&#12290; <a href="https://norden.social/@czottmann">Carlo Zottmann</a> &#26366;&#38271;&#26399;&#20351;&#29992;&#22797;&#26434;&#30340; Post-build &#33050;&#26412;&#26469;&#25644;&#36816; App&#65292;&#20294;&#20182;&#22312;&#26412;&#25991;&#20013;&#20998;&#20139;&#20102;&#19968;&#20010;&#26356;&#8220;&#21407;&#29983;&#8221;&#30340;&#26041;&#26696;&#8212;&#8212;&#36890;&#36807;&#19977;&#34892; <code>.xcconfig</code> &#37197;&#32622;&#35753; Xcode &#33258;&#21160;&#23558;&#26500;&#24314;&#20135;&#29289;&#37096;&#32626;&#21040;&#25351;&#23450;&#30446;&#24405;&#65292;&#24182;&#22312;&#28165;&#29702;&#26500;&#24314;&#26102;&#27491;&#30830;&#21024;&#38500;&#24050;&#37096;&#32626;&#30340;&#25991;&#20214;&#12290;</p><blockquote><p>&#36825;&#20010;&#25216;&#24039;&#19981;&#20165;&#36866;&#29992;&#20110; App Intents &#27979;&#35797;&#65292;&#20063;&#36866;&#29992;&#20110;&#20219;&#20309;&#38656;&#35201;&#23558; DEBUG &#26500;&#24314;&#25918;&#21040;&#29305;&#23450;&#20301;&#32622;&#30340;&#22330;&#26223;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-07">&#29992; Swift Charts &#26500;&#24314;&#33258;&#23450;&#20041;&#21487;&#20132;&#20114;&#20202;&#34920;&#30424; (Visualise anything with SwiftUI Charts)</a></strong></h3><p>&#22914;&#26524;&#20320;&#38656;&#35201;&#33258;&#23450;&#20041;&#19968;&#20010;&#21487;&#21160;&#30011;&#12289;&#21487;&#20132;&#20114;&#30340;&#29615;&#24418;&#21387;&#21147;&#20202;&#34920;&#30424;&#65288;Stress Indicator&#65289;&#30340; SwiftUI &#32452;&#20214;&#65292;&#20320;&#20250;&#22914;&#20309;&#36827;&#34892;&#65311;&#26159;&#20351;&#29992; Shape&#65292;&#36824;&#26159; Canvas&#65311;<a href="https://www.linkedin.com/in/kyryl-horbushko-67936bb5/">Kyryl Horbushko</a> &#22312;&#26412;&#25991;&#20013;&#23637;&#31034;&#20102;&#19968;&#20010;&#38750;&#24120;&#26377;&#21019;&#24847;&#30340;&#35299;&#27861;&#8212;&#8212;&#21033;&#29992; Swift Charts &#30340; <code>SectorMark</code>&#65292;&#20248;&#38597;&#19988;&#39640;&#25928;&#22320;&#23454;&#29616;&#20102;&#38656;&#27714;&#12290;</p><p>Kyryl &#30340;&#23454;&#29616;&#25171;&#30772;&#20102;&#25105;&#20204;&#23545; Swift Charts &#20165;&#29992;&#20110;&#8220;&#25968;&#25454;&#21487;&#35270;&#21270;&#8221;&#30340;&#21051;&#26495;&#21360;&#35937;&#12290;&#23545;&#20110;&#38656;&#35201;&#24320;&#21457;&#20581;&#24247;&#31867;&#12289;&#37329;&#34701;&#31867;&#22797;&#26434; Dashboard &#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#31181;&#26497;&#20855;&#21442;&#32771;&#20215;&#20540;&#30340;&#8221;&#38477;&#32500;&#25171;&#20987;&#8221;&#24335;&#26041;&#26696;&#8212;&#8212;&#29992;&#25968;&#25454;&#21487;&#35270;&#21270;&#26694;&#26550;&#35299;&#20915;&#33258;&#23450;&#20041; UI &#38382;&#39064;&#65292;&#26082;&#20943;&#23569;&#20195;&#30721;&#37327;&#65292;&#21448;&#33719;&#24471;&#20869;&#32622;&#30340;&#21160;&#30011;&#21644;&#20132;&#20114;&#25903;&#25345;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0120-08">Commander&#65306;&#20860;&#39038;&#19987;&#27880;&#19982;&#28789;&#27963;&#30340; AI &#21464;&#25104;&#20307;&#39564;</a></strong></h3><p>&#25105;&#21916;&#27426;&#22312; macOS &#19978;&#20351;&#29992; CLI &#24037;&#20855;(Claude Code&#12289;Codex)&#65292;&#20294;&#21407;&#29983;&#32456;&#31471;&#24212;&#29992;&#30340;&#35270;&#35273;&#20307;&#39564;&#23454;&#22312;&#19981;&#25954;&#24685;&#32500;&#65292;&#22240;&#27492;&#22810;&#25968;&#24773;&#20917;&#19979;&#25105;&#37117;&#22312; VSCode &#20013;&#36890;&#36807;&#25554;&#20214;&#26469;&#25913;&#21892;&#20307;&#39564;&#12290;&#28982;&#32780;&#65292;VSCode &#30340;&#19968;&#20010;&#35774;&#35745;&#22987;&#32456;&#35753;&#25105;&#22256;&#25200;&#65306;&#21363;&#20415;&#23558; Claude Code &#30340;&#23545;&#35805;&#26639;&#26368;&#22823;&#21270;&#65292;AI &#20462;&#25913;&#25991;&#20214;&#26102;&#20173;&#20250;&#33258;&#21160;&#25171;&#24320;&#26032;&#30340;&#25991;&#20214;&#26639;&#25110;&#31383;&#21475;&#65292;&#25171;&#26029;&#26082;&#26377;&#30340;&#20132;&#20114;&#33410;&#22863;&#12290;</p><p><a href="https://x.com/krzyzanowskim">Marcin Krzy&#380;anowski</a> &#24320;&#21457;&#30340; macOS &#21407;&#29983;&#24212;&#29992; Commander &#32473;&#20102;&#25105;&#19968;&#20010;&#26032;&#30340;&#36873;&#25321;&#12290;&#23427;&#25552;&#20379;&#20102;&#19968;&#20010;&#27604;&#32456;&#31471;&#26356;&#20248;&#30340;&#20132;&#20114;&#30028;&#38754;&#65292;&#21516;&#26102;&#20445;&#25252;&#20102;&#25105;&#30340;&#8220;&#24515;&#27969;&#8221;&#8212;&#8212;&#25991;&#20214;&#21482;&#22312;&#38656;&#35201;&#26102;&#25165;&#24320;&#21551;&#65292;&#24182;&#33021;&#35843;&#29992;&#31995;&#32479;&#40664;&#35748;&#24212;&#29992;&#26597;&#30475;&#12290;Commander &#30446;&#21069;&#25903;&#25345; Claude Code &#21644; Codex&#65292;&#20869;&#32622;&#20102; Git worktrees &#21644; Code diff &#25903;&#25345;&#65292;&#19988;&#23436;&#20840;&#20813;&#36153;&#12290;&#23427;&#22312;&#32456;&#31471;&#30340;&#8220;&#19987;&#27880;&#8221;&#19982; VSCode &#30340;&#8220;&#28789;&#27963;&#8221;&#20043;&#38388;&#65292;&#26500;&#24314;&#20102;&#19968;&#20010;&#32477;&#20339;&#30340;&#20013;&#38388;&#22320;&#24102;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0120-09">Oh My Agents: &#32479;&#19968;&#31649;&#29702;&#25152;&#26377; AI &#32534;&#31243;&#21161;&#25163;&#30340;&#37197;&#32622;</a></strong></h3><p>&#38543;&#30528; Claude Code&#12289;Cursor&#12289;Codex&#12289;Windsurf &#31561; AI &#32534;&#31243;&#21161;&#25163;&#30340;&#28044;&#29616;&#65292;&#24320;&#21457;&#32773;&#38754;&#20020;&#30528;&#19968;&#20010;&#26032;&#38382;&#39064;&#65306;&#22914;&#20309;&#31649;&#29702;&#25955;&#33853;&#22312;&#21508;&#20010;&#39033;&#30446;&#20013;&#30340; prompts&#12289;skills &#21644; rules? &#27599;&#20010; Agent &#37117;&#26377;&#33258;&#24049;&#30340;&#37197;&#32622;&#35268;&#33539;(<code>CLAUDE.md</code>&#12289;<code>CURSOR.md</code>...)&#65292;&#25163;&#21160;&#22797;&#21046;&#31896;&#36148;&#19981;&#20165;&#20302;&#25928;&#65292;&#36824;&#23481;&#26131;&#23548;&#33268;&#29256;&#26412;&#28151;&#20081;&#12290;<a href="https://x.com/onevcat">&#29579;&#24013;(onevcat)</a> &#24320;&#21457;&#30340; Oh My Agents &#25552;&#20379;&#20102;&#35299;&#20915;&#26041;&#26696;&#12290;</p><p>&#26680;&#24515;&#21151;&#33021;:</p><ul><li><p>&#38598;&#20013;&#31649;&#29702;&#25152;&#26377; AI Agent &#37197;&#32622;</p></li><li><p>&#23450;&#20041;&#20998;&#21457;&#35268;&#21017;&#65292;&#19968;&#38190;&#21516;&#27493;&#21040;&#22810;&#20010;&#39033;&#30446;</p></li><li><p>&#21452;&#21521;&#21516;&#27493;&#65292;&#39033;&#30446;&#25913;&#36827;&#21487;&#25289;&#22238;&#20013;&#22830;&#24211;&#24182;&#26356;&#26032;&#25152;&#26377;&#20851;&#32852;&#39033;&#30446;</p></li><li><p>&#39044;&#35272;&#21464;&#26356;&#65292;&#36991;&#20813;&#24847;&#22806;&#35206;&#30422;</p></li></ul><p>&#27880;&#65306;&#30446;&#21069;&#20165;&#25903;&#25345; macOS (Windows/Linux &#24320;&#21457;&#20013;)&#65292;Beta &#26399;&#38388;&#20813;&#36153;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #119]]></title><description><![CDATA[Building AI Moats: Anthropic&#8217;s Crackdown and the Apple-Google Alliance]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-119</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-119</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 19 Jan 2026 12:01:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!MyUF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MyUF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MyUF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 424w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 848w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 1272w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MyUF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp" width="1398" height="703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:703,&quot;width&quot;:1398,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92066,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/184936926?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MyUF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 424w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 848w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 1272w, https://substackcdn.com/image/fetch/$s_!MyUF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48f68e7c-f3f2-42c8-ae0f-318c64203adb_1398x703.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Building AI Moats: Anthropic&#8217;s Crackdown and the Apple-Google Alliance</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-119/">Read on web &#8594;</a></p><p>As 2026 begins, the AI world has already been hit with two blockbuster announcements.</p><p>First, Anthropic took drastic measures to ban third-party command-line interfaces (CLIs) and &#8220;wrapper&#8221; software from accessing personal Claude subscription accounts (Pro/Max). The official intent is clear: to plug the loophole where users were arbitraging low-cost subscriptions against high-value API usage, and to consolidate this efficient coding experience into an exclusive moat for their official tool, Claude Code.</p><p>Close on its heels, Apple officially confirmed a deep partnership with Google. Gemini serves as the cornerstone for Siri and Apple Intelligence, handling backend reasoning and logic. This signifies that in Apple&#8217;s AI landscape, Google has secured its status as &#8220;infrastructure&#8221;&#8212;thanks to its profound accumulation of cloud computing and TPU computing power&#8212;while OpenAI&#8217;s role has been repositioned as an optional &#8220;premium add-on.&#8221;</p><p>These two seemingly unrelated events reveal a significant trend for the AI industry in 2026: as the marginal returns on model capability diminish, raw &#8220;intelligence&#8221; is no longer the sole barrier to entry. Companies are now aggressively constructing their own differentiated moats.</p><p>Anthropic has chosen &#8220;vertical integration&#8221;, cementing model capabilities into an irreplaceable workflow experience by tightly bundling Claude Code with its subscription plans. Google, on the other hand, has won through &#8220;economies of scale&#8221;, leveraging the extreme cost control and stability of its TPU clusters to secure a ticket to Apple&#8217;s billion-user ecosystem.</p><p>In 2025, we were still frequently switching subscriptions based on &#8220;which model is smarter.&#8221; While each service had its merits, they were highly substitutable. Entering 2026, the window for this kind of &#8220;homogeneous competition&#8221; is rapidly closing.</p><p>In the cash-burning race of AI, time is running out for the &#8220;good but mediocre&#8221; middle ground. Whether you possess extreme cost advantages (like Google) or an exclusive, killer workflow (like Anthropic), you must possess a &#8220;trait&#8221; that competitors cannot easily replicate.</p><p>I currently subscribe to four different AI services. I believe that before the year is out, retaining just two will likely suffice for all my needs.</p><p>The main theme of 2026 will no longer be the numbers game of benchmark leaderboards. Instead, it will be about providing a compelling reason for existence that truly resonates with both business and consumer users&#8212;whether through price barriers or ultimate user experiences.</p><p><a href="https://fatbobman.com/en/weekly/issue-118/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-tuist-substack">AI moves fast. So should your builds</a></strong></h3><p>With build caching, selective testing, and actionable insights, your builds, test runs, and CI workflows fly, so your agents get faster feedback and more reliable results.</p><p><strong><a href="https://l.fatbobman.com/sb-tuist-substack">See it in action &#8594;</a></strong></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/surviving-tvos/?utm_source=fatbobman%20weekly%20issue%20119&amp;utm_medium=web">Surviving tvOS: An Engineering Log of an Atypical Media Player</a></strong></h3><p>Within Apple&#8217;s vast hardware ecosystem, Apple TV often occupies a somewhat awkward position: it possesses a stable and loyal user base in the living room context, yet it is rarely a priority target for most developers, with the uncertainty of investment versus return deterring many. <a href="https://x.com/llqoli">Ronnie Wong</a> uses an atypical media player as an entry point to review her real-world experiences during tvOS development&#8212;ranging from platform limitations and interaction differences to engineering trade-offs and compromises. This article does not attempt to glamorize tvOS, but rather honestly presents how a developer can make rational choices and &#8220;survive&#8221; under realistic conditions on this &#8220;niche but unique&#8221; platform.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-01">@_exported import vs. public import</a></strong></h3><p>Swift 6 introduced an inconspicuous yet profound new feature: <a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md">Access-level modifiers on import declarations</a>. This proposal requires developers to explicitly declare access levels when using <code>import</code> to reduce accidental dependency leaks and avoid &#8220;silent pollution&#8221; of module interfaces. In this article, <a href="https://x.com/_al_we">Alexander Wei&#223;</a> systematically explains the design intent and usage caveats of this mechanism, focusing on the practical differences between <code>public import</code> and <code>@_exported import</code> in terms of module interface exposure, dependency transitivity, and API design. He explains why the former often does not achieve the &#8220;re-export&#8221; effect that developers intuitively expect. This has strong practical significance for developers who are building SDKs, Swift Packages, or wishing to clarify module boundaries.</p><blockquote><p>After reading this article, I enabled <code>InternalImportsByDefault</code> in my current project and some third-party libraries, and was immediately greeted by a batch of compilation errors, somewhat reliving the experience of first encountering strict concurrency. However, compared to concurrency-related issues, these errors are usually more intuitive and easier to fix. I suggest you turn this setting on as early as possible to avoid facing larger-scale migration costs when it becomes the official default in the future.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-02">Universal Links At Scale: The Challenges Nobody Talks About</a></strong></h3><p>The principles and implementation of Universal Links are not complex in themselves, which often gives the illusion of them being &#8220;simple and elegant.&#8221; However, once introduced into real-world scenarios involving large-scale applications, multiple domains, complex routing, and long-term evolution, the complexity reveals itself rapidly. In this article, <a href="https://x.com/albertodebo">Alberto De Bortoli</a> combines his practical experience in large projects to systematically outline the issues often overlooked when using Universal Links at scale: the maintenance cost of AASA files, the uncertainty of caching and activation timing, risks under multi-environment and multi-team collaboration, and the reality that there is almost no &#8220;safety net&#8221; for debugging and rollback. Alberto reminds developers that when designing deep link solutions, they must prepare for &#8220;scale effects&#8221; in advance.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-03">Swift Modules and Code/Assets Duplication</a></strong></h3><p>As Swift modularization deepens, resource (CodeAssets) management has gradually become an area that is easily overlooked but can cause actual problems in large-scale projects. <a href="https://x.com/pfandrade_">Paulo Andrade</a> analyzes the problem of duplicate packaging and volume inflation caused by Swift modules and CodeAssets in multi-module dependency scenarios through specific examples. He explains the underlying build and linking mechanisms and discusses feasible avoidance strategies under the current toolchain. Paulo reminds developers: modularization is not just about the design of APIs and dependency relationships; the boundaries and ownership of resources need to be treated just as seriously.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-04">Crafting document-based apps in SwiftUI</a></strong></h3><p>Document-Based Apps are a form of application that is both common yet whose complexity is often underestimated. Compared to ordinary applications, their file lifecycle management, permissions and security scopes, and synergy with the system document browsing experience are unfamiliar to many developers. In this article, <a href="https://www.linkedin.com/in/fonztara/">Alfonso Tarallo</a> uses SwiftUI as the core to systematically outline the key components required to build document-based apps, including the division of responsibilities between <code>FileDocument</code> and <code>DocumentGroup</code>, and how SwiftUI works in synergy with system file mechanisms.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-05">State of Swift 2026</a></strong></h3><p>This is a deep observation and trend analysis surrounding the Swift ecosystem. The article defines 2025 as a &#8220;year of transformation&#8221; for Swift, detailing the evolutionary path of the concurrency model from &#8220;strict&#8221; to &#8220;approachable,&#8221; as well as substantial breakthroughs in server-side (such as the Apple Password Service migration case) and Android development. The author does not shy away from community controversies regarding the architecture of SwiftUI versus AppKit, but objectively analyzes the opportunities and challenges within. Rather than a simple technical list, this article serves more as a strategic report, helping developers see the macro picture of Swift&#8217;s metamorphosis from a single &#8220;App language&#8221; to an all-scenario safe language, beyond daily technical details.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0119-07">Axiom: Claude Code Agents for iOS Development</a></strong></h3><p>Axiom is a knowledge system of Claude Code Agents and Skills for iOS developers maintained by <a href="https://bsky.app/profile/wiltgen.net">Charles Wiltgen</a>. It systematically organizes development tasks, troubleshooting processes, and best practices that recur in real-world projects into reusable Skills, Agents, and Commands. It covers multiple directions including Swift 6, SwiftUI, concurrency, data persistence, debugging, accessibility, and Apple Intelligence.</p><p>Axiom attempts to answer another question: How to systematically entrust experienced engineering judgment to AI assistants. The author also encourages users to exchange practical experiences and feedback in the <a href="https://www.reddit.com/r/axiomdev/">axiomdev subreddit</a>.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-08">BibTeXKit: Type-Safe BibTeX Parsing Library</a></strong></h3><p>BibTeX files are a text-based bibliographic database format widely used in the LaTeX document system to manage references. By maintaining independent <code>.bib</code> files, users can centrally store and reuse citation metadata, with tools automatically handling citation and formatting during the typesetting stage.</p><p>BibTeXKit, developed by <a href="https://www.linkedin.com/in/ezefranca/">Ezequiel Santos</a>, is a BibTeX parsing and modeling library written in Swift with a clear objective: to provide a set of type-safe, scalable BibTeX processing capabilities for Swift projects. It maps entries, fields, and citation relationships in BibTeX files to clear Swift data structures, avoiding the complexity of staying at the string level for repeated parsing and manual processing. It is well-suited as a foundational component for bibliography management tools or research-oriented applications.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-09">MirageKit: High-Performance Streaming and Remote Control Framework for Apple Platforms</a></strong></h3><p>MirageKit is a streaming framework dedicated to Apple platforms developed by <a href="https://x.com/EthanLipnik">Ethan Lipnik</a>, aimed at achieving low-latency screen casting and control from macOS to iOS, visionOS, or another Mac.</p><p>The framework fully utilizes Apple&#8217;s latest system features (requires iOS 26+ / macOS 26+), with a core built on ScreenCaptureKit and Metal. It uses UDP for video streaming and supports AWDL peer-to-peer connections, achieving extremely low latency while ensuring image quality (supports 1:1 virtual display pixel-perfect rendering). Beyond simple screen transmission, MirageKit also enables input reverse control, supporting the forwarding of client-side mouse, keyboard, gestures, and even native menu bar interactions back to the host. For developers looking to build high-performance remote desktops, secondary screen apps, or Vision Pro productivity tools, this is a solution with significant potential.</p><p>Please note that MirageKit is still in an <strong>early and active stage of development</strong>, and breaking changes to the API may occur. The video shown in the <a href="https://x.com/EthanLipnik/status/2012298013558063499">tweet</a> is a demonstration of an application Ethan is building based on MirageKit, which is also still under development.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-119?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-119?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#20174; Anthropic &#23553;&#26432;&#19982;&#33529;&#26524;&#35895;&#27468;&#32467;&#30431;&#65292;&#30475; AI &#25252;&#22478;&#27827;&#30340;&#26500;&#24314;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-119/">&#32593;&#39029;&#29256;</a></strong></p><p>2026 &#24180;&#20234;&#22987;&#65292;AI &#30028;&#20415;&#36814;&#26469;&#20102;&#20004;&#35760;&#37325;&#30917;&#28040;&#24687;&#12290;</p><p>&#39318;&#20808;&#26159; Anthropic &#30171;&#19979;&#26432;&#25163;&#65292;&#31105;&#27490;&#31532;&#19977;&#26041;&#21629;&#20196;&#34892;&#24037;&#20855;&#65288;CLI&#65289;&#21644;&#8220;&#22871;&#22771;&#8221;&#36719;&#20214;&#35843;&#29992; Claude &#30340;&#20010;&#20154;&#35746;&#38405;&#36134;&#21495;&#65288;Pro/Max&#65289;&#12290;&#23448;&#26041;&#24847;&#22270;&#38750;&#24120;&#26126;&#26174;&#65306;&#22581;&#20303;&#21033;&#29992;&#20302;&#20215;&#35746;&#38405;&#8220;&#34181;&#8221;&#39640;&#20215; API &#32650;&#27611;&#30340;&#28431;&#27934;&#65292;&#24182;&#23558;&#36825;&#31181;&#39640;&#25928;&#30340;&#32534;&#30721;&#20307;&#39564;&#25910;&#24402;&#20026;&#23448;&#26041;&#24037;&#20855; Claude Code &#30340;&#19987;&#23646;&#25252;&#22478;&#27827;&#12290;</p><p>&#32039;&#25509;&#30528;&#65292;&#33529;&#26524;&#27491;&#24335;&#30830;&#35748;&#19982;&#35895;&#27468;&#36798;&#25104;&#28145;&#24230;&#21512;&#20316;&#12290;Gemini &#23558;&#25104;&#20026; Siri &#21450; Apple Intelligence &#21518;&#31471;&#25512;&#29702;&#12289;&#36923;&#36753;&#22788;&#29702;&#30340;&#20027;&#21147;&#22522;&#30707;&#12290;&#36825;&#24847;&#21619;&#30528;&#65292;&#22312;&#33529;&#26524;&#30340; AI &#29256;&#22270;&#20013;&#65292;&#35895;&#27468;&#20973;&#20511;&#20854;&#22312;&#20113;&#35745;&#31639;&#21644; TPU &#31639;&#21147;&#19978;&#30340;&#28145;&#21402;&#31215;&#32047;&#25104;&#20026;&#20102;&#8220;&#22522;&#30784;&#35774;&#26045;&#8221;&#65292;&#32780; OpenAI &#30340;&#35282;&#33394;&#21017;&#34987;&#37325;&#26032;&#23450;&#20301;&#20026;&#21487;&#36873;&#30340;&#8220;&#39640;&#32423;&#25554;&#20214;&#8221;&#12290;</p><p>&#36825;&#20004;&#20010;&#30475;&#20284;&#29420;&#31435;&#30340;&#26032;&#38395;&#65292;&#25581;&#31034;&#20102; 2026 &#24180; AI &#34892;&#19994;&#30340;&#19968;&#20010;&#26174;&#33879;&#36235;&#21183;&#65306;&#38543;&#30528;&#22823;&#27169;&#22411;&#33021;&#21147;&#30340;&#36793;&#38469;&#25928;&#24212;&#36882;&#20943;&#65292;&#21333;&#32431;&#30340;&#8220;&#26234;&#21147;&#8221;&#24050;&#19981;&#20877;&#26159;&#21807;&#19968;&#30340;&#22721;&#22418;&#65292;&#21508;&#23478;&#20844;&#21496;&#27491;&#22312;&#30127;&#29378;&#26500;&#24314;&#23646;&#20110;&#33258;&#24049;&#30340;&#24046;&#24322;&#21270;&#25252;&#22478;&#27827;&#12290;</p><p>Anthropic &#36873;&#25321;&#20102;&#8220;&#22402;&#30452;&#25972;&#21512;&#8221;&#65292;&#36890;&#36807;&#24378;&#32465;&#23450; Claude Code &#19982;&#35746;&#38405;&#35745;&#21010;&#65292;&#23558;&#27169;&#22411;&#33021;&#21147;&#22266;&#21270;&#20026;&#19981;&#21487;&#26367;&#20195;&#30340;&#24037;&#20316;&#27969;&#20307;&#39564;&#65307;&#32780;&#35895;&#27468;&#21017;&#36194;&#22312;&#20102;&#8220;&#35268;&#27169;&#25928;&#24212;&#8221;&#65292;&#20973;&#20511; TPU &#38598;&#32676;&#24102;&#26469;&#30340;&#26497;&#33268;&#25104;&#26412;&#25511;&#21046;&#21644;&#31283;&#23450;&#24615;&#65292;&#25343;&#19979;&#20102;&#33529;&#26524;&#36825;&#24352;&#36890;&#24448;&#21313;&#20159;&#29992;&#25143;&#30340;&#33337;&#31080;&#12290;</p><p>2025 &#24180;&#65292;&#25105;&#20204;&#36824;&#22312;&#20026;&#8220;&#21738;&#20010;&#27169;&#22411;&#26356;&#32874;&#26126;&#8221;&#32780;&#39057;&#32321;&#20999;&#25442;&#35746;&#38405;&#65292;&#21508;&#23478;&#26381;&#21153;&#34429;&#21508;&#26377;&#21315;&#31179;&#65292;&#20294;&#21487;&#26367;&#20195;&#24615;&#24378;&#12290;&#36827;&#20837; 2026 &#24180;&#65292;&#36825;&#31181;&#8220;&#21516;&#36136;&#21270;&#31454;&#20105;&#8221;&#30340;&#31383;&#21475;&#26399;&#24050;&#20020;&#36817;&#20851;&#38381;&#12290;</p><p>&#22312;&#28903;&#38065;&#22914;&#27969;&#27700;&#30340; AI &#36187;&#36947;&#65292;&#30041;&#32473;&#8220;&#19981;&#38169;&#20294;&#24179;&#24248;&#8221;&#30340;&#20013;&#38388;&#27966;&#30340;&#26102;&#38388;&#24050;&#32463;&#19981;&#22810;&#20102;&#12290;&#26080;&#35770;&#20320;&#26159;&#25317;&#26377;&#26497;&#33268;&#30340;&#25104;&#26412;&#20248;&#21183;&#65288;&#22914; Google&#65289;&#65292;&#36824;&#26159;&#25317;&#26377;&#29420;&#21344;&#30340;&#26432;&#25163;&#32423;&#24037;&#20316;&#27969;&#65288;&#22914; Anthropic&#65289;&#65292;&#20320;&#24517;&#39035;&#20855;&#22791;&#19968;&#20010;&#31454;&#20105;&#23545;&#25163;&#26080;&#27861;&#36731;&#26131;&#22797;&#21046;&#30340;&#8220;&#29305;&#36136;&#8221;&#12290;</p><p>&#25105;&#30446;&#21069;&#20173;&#26377; 4 &#20010;&#19981;&#21516;&#30340; AI &#26381;&#21153;&#35746;&#38405;&#65292;&#25105;&#30456;&#20449;&#19981;&#29992;&#21040;&#24180;&#24213;&#65292;&#30041; 2 &#20010;&#35746;&#38405;&#25110;&#35768;&#23601;&#33021;&#28385;&#36275;&#25105;&#30340;&#20840;&#37096;&#38656;&#27714;&#12290;</p><p>2026 &#24180;&#30340;&#20027;&#36724;&#23558;&#19981;&#20877;&#26159;&#36305;&#20998;&#27036;&#19978;&#30340;&#25968;&#23383;&#28216;&#25103;&#65292;&#32780;&#26159;&#36890;&#36807;&#20215;&#26684;&#22721;&#22418;&#25110;&#26497;&#33268;&#20307;&#39564;&#65292;&#25552;&#20379;&#20999;&#23454;&#25171;&#21160; B &#31471;&#19982; C &#31471;&#30340;&#29983;&#23384;&#29702;&#30001;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-118/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div><hr></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-tuist-substack">AI &#36895;&#24230;&#24555;&#65292;&#20320;&#30340;&#26500;&#24314;&#20063;&#24212;&#22914;&#27492;</a></strong></h3><p>&#36890;&#36807;&#26500;&#24314;&#32531;&#23384;&#12289;&#36873;&#25321;&#24615;&#27979;&#35797;&#20197;&#21450;&#21487;&#25805;&#20316;&#30340;&#27934;&#23519;&#65292;&#35753;&#20320;&#30340;&#26500;&#24314;&#12289;&#27979;&#35797;&#36816;&#34892;&#21644; CI &#24037;&#20316;&#27969;&#39134;&#36895;&#36816;&#36716;&#65292;&#35753;&#20320;&#30340; AI &#20195;&#29702;&#33719;&#24471;&#26356;&#24555;&#30340;&#21453;&#39304;&#21644;&#26356;&#21487;&#38752;&#30340;&#32467;&#26524;&#12290;</p><p><strong><a href="https://l.fatbobman.com/sb-tuist-substack">&#31435;&#21363;&#20307;&#39564; &#8594;</a></strong></p><div><hr></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/surviving-tvos/?utm_source=fatbobman%20weekly%20issue%20119&amp;utm_medium=web">&#22312; tvOS &#19978;&#27963;&#19979;&#20358;&#65306;&#19968;&#20491;&#38750;&#20856;&#22411;&#25773;&#25918;&#22120;&#30340;&#24037;&#31243;&#23526;&#37636;</a></strong></h3><p>&#22312;&#33529;&#26524;&#24222;&#22823;&#30340;&#30828;&#20214;&#29983;&#24577;&#20013;&#65292;Apple TV &#24448;&#24448;&#22788;&#20110;&#19968;&#20010;&#30053;&#26174;&#23604;&#23596;&#30340;&#20301;&#32622;&#65306;&#23427;&#22312;&#23458;&#21381;&#22330;&#26223;&#20013;&#25317;&#26377;&#31283;&#23450;&#19988;&#24544;&#23454;&#30340;&#29992;&#25143;&#32676;&#65292;&#21364;&#22987;&#32456;&#19981;&#26159;&#22810;&#25968;&#24320;&#21457;&#32773;&#30340;&#20248;&#20808;&#30446;&#26631;&#65292;&#25237;&#20837;&#19982;&#22238;&#25253;&#30340;&#19981;&#30830;&#23450;&#24615;&#20063;&#35753;&#19981;&#23569;&#20154;&#26395;&#32780;&#21364;&#27493;&#12290;<a href="https://x.com/llqoli">Ronnie Wong</a> &#20197;&#19968;&#27454;&#38750;&#20856;&#22411;&#25773;&#25918;&#22120;&#20026;&#20999;&#20837;&#28857;&#65292;&#22238;&#39038;&#20102;&#22905;&#22312; tvOS &#24320;&#21457;&#36807;&#31243;&#20013;&#30340;&#30495;&#23454;&#32463;&#21382;&#8212;&#8212;&#20174;&#24179;&#21488;&#38480;&#21046;&#12289;&#20132;&#20114;&#24046;&#24322;&#65292;&#21040;&#24037;&#31243;&#21462;&#33293;&#19982;&#22949;&#21327;&#12290;&#36825;&#31687;&#25991;&#31456;&#36825;&#31687;&#25991;&#31456;&#27809;&#26377;&#35797;&#22270;&#31881;&#39280; tvOS &#24320;&#21457;&#30340;&#30171;&#28857;&#65292;&#32780;&#26159;&#22914;&#23454;&#21576;&#29616;&#20102;&#22312;&#36825;&#19968;&#8220;&#23567;&#20247;&#20294;&#29420;&#29305;&#8221;&#30340;&#24179;&#21488;&#19978;&#65292;&#24320;&#21457;&#32773;&#22914;&#20309;&#22312;&#29616;&#23454;&#26465;&#20214;&#20013;&#20570;&#20986;&#29702;&#24615;&#36873;&#25321;&#24182;&#8220;&#27963;&#19979;&#26469;&#8221;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-01">@_exported import vs. public import</a></strong></h3><p>Swift 6 &#24341;&#20837;&#20102;&#19968;&#20010;&#24182;&#19981;&#26174;&#30524;&#12289;&#21364;&#24433;&#21709;&#28145;&#36828;&#30340;&#26032;&#29305;&#24615;&#65306;<a href="https://github.com/swiftlang/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md">Access-level modifiers on import declarations</a>&#12290;&#35813;&#25552;&#26696;&#35201;&#27714;&#24320;&#21457;&#32773;&#22312;&#20351;&#29992; <code>import</code> &#26102;&#26174;&#24335;&#22768;&#26126;&#35775;&#38382;&#32423;&#21035;&#65292;&#20197;&#20943;&#23569;&#20381;&#36182;&#26080;&#24847;&#22806;&#27844;&#12289;&#36991;&#20813;&#27169;&#22359;&#25509;&#21475;&#34987;&#8220;&#24708;&#28982;&#27745;&#26579;&#8221;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/_al_we">Alexander Wei&#223;</a> &#31995;&#32479;&#35762;&#35299;&#20102;&#36825;&#19968;&#26426;&#21046;&#30340;&#35774;&#35745;&#21021;&#34935;&#19982;&#20351;&#29992;&#27880;&#24847;&#20107;&#39033;&#65292;&#24182;&#37325;&#28857;&#23545;&#27604;&#20102; <code>public import</code> &#19982; <code>@_exported import</code> &#22312;&#27169;&#22359;&#25509;&#21475;&#26292;&#38706;&#12289;&#20381;&#36182;&#20256;&#36882;&#20197;&#21450; API &#35774;&#35745;&#23618;&#38754;&#30340;&#23454;&#38469;&#24046;&#24322;&#65292;&#35299;&#37322;&#20102;&#20026;&#20160;&#20040;&#21069;&#32773;&#24448;&#24448;&#24182;&#19981;&#33021;&#23454;&#29616;&#24320;&#21457;&#32773;&#30452;&#35273;&#20013;&#30340;&#8220;&#37325;&#23548;&#20986;&#8221;&#25928;&#26524;&#12290;&#36825;&#23545;&#20110;&#27491;&#22312;&#26500;&#24314; SDK&#12289;Swift Package&#65292;&#25110;&#24076;&#26395;&#26126;&#30830;&#27169;&#22359;&#36793;&#30028;&#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#20855;&#26377;&#24456;&#24378;&#30340;&#29616;&#23454;&#25351;&#23548;&#24847;&#20041;&#12290;</p><blockquote><p>&#25105;&#22312;&#35835;&#23436;&#36825;&#31687;&#25991;&#31456;&#21518;&#65292;&#24050;&#32463;&#22312;&#24403;&#21069;&#39033;&#30446;&#20197;&#21450;&#37096;&#20998;&#31532;&#19977;&#26041;&#24211;&#20013;&#21551;&#29992;&#20102; <code>InternalImportsByDefault</code>&#65292;&#24182;&#31435;&#21051;&#36814;&#26469;&#20102;&#19968;&#25209;&#32534;&#35793;&#38169;&#35823;&#65292;&#22810;&#23569;&#37325;&#28201;&#20102;&#21018;&#25509;&#35302;&#20005;&#26684;&#24182;&#21457;&#26102;&#30340;&#20307;&#39564;&#12290;&#19981;&#36807;&#65292;&#30456;&#27604;&#24182;&#21457;&#30456;&#20851;&#30340;&#38382;&#39064;&#65292;&#36825;&#31867;&#38169;&#35823;&#36890;&#24120;&#26356;&#30452;&#35266;&#12289;&#20063;&#26356;&#23481;&#26131;&#20462;&#22797;&#12290;&#24314;&#35758;&#20320;&#23613;&#26089;&#24320;&#21551;&#36825;&#19968;&#35774;&#32622;&#65292;&#20197;&#36991;&#20813;&#22312;&#26410;&#26469;&#23448;&#26041;&#40664;&#35748;&#21551;&#29992;&#26102;&#65292;&#38598;&#20013;&#38754;&#23545;&#26356;&#22823;&#35268;&#27169;&#30340;&#36801;&#31227;&#25104;&#26412;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-02">Universal Links at Scale&#65306;&#37027;&#20123;&#40092;&#26377;&#20154;&#25552;&#21450;&#30340;&#35268;&#27169;&#21270;&#25361;&#25112; (Universal Links At Scale: The Challenges Nobody Talks About)</a></strong></h3><p>Universal Links &#30340;&#21407;&#29702;&#21644;&#23454;&#29616;&#26412;&#36523;&#24182;&#19981;&#22797;&#26434;&#65292;&#20063;&#22240;&#27492;&#24120;&#24120;&#32473;&#20154;&#19968;&#31181;&#8220;&#31616;&#21333;&#32780;&#20248;&#38597;&#8221;&#30340;&#38169;&#35273;&#12290;&#20294;&#19968;&#26086;&#36827;&#20837;&#22823;&#35268;&#27169;&#24212;&#29992;&#12289;&#22810;&#20010;&#22495;&#21517;&#12289;&#22797;&#26434;&#36335;&#30001;&#21644;&#38271;&#26399;&#28436;&#36827;&#30340;&#30495;&#23454;&#22330;&#26223;&#65292;&#20854;&#22797;&#26434;&#24230;&#20250;&#36805;&#36895;&#26174;&#29616;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/albertodebo">Alberto De Bortoli</a> &#32467;&#21512;&#33258;&#36523;&#22312;&#22823;&#22411;&#39033;&#30446;&#20013;&#30340;&#23454;&#36341;&#32463;&#39564;&#65292;&#31995;&#32479;&#26803;&#29702;&#20102; Universal Links &#22312;&#35268;&#27169;&#21270;&#20351;&#29992;&#26102;&#24120;&#34987;&#24573;&#35270;&#30340;&#38382;&#39064;&#65306;AASA &#25991;&#20214;&#30340;&#32500;&#25252;&#25104;&#26412;&#12289;&#32531;&#23384;&#19982;&#29983;&#25928;&#26102;&#26426;&#30340;&#19981;&#30830;&#23450;&#24615;&#12289;&#22810;&#29615;&#22659;&#19982;&#22810;&#22242;&#38431;&#21327;&#20316;&#19979;&#30340;&#39118;&#38505;&#65292;&#20197;&#21450;&#35843;&#35797;&#19982;&#22238;&#28378;&#20960;&#20046;&#27809;&#26377;&#8220;&#23433;&#20840;&#32593;&#8221;&#30340;&#29616;&#23454;&#22256;&#22659;&#12290;Alberto &#25552;&#37266;&#24320;&#21457;&#32773;&#22312;&#35774;&#35745;&#28145;&#24230;&#38142;&#25509;&#26041;&#26696;&#26102;&#65292;&#24517;&#39035;&#25552;&#21069;&#20026;&#8220;&#35268;&#27169;&#25928;&#24212;&#8221;&#20570;&#22909;&#20934;&#22791;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-03">&#24403;&#27169;&#22359;&#21270;&#36935;&#21040;&#36164;&#28304;&#22797;&#21046;&#38382;&#39064; (Swift Modules and Code/Assets Duplication)</a></strong></h3><p>&#38543;&#30528; Swift &#27169;&#22359;&#21270;&#31243;&#24230;&#30340;&#19981;&#26029;&#21152;&#28145;&#65292;&#36164;&#28304;&#65288;CodeAssets&#65289;&#31649;&#29702;&#36880;&#28176;&#25104;&#20026;&#19968;&#20010;&#23481;&#26131;&#34987;&#24573;&#35270;&#12289;&#21364;&#21487;&#33021;&#22312;&#35268;&#27169;&#21270;&#39033;&#30446;&#20013;&#24341;&#21457;&#23454;&#38469;&#38382;&#39064;&#30340;&#39046;&#22495;&#12290;<a href="https://x.com/pfandrade_">Paulo Andrade</a> &#36890;&#36807;&#20855;&#20307;&#31034;&#20363;&#20998;&#26512;&#20102; Swift &#27169;&#22359;&#19982; CodeAssets &#22312;&#22810;&#27169;&#22359;&#20381;&#36182;&#22330;&#26223;&#19979;&#20135;&#29983;&#37325;&#22797;&#25171;&#21253;&#19982;&#20307;&#31215;&#33192;&#32960;&#30340;&#38382;&#39064;&#65292;&#35299;&#37322;&#20102;&#20854;&#32972;&#21518;&#30340;&#26500;&#24314;&#19982;&#38142;&#25509;&#26426;&#21046;&#65292;&#24182;&#25506;&#35752;&#20102;&#24403;&#21069;&#24037;&#20855;&#38142;&#19979;&#21487;&#34892;&#30340;&#35268;&#36991;&#31574;&#30053;&#12290;Paulo &#25552;&#37266;&#24320;&#21457;&#32773;&#65306;&#27169;&#22359;&#21270;&#24182;&#19981;&#20165;&#20165;&#26159; API &#19982;&#20381;&#36182;&#20851;&#31995;&#30340;&#35774;&#35745;&#65292;&#36164;&#28304;&#30340;&#36793;&#30028;&#19982;&#24402;&#23646;&#21516;&#26679;&#38656;&#35201;&#34987;&#35748;&#30495;&#23545;&#24453;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-04">&#20351;&#29992; SwiftUI &#26500;&#24314;&#25991;&#26723;&#22411;&#24212;&#29992; (Crafting document-based apps in SwiftUI)</a></strong></h3><p>&#25991;&#26723;&#22411;&#24212;&#29992;&#65288;Document-Based App&#65289;&#26159;&#19968;&#20010;&#26082;&#24120;&#35265;&#12289;&#21364;&#24120;&#34987;&#20302;&#20272;&#22797;&#26434;&#24230;&#30340;&#24212;&#29992;&#24418;&#24577;&#12290;&#30456;&#27604;&#26222;&#36890;&#24212;&#29992;&#65292;&#20854;&#25991;&#20214;&#29983;&#21629;&#21608;&#26399;&#31649;&#29702;&#12289;&#26435;&#38480;&#19982;&#23433;&#20840;&#20316;&#29992;&#22495;&#65292;&#20197;&#21450;&#19982;&#31995;&#32479;&#25991;&#26723;&#27983;&#35272;&#20307;&#39564;&#30340;&#21327;&#21516;&#26041;&#24335;&#65292;&#23545;&#19981;&#23569;&#24320;&#21457;&#32773;&#32780;&#35328;&#37117;&#36739;&#20026;&#38476;&#29983;&#12290; &#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://www.linkedin.com/in/fonztara/">Alfonso Tarallo</a> &#20197; SwiftUI &#20026;&#26680;&#24515;&#65292;&#31995;&#32479;&#26803;&#29702;&#20102;&#26500;&#24314;&#25991;&#26723;&#22411;&#24212;&#29992;&#25152;&#38656;&#30340;&#20851;&#38190;&#32452;&#25104;&#37096;&#20998;&#65292;&#21253;&#25324; <code>FileDocument</code>&#12289;<code>DocumentGroup</code> &#30340;&#32844;&#36131;&#21010;&#20998;&#65292;&#20197;&#21450; SwiftUI &#22914;&#20309;&#19982;&#31995;&#32479;&#25991;&#20214;&#26426;&#21046;&#21327;&#21516;&#24037;&#20316;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-05">Swift 2026 &#29983;&#24577;&#29616;&#29366; (State of Swift 2026)</a></strong></h3><p>&#36825;&#26159;&#19968;&#31687;&#22260;&#32469; Swift &#29983;&#24577;&#30340;&#28145;&#24230;&#35266;&#23519;&#19982;&#36235;&#21183;&#30740;&#21028;&#12290;&#25991;&#31456;&#23558; 2025 &#24180;&#23450;&#20041;&#20026; Swift &#30340;&#8220;&#21464;&#38761;&#20043;&#24180;&#8221;&#65292;&#35814;&#32454;&#26803;&#29702;&#20102;&#24182;&#21457;&#27169;&#22411;&#20174;&#8220;&#20005;&#26684;&#8221;&#21521;&#8220;&#24179;&#26131;&#36817;&#20154;&#65288;Approachable&#65289;&#8221;&#30340;&#28436;&#36827;&#36335;&#24452;&#65292;&#20197;&#21450;&#26381;&#21153;&#31471;&#65288;&#22914; Apple &#23494;&#30721;&#26381;&#21153;&#36801;&#31227;&#26696;&#20363;&#65289;&#19982; Android &#24320;&#21457;&#30340;&#23454;&#36136;&#24615;&#31361;&#30772;&#12290;&#20316;&#32773;&#27809;&#26377;&#22238;&#36991;&#31038;&#21306;&#20851;&#20110; SwiftUI &#19982; AppKit &#30340;&#26550;&#26500;&#20105;&#35758;&#65292;&#32780;&#26159;&#23458;&#35266;&#20998;&#26512;&#20102;&#20854;&#20013;&#30340;&#26426;&#36935;&#19982;&#25361;&#25112;&#12290;&#30456;&#27604;&#20110;&#21333;&#32431;&#30340;&#25216;&#26415;&#28165;&#21333;&#65292;&#26412;&#25991;&#26356;&#20687;&#26159;&#19968;&#20221;&#25112;&#30053;&#25253;&#21578;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#22312;&#26085;&#24120;&#20195;&#30721;&#20043;&#22806;&#65292;&#30475;&#28165; Swift &#27491;&#20174;&#21333;&#19968;&#30340;&#8220;App &#35821;&#35328;&#8221;&#21521;&#20840;&#22330;&#26223;&#23433;&#20840;&#35821;&#35328;&#34581;&#21464;&#30340;&#23439;&#35266;&#22270;&#26223;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-06">&#21644; ChaoCode &#19968;&#36215;&#23398; CS146S</a></strong></h3><p><a href="https://themodernsoftware.dev/">CS146S</a> &#26159;&#26031;&#22374;&#31119;&#22823;&#23398;&#24320;&#35774;&#30340;&#19968;&#38376;&#21069;&#27839;&#35745;&#31639;&#26426;&#31185;&#23398;&#35838;&#31243;&#65292;&#20840;&#21517;&#20026; &#8220;CS146S: The Modern Software Developer&#8221;&#12290;&#35813;&#35838;&#31243;&#30340;&#26680;&#24515;&#29702;&#24565;&#22312;&#20110;&#25945;&#23548;&#23398;&#29983;&#21033;&#29992;&#26368;&#26032;&#30340; AI &#24037;&#20855;&#65288;&#22914; LLMs&#12289;Cursor&#12289;Claude &#31561;&#65289;&#23558;&#24320;&#21457;&#25928;&#29575;&#25552;&#21319; 10 &#20493;&#65292;&#20174;&#21333;&#32431;&#30340;&#8220;&#20195;&#30721;&#32534;&#20889;&#32773;&#8221;&#36716;&#21464;&#20026;&#8220;AI &#26234;&#33021;&#20307;&#30340;&#25351;&#25381;&#23448;&#8221;&#12290;</p><p>&#22914;&#26524;&#20320;&#23545;&#36825;&#38376;&#35838;&#31243;&#24863;&#20852;&#36259;&#65292;&#20294;&#38754;&#23545;&#22823;&#37327;&#30340;&#33521;&#25991;&#38405;&#35835;&#26448;&#26009;&#21644;&#32431;&#25991;&#26412; Slides &#24863;&#21040;&#26543;&#29157;&#25110;&#30031;&#38590;&#65292;&#37027;&#20040; <a href="https://x.com/janechao_dev">ChaoCode</a> (Jane) &#21018;&#21018;&#24320;&#21551;&#30340;&#36825;&#20010;&#8220;&#20276;&#35835;&#8221;&#31995;&#21015;&#21487;&#33021;&#27491;&#26159;&#20320;&#38656;&#35201;&#30340;&#12290;Jane &#20197;&#8220;&#35270;&#35273;&#23398;&#20064;&#32773;&#8221;&#30340;&#35270;&#35282;&#65292;&#36890;&#36807;&#35270;&#39057;&#24418;&#24335;&#35760;&#24405;&#24182;&#20998;&#20139;&#20102;&#36825;&#38376;&#35838;&#31243;&#30340;&#23398;&#20064;&#36807;&#31243;&#12290;&#22905;&#19981;&#20165;&#23558;&#21407;&#22987; Slides &#25972;&#29702;&#25104;&#20102;&#32321;&#20307;&#20013;&#25991;/&#33521;&#25991;&#21452;&#35821;&#29256;&#26412;&#65292;&#34917;&#20805;&#20102;&#21407;&#29256;&#32570;&#22833;&#30340;&#35762;&#32773;&#27880;&#37322;&#65292;&#36824;&#19987;&#38376;&#32500;&#25252;&#20102;&#19968;&#20010; <a href="https://chaocode.notion.site/cs146s">Notion &#39029;&#38754;</a> &#26469;&#25972;&#21512;&#25152;&#26377;&#30340;&#23398;&#20064;&#36164;&#28304;&#19982;&#20316;&#19994;&#12290;&#36825;&#19981;&#26159;&#19968;&#20010;&#35838;&#31243;&#25644;&#36816;&#65292;&#32780;&#26159;&#19968;&#20010;&#8220;Learning in Public&#8221;&#30340;&#26368;&#20339;&#23454;&#36341;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0119-07">Axiom&#65306;&#38754;&#21521; iOS &#24320;&#21457;&#30340; Claude Code Agent &#38598;&#21512;</a></strong></h3><p>Axiom &#26159;&#30001; <a href="https://bsky.app/profile/wiltgen.net">Charles Wiltgen</a> &#32500;&#25252;&#30340;&#19968;&#22871;&#38754;&#21521; iOS &#24320;&#21457;&#32773;&#30340; Claude Code Agents &#19982; Skills &#30693;&#35782;&#20307;&#31995;&#12290;&#23427;&#23558;&#22823;&#37327;&#30495;&#23454;&#39033;&#30446;&#20013;&#21453;&#22797;&#20986;&#29616;&#30340;&#24320;&#21457;&#20219;&#21153;&#12289;&#25490;&#38556;&#27969;&#31243;&#19982;&#26368;&#20339;&#23454;&#36341;&#65292;&#31995;&#32479;&#25972;&#29702;&#20026;&#21487;&#22797;&#29992;&#30340; Skills&#12289;Agents &#19982; Commands&#65292;&#35206;&#30422; Swift 6&#12289;SwiftUI&#12289;&#24182;&#21457;&#12289;&#25968;&#25454;&#25345;&#20037;&#21270;&#12289;&#35843;&#35797;&#12289;&#21487;&#35775;&#38382;&#24615;&#20197;&#21450; Apple Intelligence &#31561;&#22810;&#20010;&#26041;&#21521;&#12290;</p><p>Axiom &#23581;&#35797;&#22238;&#31572;&#21478;&#19968;&#20010;&#38382;&#39064;&#65306;&#22914;&#20309;&#25226;&#32463;&#39564;&#20016;&#23500;&#30340;&#24037;&#31243;&#21028;&#26029;&#65292;&#31995;&#32479;&#21270;&#22320;&#20132;&#32473; AI &#21161;&#25163;&#25191;&#34892;&#12290;&#20316;&#32773;&#20063;&#40723;&#21169;&#20351;&#29992;&#32773;&#22312; <a href="https://www.reddit.com/r/axiomdev/">Reddit &#30340; axiomdev &#26495;&#22359;</a> &#20013;&#20132;&#27969;&#23454;&#36341;&#32463;&#39564;&#19982;&#21453;&#39304;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-08">BibTeXKit&#65306;&#31867;&#22411;&#23433;&#20840;&#30340; BibTeX &#35299;&#26512;&#24211;</a></strong></h3><p>BibTeX &#25991;&#20214;&#26159;&#19968;&#31181;&#22522;&#20110;&#25991;&#26412;&#30340;&#25991;&#29486;&#25968;&#25454;&#24211;&#26684;&#24335;&#65292;&#24191;&#27867;&#29992;&#20110; LaTeX &#25991;&#26723;&#20307;&#31995;&#20013;&#31649;&#29702;&#21442;&#32771;&#25991;&#29486;&#12290;&#36890;&#36807;&#32500;&#25252;&#29420;&#31435;&#30340; <code>.bib</code> &#25991;&#20214;&#65292;&#29992;&#25143;&#21487;&#20197;&#38598;&#20013;&#23384;&#20648;&#24182;&#22797;&#29992;&#25991;&#29486;&#30340;&#20803;&#25968;&#25454;&#65292;&#22312;&#25490;&#29256;&#38454;&#27573;&#30001;&#24037;&#20855;&#33258;&#21160;&#23436;&#25104;&#24341;&#29992;&#19982;&#26684;&#24335;&#21270;&#12290;</p><p>&#30001; <a href="https://www.linkedin.com/in/ezefranca/">Ezequiel Santos</a> &#24320;&#21457;&#30340; BibTeXKit &#26159;&#19968;&#20010;&#20351;&#29992; Swift &#32534;&#20889;&#30340; BibTeX &#35299;&#26512;&#19982;&#24314;&#27169;&#24211;&#65292;&#30446;&#26631;&#38750;&#24120;&#26126;&#30830;&#65306;&#20026; Swift &#39033;&#30446;&#25552;&#20379;&#19968;&#22871;&#31867;&#22411;&#23433;&#20840;&#12289;&#21487;&#25193;&#23637;&#30340; BibTeX &#22788;&#29702;&#33021;&#21147;&#12290;&#23427;&#23558; BibTeX &#25991;&#20214;&#20013;&#30340;&#26465;&#30446;&#12289;&#23383;&#27573;&#19982;&#24341;&#29992;&#20851;&#31995;&#26144;&#23556;&#20026;&#28165;&#26224;&#30340; Swift &#25968;&#25454;&#32467;&#26500;&#65292;&#36991;&#20813;&#20102;&#20572;&#30041;&#22312;&#23383;&#31526;&#20018;&#23618;&#38754;&#21453;&#22797;&#35299;&#26512;&#19982;&#25163;&#24037;&#22788;&#29702;&#25152;&#24102;&#26469;&#30340;&#22797;&#26434;&#24615;&#65292;&#26356;&#36866;&#21512;&#20316;&#20026;&#25991;&#29486;&#31649;&#29702;&#31867;&#24037;&#20855;&#25110;&#30740;&#31350;&#22411;&#24212;&#29992;&#30340;&#24213;&#23618;&#32452;&#20214;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0119-09">MirageKit&#65306;Apple &#24179;&#21488;&#39640;&#24615;&#33021;&#25237;&#23631;&#19982;&#36828;&#31243;&#25511;&#21046;&#26694;&#26550;</a></strong></h3><p>MirageKit &#26159;&#19968;&#20010;&#30001; <a href="https://x.com/EthanLipnik">Ethan Lipnik</a> &#24320;&#21457;&#30340; Apple &#24179;&#21488;&#19987;&#29992;&#27969;&#23186;&#20307;&#26694;&#26550;&#65292;&#26088;&#22312;&#23454;&#29616; macOS &#30011;&#38754;&#21521; iOS&#12289;visionOS &#25110;&#21478;&#19968;&#21488; Mac &#30340;&#20302;&#24310;&#36831;&#25237;&#23631;&#19982;&#25511;&#21046;&#12290;</p><p>&#35813;&#26694;&#26550;&#20805;&#20998;&#21033;&#29992;&#20102; Apple &#26368;&#26032;&#30340;&#31995;&#32479;&#29305;&#24615;&#65288;&#38656; iOS 26+ / macOS 26+&#65289;&#65292;&#26680;&#24515;&#22522;&#20110; ScreenCaptureKit &#19982; Metal &#26500;&#24314;&#65292;&#21033;&#29992; UDP &#20256;&#36755;&#35270;&#39057;&#27969;&#24182;&#25903;&#25345; AWDL &#28857;&#23545;&#28857;&#36830;&#25509;&#65292;&#22312;&#20445;&#35777;&#30011;&#36136;&#65288;&#25903;&#25345; 1:1 &#34394;&#25311;&#26174;&#31034;&#22120;&#20687;&#32032;&#32423;&#28210;&#26579;&#65289;&#30340;&#21516;&#26102;&#23454;&#29616;&#20102;&#26497;&#20302;&#30340;&#24310;&#36831;&#12290;&#38500;&#20102;&#21333;&#32431;&#30340;&#30011;&#38754;&#20256;&#36755;&#65292;MirageKit &#36824;&#25171;&#36890;&#20102;&#36755;&#20837;&#21453;&#21521;&#25511;&#21046;&#65292;&#25903;&#25345;&#23558;&#23458;&#25143;&#31471;&#30340;&#38190;&#40736;&#12289;&#25163;&#21183;&#25805;&#20316;&#29978;&#33267;&#21407;&#29983;&#33756;&#21333;&#26639;&#20132;&#20114;&#22238;&#20256;&#33267;&#20027;&#26426;&#12290;&#23545;&#20110;&#24819;&#35201;&#26500;&#24314;&#39640;&#24615;&#33021;&#36828;&#31243;&#26700;&#38754;&#12289;&#21103;&#23631;&#24212;&#29992;&#25110; Vision Pro &#29983;&#20135;&#21147;&#24037;&#20855;&#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20010;&#38750;&#24120;&#26377;&#28508;&#21147;&#30340;&#36215;&#27493;&#26041;&#26696;&#12290;</p><p>&#38656;&#35201;&#27880;&#24847;&#30340;&#26159;&#65292;MirageKit &#30446;&#21069;&#20173;&#22788;&#20110; <strong>&#26089;&#26399;&#19988;&#27963;&#36291;&#30340;&#24320;&#21457;&#38454;&#27573;</strong>&#65292;API &#21487;&#33021;&#20250;&#20986;&#29616;&#30772;&#22351;&#24615;&#21464;&#26356;&#12290;<a href="https://x.com/EthanLipnik/status/2012298013558063499">&#25512;&#25991;</a> &#20013;&#23637;&#31034;&#30340;&#35270;&#39057;&#65292;&#26159; Ethan &#22522;&#20110; MirageKit &#26500;&#24314;&#12289;&#20173;&#22312;&#24320;&#21457;&#20013;&#30340;&#24212;&#29992;&#28436;&#31034;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #118]]></title><description><![CDATA[An AT Life Isn't Necessarily Better Than an MT One]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-118</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-118</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 12 Jan 2026 12:03:07 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!EcSf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EcSf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EcSf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 424w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 848w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 1272w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EcSf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp" width="1456" height="731" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:731,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23838,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/184194748?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!EcSf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 424w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 848w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 1272w, https://substackcdn.com/image/fetch/$s_!EcSf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbab0e24-3d2e-49a5-b220-e6e129526b47_1911x960.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@pinjasaur?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Paul Esch-Laurent</a> on <a href="https://unsplash.com/photos/a-close-up-of-a-cars-dashboard-rrwRGUV4a-0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>An AT Life Isn&#8217;t Necessarily Better Than an MT One</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-118/">Read on web &#8594;</a></p><p>When I learned to drive, I used a manual transmission (MT). At first, my lack of skill often left me flustered, so for my first car, I went straight for an automatic (AT). However, after driving for a few years, I began to crave that sense of total control, so I added a manual car to my collection. Regrettably, as traffic congestion grew worse, the joy of shifting gears was gradually canceled out by exhaustion, and that car eventually sat neglected. It has been nearly twenty years since I seriously drove a manual, but deep down, I still occasionally miss that time when &#8220;man and car were one.&#8221;</p><p>As AI integrates more deeply into my work and life, I feel my existence shifting from MT to AT. Undoubtedly, AI has helped me break through many bottlenecks and brought immense efficiency gains even in familiar fields. But strangely, my sense of wonder about it keeps fading. It seems to have saved me time, yet I haven&#8217;t gained the expected satisfaction from this &#8220;extra time.&#8221; Perhaps my threshold for expectations keeps rising, but the undeniable fact is: I haven&#8217;t experienced that simple joy in the process of learning and developing for quite a while.</p><p>Fortunately, I rediscovered this long-lost happiness a few days ago. While preparing my Keynote for iOS Conf SG, because the app still relies on relatively &#8220;primitive&#8221; construction methods for animation&#8212;and lacks AI features&#8212;I had a rare, uninterrupted block of time to manually experiment and tweak things. Even for a simple parallel animation, I tinkered with great delight, debating between transitions, standard animations, or &#8220;Magic Move.&#8221; Settings that an expert might finalize in two or three minutes took me half a day of tinkering. Although efficiency was non-existent, I enjoyed every moment. Looking at the final, slightly &#8220;crude&#8221; effect I&#8217;d built, I found myself genuinely moved by what I&#8217;d made.</p><p>For professionals, efficiency and completeness are certainly hard metrics. But being able to experience the tangible reality in the process is perhaps a fundamental human pursuit.</p><p>I probably won&#8217;t buy an MT vehicle again, but as long as I can still grip the steering wheel, I won&#8217;t let &#8220;smart driving&#8221; take over completely. The same goes for coding&#8212;I fell in love with it because it brought me pure joy. When all our tools push us to be faster and better, I think we should leave ourselves a bit of space to be slower and &#8220;dumber&#8221;&#8212;after all, an AT life isn&#8217;t necessarily better than an MT one.</p><p><a href="https://fatbobman.com/en/weekly/issue-117/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/running-swift-on-mcu/?utm_source=fatbobman%20weekly%20issue%20118&amp;utm_medium=web">Farewell to Portable Assembly: I&#8217;ve Been Running Swift on MCUs for Seven Years</a></strong></h3><p>Since 2024, Swift has officially provided support for embedded systems, but gaining significant market share in this field still has a long way to go. In fact, as early as 2018, before the official support, <a href="https://x.com/madmachineio">Andy Liu</a> and his <a href="https://madmachine.io/">MadMachine</a> team began exploring and practicing the application of Swift in the embedded field, launching related hardware products along the way. They firmly believe that in increasingly complex development scenarios, Swift&#8217;s modern language features will demonstrate tremendous advantages. In this article, Andy shares his journey of exploration in this field over the past few years. I sincerely hope that Swift can showcase its charm in more scenarios.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-01">Building a Base DialSlider Component in SwiftUI</a></strong></h3><p>In today&#8217;s world where AI capabilities are increasingly powerful, getting AI to help you implement a visual effect has become easier than ever. However, whenever I see developers continuously exploring implementation approaches and refining effects through their own &#8220;creative ingenuity&#8221;, I still find myself genuinely impressed. In this article recreating a &#8220;vintage telephone dial&#8221;, <a href="https://x.com/Codelaby">codelaby</a> cleverly utilizes SwiftUI&#8217;s <code>.compositingGroup()</code> and <code>.blendMode(.destinationOut)</code> to achieve a dynamic &#8220;cutout&#8221; effect, making static numbers beneath the rotating layer clearly visible&#8212;offering more flexibility and native feel compared to simply rotating an image. Additionally, the article provides a thoroughly clear explanation of circular gesture handling, angle calculations (<code>atan2</code>), and stopper logic.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-02">CKSyncEngine Questions and Answers</a></strong></h3><p>Many developers have complained about Core Data&#8217;s <code>NSPersistentCloudKitContainer</code>, finding it opaque and lacking customizability. However, when they actually try to tackle CloudKit data synchronization themselves, they discover there are far more considerations than imagined, with difficulty far exceeding expectations. Apple&#8217;s <a href="https://developer.apple.com/documentation/cloudkit/cksyncengine-5sie5">CKSyncEngine</a>, introduced several years ago, completely broke through this impasse by providing clearer state management and error handling, automatically handling numerous complex edge cases, allowing developers to focus on building data synchronization logic.</p><p><a href="https://x.com/christianselig">Christian Selig</a> shares his experience using the <code>CKSyncEngine</code> API through a Q&amp;A format, detailing how <code>CKSyncEngine</code> serves as a perfect middle layer that retains data storage flexibility (you can continue using SQLite, Realm, or JSON) while taking over the most troublesome synchronization state management.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-03">My Beef with the iOS 26 Tab Bar</a></strong></h3><p>SwiftUI&#8217;s adjustments to the Tab Bar in iOS 18 have had an impact almost comparable to when NavigationStack/NavigationSplitView replaced NavigationView&#8212;not only changing the design language but also having a disruptive effect on application implementation and data flow. The &#8220;search tab&#8221; feature introduced for iOS 26&#8217;s Liquid Glass style further advances this transformation. In this article, <a href="https://mastodon.social/@ryanashcraft">Ryan Ashcraft</a> candidly points out numerous issues with the new Tab Bar design: the default floating style appears jarring in certain interfaces and is difficult to coordinate with the overall visual style of applications; new margin and spacing rules break long-standing design conventions, requiring developers to readjust large amounts of existing interfaces; more importantly, these changes have not significantly improved user experience but instead increased adaptation costs.</p><blockquote><p>My biggest impression of the new Tab is that it will significantly impact developers&#8217; decisions regarding minimum system versions when developing applications. Is it worth maintaining two sets of code for Tab? If simplifying implementation forces raising the minimum version to iOS 18, this might be another design intention of the SwiftUI team.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-04">Dia: A Technical Deep Dive into The Browser Company&#8217;s macOS Browser</a></strong></h3><p>Arc was the first major Windows platform application built using Swift, and The Browser Company has made outstanding contributions to the Swift community&#8217;s Windows toolchain. After transitioning from Arc to Dia, the development team has not abandoned Swift, so what development frameworks does Dia specifically use on macOS?</p><p>In this article, <a href="https://x.com/everettjf">Everett</a> reveals Dia&#8217;s unique technical architecture: this is a native macOS application based on AppKit + SwiftUI, but its core rendering engine is not WebKit&#8212;instead, it embeds a self-modified Chromium (<code>ArcCore</code>). Additionally, a large number of local AI-related libraries (such as Apple MLX and LoRA adapters) were discovered in Dia&#8217;s binary files, indicating that Dia is not just about &#8220;speed&#8221; but has already prepared the underlying engineering for on-device AI inference.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-05">Myths about Logitech Developer ID certificate expiration</a></strong></h3><p>A few days ago, many macOS users discovered that their Logitech mouse custom buttons had stopped working. Due to control console logs being filled with code signing-related errors, many users and media outlets attributed this to &#8220;Apple revoking certificates.&#8221; Through analyzing system logs, <a href="https://mastodon.social/@lapcatsoftware">Jeff Johnson</a> vindicated Apple&#8217;s role in this incident: this was not an Apple certificate service failure, but rather a software engineering issue on Logitech&#8217;s end. After updating, the Logi Options+ background process failed to pass macOS <code>taskgated</code> code signature validity verification and was directly terminated by the system. This article is not only a failure analysis report but also reminds developers: under macOS&#8217;s strict security mechanisms, the signature verification process for application updates cannot tolerate any carelessness.</p><blockquote><p>&#8220;If your certificate expires, users can still download, install, and run versions of your Mac applications that were signed with this certificate. However, you&#8217;ll need a new certificate to sign updates and new applications.&#8221; &#8212; <a href="https://developer.apple.com/support/certificates/">Apple Official Documentation</a></p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-06">Stop Getting Average Code from Your LLM</a></strong></h3><p>Undeniably, in the ocean of information accumulated by humanity over time, high-quality data and information constitute only a minority. For individuals, we can purposefully identify and learn from this quality content. However, due to mechanism limitations, LLMs default to the &#8220;average&#8221; of their training data, causing the content they generate to appear mediocre in various aspects. In the specific context of Swift development, this often means generating large amounts of outdated, unstructured code.</p><p>To obtain high-quality code that conforms to Swift 6 standards or even specific architectural styles, the key is to combat this &#8220;regression to the mean&#8221; instinct. <a href="https://x.com/merowing_">Krzysztof Zab&#322;ocki</a> provides detailed guidance on how to use Few-Shot Prompting and context injection techniques, forcing the LLM to &#8220;forget&#8221; mediocre default settings by providing specific code examples and architectural specifications, instead generating high-quality code that precisely matches project standards.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0118-07">swift-effect: A Type-Driven Approach to Side Effects</a></strong></h3><p><a href="https://x.com/AlexOzun">Alex Ozun</a> has long focused on <a href="https://swiftology.io/collections/type-driven-design/?utm_source=fatbobman%20weekly%20issue%20118&amp;utm_medium=web">type-driven design</a> in Swift, and this library is his practice of &#8220;Algebraic Effects + Effect Handlers&#8221; in Swift.</p><p>swift-effect doesn&#8217;t turn side effects into &#8220;data structures to be interpreted,&#8221; but rather models side effects as interceptable global operations (@Effect), combining and replacing behaviors at runtime through handlers, allowing business code to maintain a linear/procedural style while providing fine-grained control over I/O, concurrency, and other behaviors.</p><p>Core highlights:</p><ul><li><p><strong>Maintains Linear Code</strong>: Calling effects like Console.print works like regular functions, but behavior can be dynamically determined by handlers.</p></li><li><p><strong>Behavior Testing Without Mocks</strong>: Use <code>withTestHandler</code> to intercept/assert effect sequences step by step, testing processes like &#8220;interactive scripts.&#8221;</p></li><li><p><strong>Controllable Concurrency</strong>: Supports deterministic testing of Task/AsyncSequence, solving the problem of unstable concurrency ordering.</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-08">Codex Skill Manager: A macOS Tool for Multiple CLI Services</a></strong></h3><p>Many developers use multiple AI programming services simultaneously. Although they have similar concepts, configurations, and tool types, differences remain in specific settings and detailed descriptions, making it difficult for developers to manage all services uniformly. <a href="https://x.com/Dimillian">Thomas Ricouard</a>&#8216;s Codex Skill Manager consolidates skills from Codex, Claude Code (as well as OpenCode and Copilot) in a single UI for viewing, searching, deleting, and importing, avoiding manual searching through multiple hidden directories.</p><p>Core Features:</p><ul><li><p><strong>Local Skills</strong>: Scans paths like <code>~/.codex/skills/public</code> and <code>~/.claude/skills</code>, displaying lists and details</p></li><li><p><strong>Detail Rendering</strong>: Markdown view + reference preview</p></li><li><p><strong>Remote Skills</strong>: Clawdhub search/latest lists, detail fetching and downloading</p></li><li><p><strong>Import/Delete/Custom Paths</strong>: Supports importing from zip or folders, sidebar deletion, adding custom paths</p></li><li><p><strong>Multi-platform Installation Status</strong>: Marks installation status for different platforms</p></li></ul><h2><strong>Events</strong></h2><h3><strong><a href="https://letsvision.swiftgg.team/">LET&#8217;S VISION 2026</a></strong></h3><p>Born to Create. Powered by AI.</p><ul><li><p>Speakers &#8226; Exhibitors &#8226; Partners &#8212; now open</p></li></ul><ul><li><p>&#128205; Shanghai | March 27&#8211;29, 2026</p></li></ul><p>Apple ecosystem &#183; AI &#183; Spatial Computing See you in Shanghai.</p><p>Let&#8217;s shape the future together.</p><div><hr></div><h3><strong><a href="https://developer.apple.com/swift-student-challenge/?utm_source=fatbobman%20weekly%20issue%20118&amp;utm_medium=web">Swift Student Challenge 2026</a></strong></h3><p>The annual student challenge returns once again. The challenge provides thousands of student developers with the opportunity to showcase their creativity and programming abilities, allowing them to present their work through App Playground and learn practical skills that will serve them throughout their careers.</p><p><strong>This year&#8217;s submission period will be open from February 6 to February 28, 2026.</strong></p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-118?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-118?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>AT &#30340;&#20154;&#29983;&#26410;&#24517;&#27604; MT &#26356;&#22909;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-118/">&#32593;&#39029;&#29256;</a></strong></p><p>&#23398;&#36710;&#26102;&#25105;&#24320;&#30340;&#26159;&#25163;&#21160;&#25377;&#65292;&#36215;&#21021;&#22240;&#20026;&#25216;&#26415;&#29983;&#30095;&#65292;&#24120;&#25630;&#24471;&#25163;&#24537;&#33050;&#20081;&#65292;&#25152;&#20197;&#31532;&#19968;&#21488;&#36710;&#23601;&#30452;&#25509;&#36873;&#20102;&#33258;&#21160;&#25377;&#12290;&#20294;&#24320;&#20102;&#20960;&#24180;&#65292;&#25105;&#24320;&#22987;&#36861;&#27714;&#37027;&#31181;&#23436;&#20840;&#25484;&#25511;&#30340;&#39550;&#39542;&#24863;&#65292;&#20110;&#26159;&#21448;&#22686;&#36141;&#20102;&#19968;&#21488;&#25163;&#21160;&#25377;&#12290;&#36951;&#25022;&#30340;&#26159;&#65292;&#38543;&#30528;&#20132;&#36890;&#26085;&#30410;&#25317;&#22581;&#65292;&#25442;&#25377;&#30340;&#20048;&#36259;&#36880;&#28176;&#34987;&#30130;&#24811;&#25269;&#28040;&#65292;&#26368;&#32456;&#36825;&#21488;&#36710;&#20063;&#34987;&#20919;&#33853;&#12290;&#31639;&#36215;&#26469;&#65292;&#25105;&#24050;&#32463;&#24555;&#20108;&#21313;&#24180;&#27809;&#35748;&#30495;&#24320;&#36807;&#25163;&#21160;&#25377;&#20102;&#65292;&#20294;&#20869;&#24515;&#28145;&#22788;&#65292;&#25105;&#20173;&#20250;&#26102;&#19981;&#26102;&#22320;&#24576;&#24565;&#37027;&#27573;&#8220;&#20154;&#36710;&#21512;&#19968;&#8221;&#30340;&#26102;&#20809;&#12290;</p><p>&#38543;&#30528; AI &#28145;&#24230;&#20171;&#20837;&#25105;&#30340;&#24037;&#20316;&#19982;&#29983;&#27963;&#65292;&#25105;&#24863;&#35273;&#33258;&#24049;&#30340;&#20154;&#29983;&#27491;&#20174; MT &#36716;&#21521; AT&#12290;&#27627;&#26080;&#30097;&#38382;&#65292;AI &#21161;&#25105;&#31361;&#30772;&#20102;&#35768;&#22810;&#33021;&#21147;&#29942;&#39048;&#65292;&#20063;&#22312;&#29087;&#24713;&#39046;&#22495;&#24102;&#26469;&#20102;&#24040;&#22823;&#30340;&#25928;&#29575;&#25552;&#21319;&#12290;&#20294;&#22855;&#24618;&#30340;&#26159;&#65292;&#25105;&#23545;&#23427;&#30340;&#8220;&#24778;&#21497;&#8221;&#21364;&#22312;&#19982;&#26085;&#20465;&#20943;&#12290;&#30475;&#20284;&#23427;&#33410;&#30465;&#20102;&#25105;&#30340;&#26102;&#38388;&#65292;&#20294;&#25105;&#24182;&#26410;&#20174;&#36825;&#20123;&#8220;&#22810;&#20986;&#26469;&#30340;&#26102;&#38388;&#8221;&#37324;&#33719;&#24471;&#39044;&#26399;&#30340;&#28385;&#36275;&#24863;&#12290;&#20063;&#35768;&#26159;&#25105;&#23545;&#23427;&#30340;&#26399;&#26395;&#38408;&#20540;&#19981;&#26029;&#25552;&#39640;&#65292;&#20294;&#19968;&#20010;&#19981;&#20105;&#30340;&#20107;&#23454;&#26159;&#65306;&#25105;&#24050;&#32463;&#26377;&#19968;&#27573;&#26102;&#38388;&#27809;&#26377;&#22312;&#23398;&#20064;&#21644;&#24320;&#21457;&#36807;&#31243;&#20013;&#65292;&#20307;&#20250;&#21040;&#37027;&#31181;&#21333;&#32431;&#30340;&#24555;&#20048;&#20102;&#12290;</p><p>&#24184;&#22909;&#65292;&#20960;&#22825;&#21069;&#25105;&#21448;&#25214;&#22238;&#20102;&#36825;&#31181;&#20037;&#36829;&#30340;&#24320;&#24515;&#12290;&#22312;&#20934;&#22791; iOS Conf SG &#30340; Keynote &#26102;&#65292;&#30001;&#20110; Keynote &#22312;&#21160;&#30011;&#26500;&#24314;&#19978;&#30456;&#23545;&#8220;&#21407;&#22987;&#8221;&#19988;&#32570;&#20047; AI &#36741;&#21161;&#65292;&#25105;&#38590;&#24471;&#22320;&#25317;&#26377;&#19968;&#27573;&#23436;&#25972;&#30340;&#26102;&#38388;&#65292;&#21435;&#32431;&#25163;&#24037;&#22320;&#23581;&#35797;&#21644;&#20462;&#25913;&#12290;&#21738;&#24597;&#21482;&#26159;&#19968;&#20010;&#31616;&#21333;&#30340;&#24182;&#34892;&#21160;&#30011;&#65292;&#31350;&#31455;&#26159;&#29992;&#36716;&#22330;&#12289;&#26222;&#36890;&#21160;&#30011;&#36824;&#26159;&#8220;&#31070;&#22855;&#31227;&#21160;&#8221;&#65292;&#25105;&#37117;&#29609;&#24471;&#19981;&#20134;&#20048;&#20046;&#12290;&#37027;&#20123;&#22312;&#19987;&#23478;&#25163;&#37324;&#21487;&#33021;&#20004;&#19977;&#20998;&#38047;&#25630;&#23450;&#30340;&#35774;&#32622;&#65292;&#25105;&#25240;&#33150;&#20102;&#22823;&#21322;&#22825;&#12290;&#23613;&#31649;&#27627;&#26080;&#25928;&#29575;&#21487;&#35328;&#65292;&#20294;&#25105;&#20048;&#22312;&#20854;&#20013;&#12290;&#30475;&#30528;&#26368;&#32456;&#37027;&#20010;&#30053;&#26174;&#8220;&#31616;&#38475;&#8221;&#30340;&#25928;&#26524;&#65292;&#25105;&#31455;&#34987;&#33258;&#24049;&#24863;&#21160;&#20102;&#12290;</p><p>&#23545;&#20110;&#32844;&#22330;&#20013;&#20154;&#65292;&#25928;&#29575;&#21644;&#23436;&#25104;&#24230;&#22266;&#28982;&#26159;&#30828;&#25351;&#26631;&#65307;&#20294;&#33021;&#21542;&#20307;&#20250;&#21040;&#36807;&#31243;&#24102;&#26469;&#30340;&#8220;&#23454;&#24863;&#8221;&#65292;&#25110;&#35768;&#25165;&#26159;&#20316;&#20026;&#8220;&#20154;&#8221;&#26368;&#26420;&#32032;&#30340;&#36861;&#27714;&#12290;</p><p>&#25105;&#22823;&#27010;&#29575;&#19981;&#20250;&#20877;&#20080; MT &#30340;&#36710;&#20102;&#65292;&#20294;&#22312;&#25105;&#36824;&#33021;&#25569;&#32039;&#26041;&#21521;&#30424;&#30340;&#26102;&#20505;&#65292;&#20063;&#19981;&#20250;&#36731;&#26131;&#35753;&#8220;&#26234;&#33021;&#39550;&#39542;&#8221;&#20195;&#21171;&#12290;&#20889;&#20195;&#30721;&#20063;&#26159;&#22914;&#27492;&#65292;&#24403;&#21021;&#29233;&#19978;&#23427;&#65292;&#27491;&#26159;&#22240;&#20026;&#23427;&#33021;&#32473;&#25105;&#24102;&#26469;&#32431;&#31929;&#30340;&#24555;&#20048;&#12290;&#24403;&#25152;&#26377;&#24037;&#20855;&#37117;&#22312;&#20652;&#20419;&#25105;&#20204;&#21464;&#24471;&#26356;&#24555;&#26356;&#22909;&#26102;&#65292;&#25105;&#24819;&#24212;&#35813;&#32473;&#33258;&#24049;&#30041;&#19968;&#28857;&#21464;&#24930;&#12289;&#21464;&#8220;&#31528;&#8221;&#30340;&#31354;&#38388;&#8212;&#8212;&#27605;&#31455;&#65292;AT &#30340;&#20154;&#29983;&#26410;&#24517;&#27604; MT &#26356;&#22909;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-117/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/running-swift-on-mcu/?utm_source=fatbobman%20weekly%20issue%20118&amp;utm_medium=web">&#21578;&#21035;&#8220;&#21487;&#31227;&#26893;&#27719;&#32534;&#8221;&#65306;&#25105;&#24050;&#35753; Swift &#22312; MCU &#19978;&#36816;&#34892;&#19971;&#24180;</a></strong></h3><p>&#20174; 2024 &#24180;&#24320;&#22987;&#65292;Swift &#23448;&#26041;&#27491;&#24335;&#25552;&#20379;&#20102;&#23545;&#23884;&#20837;&#24335;&#31995;&#32479;&#30340;&#25903;&#25345;&#65292;&#20294;&#35201;&#22312;&#36825;&#20010;&#39046;&#22495;&#33719;&#24471;&#26174;&#33879;&#20221;&#39069;&#65292;&#20173;&#26377;&#24456;&#38271;&#30340;&#36335;&#35201;&#36208;&#12290;&#20854;&#23454;&#65292;&#26089;&#22312;&#23448;&#26041;&#19979;&#22330;&#20043;&#21069;&#30340; 2018 &#24180;&#65292;<a href="https://x.com/madmachineio">Andy Liu</a> &#21644;&#20182;&#30340; <a href="https://madmachine.io/">MadMachine</a> &#22242;&#38431;&#23601;&#24320;&#22987;&#22312;&#25506;&#32034;&#21644;&#23454;&#36341;&#23558; Swift &#24212;&#29992;&#20110;&#23884;&#20837;&#24335;&#39046;&#22495;&#65292;&#24182;&#38470;&#32493;&#25512;&#20986;&#20102;&#30456;&#20851;&#30828;&#20214;&#12290;&#20182;&#20204;&#22362;&#20449;&#65292;&#22312;&#21151;&#33021;&#26085;&#30410;&#22797;&#26434;&#30340;&#24320;&#21457;&#22330;&#26223;&#20013;&#65292;Swift &#30340;&#29616;&#20195;&#35821;&#35328;&#29305;&#24615;&#23558;&#23637;&#29616;&#20986;&#24040;&#22823;&#30340;&#20248;&#21183;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;Andy &#20998;&#20139;&#20102;&#36807;&#21435;&#20960;&#24180;&#20013;&#22312;&#35813;&#39046;&#22495;&#30340;&#25506;&#32034;&#21382;&#31243;&#12290;&#25105;&#30495;&#24515;&#24076;&#26395;&#65292;Swift &#33021;&#22815;&#22312;&#26356;&#22810;&#30340;&#22330;&#26223;&#20013;&#65292;&#23637;&#29616;&#20854;&#39749;&#21147;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-01">&#22312; SwiftUI &#20013;&#26500;&#24314;&#22522;&#30784;&#25320;&#21495;&#28369;&#22359;&#32452;&#20214; (Building a Base DialSlider Component in SwiftUI)</a></strong></h3><p>&#22312; AI &#21151;&#33021;&#36234;&#26469;&#36234;&#24378;&#22823;&#30340;&#20170;&#22825;&#65292;&#30475;&#21040;&#19968;&#20010;&#21160;&#25928;&#65292;&#35753; AI &#24110;&#20320;&#23454;&#29616;&#24050;&#32463;&#36234;&#26469;&#36234;&#23481;&#26131;&#20102;&#12290;&#20294;&#27599;&#24403;&#30475;&#21040;&#24320;&#21457;&#32773;&#20973;&#20511;&#33258;&#24049;&#30340;&#8221;&#22855;&#24605;&#22937;&#24819;&#8221;&#19981;&#26029;&#25506;&#32034;&#23454;&#29616;&#26041;&#24335;&#24182;&#25171;&#30952;&#25928;&#26524;&#26102;&#65292;&#25105;&#20173;&#20250;&#30001;&#34935;&#36190;&#21497;&#12290;<a href="https://x.com/Codelaby">codelaby</a> &#22312;&#36825;&#31687;&#22797;&#21051;&#8221;&#32769;&#24335;&#30005;&#35805;&#25320;&#21495;&#30424;&#8221;&#30340;&#25991;&#31456;&#20013;&#65292;&#24039;&#22937;&#36816;&#29992; SwiftUI &#30340; <code>.compositingGroup()</code> &#21644; <code>.blendMode(.destinationOut)</code> &#23454;&#29616;&#20102;&#21160;&#24577;&#8221;&#38210;&#31354;&#8221;&#25928;&#26524;&#65292;&#20351;&#26059;&#36716;&#23618;&#19979;&#30340;&#38745;&#24577;&#25968;&#23383;&#28165;&#26224;&#26174;&#29616;&#65292;&#30456;&#27604;&#21333;&#32431;&#26059;&#36716;&#22270;&#29255;&#26356;&#20855;&#28789;&#27963;&#24615;&#21644;&#21407;&#29983;&#36136;&#24863;&#12290;&#27492;&#22806;&#65292;&#25991;&#31456;&#23545;&#29615;&#24418;&#25163;&#21183;&#22788;&#29702;&#12289;&#35282;&#24230;&#35745;&#31639;&#65288;<code>atan2</code>&#65289;&#20197;&#21450;&#38480;&#20301;&#36923;&#36753;&#65288;Stopper&#65289;&#30340;&#38416;&#36848;&#20063;&#21313;&#20998;&#36879;&#24443;&#28165;&#26224;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-02">CKSyncEngine &#31572;&#30097;&#19982;&#23454;&#25112;&#32463;&#39564;&#20998;&#20139; (CKSyncEngine Questions and Answers)</a></strong></h3><p>&#19981;&#23569;&#24320;&#21457;&#32773;&#23545; Core Data &#30340; <code>NSPersistentCloudKitContainer</code> &#39047;&#26377;&#35807;&#30149;&#65292;&#35748;&#20026;&#20854;&#19981;&#36879;&#26126;&#19988;&#32570;&#20047;&#23450;&#21046;&#24615;&#12290;&#20294;&#30495;&#27491;&#24819;&#33258;&#24049;&#30528;&#25163;&#35299;&#20915; CloudKit &#30340;&#25968;&#25454;&#21516;&#27493;&#38382;&#39064;&#26102;&#65292;&#25165;&#21457;&#29616;&#38656;&#35201;&#32771;&#34385;&#30340;&#22320;&#26041;&#23454;&#22312;&#22826;&#22810;&#65292;&#38590;&#24230;&#36828;&#36229;&#24819;&#35937;&#12290;&#33529;&#26524;&#22312;&#20960;&#24180;&#21069;&#25512;&#20986;&#30340; <a href="https://developer.apple.com/documentation/cloudkit/cksyncengine-5sie5">CKSyncEngine</a> &#24443;&#24213;&#25171;&#30772;&#20102;&#36825;&#20010;&#22256;&#22659;&#65292;&#25552;&#20379;&#20102;&#26356;&#28165;&#26224;&#30340;&#29366;&#24577;&#31649;&#29702;&#21644;&#38169;&#35823;&#22788;&#29702;&#65292;&#24182;&#33258;&#21160;&#22788;&#29702;&#20102;&#35832;&#22810;&#22797;&#26434;&#30340;&#36793;&#32536;&#24773;&#20917;&#65292;&#35753;&#24320;&#21457;&#32773;&#21487;&#20197;&#19987;&#24515;&#26500;&#24314;&#25968;&#25454;&#21516;&#27493;&#36923;&#36753;&#12290;</p><p><a href="https://x.com/christianselig">Christian Selig</a> &#36890;&#36807;&#33258;&#38382;&#33258;&#31572;&#30340;&#26041;&#24335;&#65292;&#20998;&#20139;&#20102;&#20182;&#22312;&#20351;&#29992; <code>CKSyncEngine</code> API &#26102;&#30340;&#32463;&#39564;&#65292;&#35814;&#32454;&#25286;&#35299;&#20102; <code>CKSyncEngine</code> &#22914;&#20309;&#20316;&#20026;&#19968;&#20010;&#23436;&#32654;&#30340;&#20013;&#38388;&#23618;&#65292;&#22312;&#20445;&#30041;&#25968;&#25454;&#23384;&#20648;&#28789;&#27963;&#24615;&#65288;&#20320;&#21487;&#20197;&#32487;&#32493;&#29992; SQLite&#12289;Realm &#25110; JSON&#65289;&#30340;&#21516;&#26102;&#65292;&#25509;&#31649;&#20102;&#26368;&#20196;&#20154;&#22836;&#30140;&#30340;&#21516;&#27493;&#29366;&#24577;&#31649;&#29702;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-03">&#25105;&#23545; iOS 26 Tab Bar &#30340;&#21520;&#27133; (My Beef with the iOS 26 Tab Bar)</a></strong></h3><p>SwiftUI &#22312; iOS 18 &#20013;&#23545; Tab Bar &#30340;&#35843;&#25972;&#65292;&#20854;&#24433;&#21709;&#20960;&#20046;&#22570;&#27604;&#24403;&#24180; NavigationStack/NavigationSplitView &#21462;&#20195; NavigationView&#65292;&#19981;&#20165;&#25913;&#21464;&#20102;&#35774;&#35745;&#35821;&#35328;&#65292;&#23545;&#24212;&#29992;&#30340;&#23454;&#29616;&#26041;&#24335;&#21644;&#25968;&#25454;&#27969;&#36208;&#21521;&#37117;&#20135;&#29983;&#20102;&#39072;&#35206;&#24615;&#24433;&#21709;&#12290;&#32780;&#20026; iOS 26 Liquid Glass &#39118;&#26684;&#24341;&#20837;&#30340;&#8221;&#25628;&#32034;&#26631;&#31614;&#8221;&#21151;&#33021;&#36827;&#19968;&#27493;&#25512;&#36827;&#20102;&#36825;&#31181;&#21464;&#38761;&#12290;<a href="https://mastodon.social/@ryanashcraft">Ryan Ashcraft</a> &#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#30452;&#35328;&#19981;&#35763;&#22320;&#25351;&#20986;&#20102;&#26032; Tab Bar &#35774;&#35745;&#30340;&#35832;&#22810;&#38382;&#39064;&#65306;&#40664;&#35748;&#30340;&#28014;&#21160;&#26679;&#24335;&#22312;&#26576;&#20123;&#30028;&#38754;&#20013;&#26174;&#24471;&#31361;&#20800;&#65292;&#19982;&#24212;&#29992;&#25972;&#20307;&#35270;&#35273;&#39118;&#26684;&#38590;&#20197;&#21327;&#35843;&#65307;&#26032;&#30340;&#36793;&#36317;&#21644;&#38388;&#36317;&#35268;&#21017;&#25171;&#30772;&#20102;&#38271;&#26399;&#20197;&#26469;&#30340;&#35774;&#35745;&#24815;&#20363;&#65292;&#35753;&#24320;&#21457;&#32773;&#38656;&#35201;&#37325;&#26032;&#35843;&#25972;&#22823;&#37327;&#29616;&#26377;&#30028;&#38754;&#65307;&#26356;&#37325;&#35201;&#30340;&#26159;&#65292;&#36825;&#20123;&#25913;&#21160;&#24182;&#26410;&#26126;&#26174;&#25552;&#21319;&#29992;&#25143;&#20307;&#39564;&#65292;&#21453;&#32780;&#22686;&#21152;&#20102;&#36866;&#37197;&#25104;&#26412;&#12290;</p><blockquote><p>&#25105;&#20010;&#20154;&#23545;&#26032; Tab &#30340;&#26368;&#22823;&#24863;&#21463;&#26159;&#65292;&#23427;&#20250;&#26174;&#33879;&#24433;&#21709;&#24320;&#21457;&#32773;&#22312;&#24320;&#21457;&#24212;&#29992;&#26102;&#23545;&#26368;&#20302;&#31995;&#32479;&#29256;&#26412;&#30340;&#20915;&#31574;&#12290;&#20026; Tab &#32500;&#25252;&#20004;&#22871;&#20195;&#30721;&#26159;&#21542;&#20540;&#24471;&#65311;&#22914;&#26524;&#20026;&#20102;&#31616;&#21270;&#23454;&#29616;&#32780;&#19981;&#24471;&#19981;&#23558;&#26368;&#20302;&#29256;&#26412;&#25552;&#39640;&#21040; iOS 18&#65292;&#36825;&#25110;&#35768;&#27491;&#26159; SwiftUI &#22242;&#38431;&#30340;&#21478;&#19968;&#20010;&#35774;&#35745;&#24847;&#22270;&#65311;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-04">Dia&#65306;&#28145;&#24230;&#21078;&#26512; The Browser Company &#30340; macOS &#27983;&#35272;&#22120;&#26550;&#26500; (Dia: A Technical Deep Dive into The Browser Company&#8217;s macOS Browser)</a></strong></h3><p>Arc &#26159;&#31532;&#19968;&#20010;&#20351;&#29992; Swift &#26500;&#24314;&#30340;&#22823;&#22411; Windows &#24179;&#21488;&#24212;&#29992;&#65292;&#32780;&#19988; The Browser Company &#20063;&#22240;&#27492;&#20026; Swift &#31038;&#21306;&#30340; Windows &#24037;&#20855;&#38142;&#20570;&#20986;&#20102;&#31361;&#20986;&#36129;&#29486;&#12290;&#22312;&#20174; Arc &#36716;&#22411;&#21040; Dia &#21518;&#65292;&#24320;&#21457;&#22242;&#38431;&#24182;&#27809;&#26377;&#25918;&#24323;&#20351;&#29992; Swift&#65292;&#37027;&#20040; macOS &#31471;&#30340; Dia &#20855;&#20307;&#20351;&#29992;&#20102;&#21738;&#20123;&#24320;&#21457;&#26694;&#26550;&#21602;&#65311;</p><p><a href="https://x.com/everettjf">Everett</a> &#22312;&#26412;&#25991;&#20013;&#25581;&#31034;&#20102; Dia &#29420;&#29305;&#30340;&#25216;&#26415;&#26550;&#26500;&#65306;&#36825;&#26159;&#19968;&#20010;&#22522;&#20110; AppKit + SwiftUI &#30340;&#21407;&#29983; macOS &#24212;&#29992;&#65292;&#20294;&#20854;&#26680;&#24515;&#28210;&#26579;&#24341;&#25806;&#24182;&#38750; WebKit&#65292;&#32780;&#26159;&#23884;&#20837;&#20102;&#33258;&#34892;&#20462;&#25913;&#30340; Chromium&#65288;<code>ArcCore</code>&#65289;&#12290;&#27492;&#22806;&#65292;&#22312; Dia &#30340;&#20108;&#36827;&#21046;&#25991;&#20214;&#20013;&#21457;&#29616;&#20102;&#22823;&#37327;&#19982;&#26412;&#22320; AI &#30456;&#20851;&#30340;&#24211;&#65288;&#22914; Apple MLX &#21644; LoRA &#36866;&#37197;&#22120;&#65289;&#65292;&#36825;&#39044;&#31034;&#30528; Dia &#24182;&#38750;&#21482;&#26159;&#20026;&#20102;&#8221;&#24555;&#8221;&#65292;&#32780;&#26159;&#24050;&#32463;&#20026;&#35774;&#22791;&#31471; AI &#25512;&#29702;&#20570;&#22909;&#20102;&#24213;&#23618;&#24037;&#31243;&#20934;&#22791;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-05">&#20851;&#20110;&#32599;&#25216;&#24320;&#21457;&#32773;&#35777;&#20070;&#36807;&#26399;&#30340;&#36855;&#24605; (Myths about Logitech Developer ID certificate expiration)</a></strong></h3><p>&#20960;&#22825;&#21069;&#65292;&#19981;&#23569; macOS &#29992;&#25143;&#21457;&#29616;&#32599;&#25216;&#40736;&#26631;&#30340;&#33258;&#23450;&#20041;&#25353;&#38062;&#22833;&#25928;&#12290;&#30001;&#20110;&#25511;&#21046;&#21488;&#26085;&#24535;&#20013;&#20805;&#26021;&#30528;&#20195;&#30721;&#31614;&#21517;&#65288;Code Signing&#65289;&#30456;&#20851;&#30340;&#25253;&#38169;&#65292;&#19981;&#23569;&#29992;&#25143;&#21644;&#23186;&#20307;&#23558;&#20854;&#24402;&#21646;&#20110;&#8221;&#33529;&#26524;&#25764;&#38144;&#20102;&#35777;&#20070;&#8221;&#12290;<a href="https://mastodon.social/@lapcatsoftware">Jeff Johnson</a> &#36890;&#36807;&#20998;&#26512;&#31995;&#32479;&#26085;&#24535;&#20026;&#33529;&#26524;&#22312;&#26412;&#27425;&#20107;&#20214;&#20013;&#30340;&#35282;&#33394;&#36827;&#34892;&#20102;&#24179;&#21453;&#65306;&#36825;&#24182;&#38750;&#33529;&#26524;&#30340;&#35777;&#20070;&#26381;&#21153;&#25925;&#38556;&#65292;&#32780;&#26159;&#32599;&#25216;&#33258;&#36523;&#36719;&#20214;&#24037;&#31243;&#38382;&#39064;&#23548;&#33268;&#30340;&#12290;Logi Options+ &#30340;&#21518;&#21488;&#36827;&#31243;&#22312;&#26356;&#26032;&#21518;&#65292;&#26410;&#33021;&#36890;&#36807; macOS <code>taskgated</code> &#30340;&#20195;&#30721;&#31614;&#21517;&#26377;&#25928;&#24615;&#39564;&#35777;&#65292;&#20174;&#32780;&#34987;&#31995;&#32479;&#30452;&#25509;&#32456;&#27490;&#12290;&#36825;&#31687;&#25991;&#31456;&#19981;&#20165;&#26159;&#19968;&#20221;&#25925;&#38556;&#20998;&#26512;&#25253;&#21578;&#65292;&#26356;&#25552;&#37266;&#24320;&#21457;&#32773;&#65306;&#22312; macOS &#20005;&#26684;&#30340;&#23433;&#20840;&#26426;&#21046;&#19979;&#65292;&#24212;&#29992;&#26356;&#26032;&#30340;&#31614;&#21517;&#39564;&#35777;&#27969;&#31243;&#23481;&#19981;&#24471;&#21322;&#28857;&#39532;&#34382;&#12290;</p><blockquote><p>&#8220;&#22914;&#26524;&#20320;&#30340;&#35777;&#20070;&#36807;&#26399;&#20102;&#65292;&#29992;&#25143;&#20173;&#28982;&#21487;&#20197;&#19979;&#36733;&#12289;&#23433;&#35013;&#21644;&#36816;&#34892;&#29992;&#35813;&#35777;&#20070;&#31614;&#21517;&#30340; Mac &#24212;&#29992;&#31243;&#24207;&#29256;&#26412;&#12290;&#20294;&#26159;&#65292;&#20320;&#38656;&#35201;&#19968;&#20010;&#26032;&#30340;&#35777;&#20070;&#26469;&#31614;&#32626;&#26356;&#26032;&#21644;&#26032;&#30003;&#35831;&#12290;&#8221; &#8212;&#8212; <a href="https://developer.apple.com/support/certificates/">&#33529;&#26524;&#23448;&#26041;&#25991;&#26723;</a></p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-06">&#25298;&#32477; LLM &#29983;&#25104;&#30340;&#24179;&#24248;&#20195;&#30721; (Stop Getting Average Code from Your LLM)</a></strong></h3><p>&#19981;&#21487;&#21542;&#35748;&#65292;&#22312;&#20154;&#31867;&#38271;&#20037;&#20197;&#26469;&#32047;&#31215;&#30340;&#20449;&#24687;&#28023;&#27915;&#20013;&#65292;&#39640;&#36136;&#37327;&#30340;&#25968;&#25454;&#19982;&#20449;&#24687;&#21482;&#21344;&#23569;&#25968;&#12290;&#23545;&#20110;&#20010;&#20307;&#26469;&#35828;&#65292;&#25105;&#20204;&#23436;&#20840;&#21487;&#20197;&#26377;&#30446;&#30340;&#22320;&#21435;&#29956;&#21035;&#21644;&#23398;&#20064;&#36825;&#20123;&#20248;&#36136;&#20869;&#23481;&#12290;&#20294;&#26159;&#65292;&#21463;&#38480;&#20110;&#26426;&#21046;&#65292;LLM &#40664;&#35748;&#20542;&#21521;&#20110;&#35757;&#32451;&#25968;&#25454;&#30340;&#8220;&#24179;&#22343;&#20540;&#8221;&#65292;&#36825;&#23601;&#23548;&#33268;&#23427;&#29983;&#25104;&#30340;&#20869;&#23481;&#22312;&#21508;&#20010;&#26041;&#38754;&#37117;&#26174;&#24471;&#27604;&#36739;&#24179;&#24248;&#12290;&#20855;&#20307;&#21040; Swift &#24320;&#21457;&#39046;&#22495;&#65292;&#36825;&#24448;&#24448;&#24847;&#21619;&#30528;&#23427;&#20250;&#29983;&#25104;&#22823;&#37327;&#26087;&#29256;&#30340;&#12289;&#38750;&#32467;&#26500;&#21270;&#30340;&#20195;&#30721;&#12290;</p><p>&#35201;&#24819;&#33719;&#24471;&#39640;&#36136;&#37327;&#12289;&#31526;&#21512; Swift 6 &#26631;&#20934;&#29978;&#33267;&#29305;&#23450;&#26550;&#26500;&#39118;&#26684;&#30340;&#20195;&#30721;&#65292;&#20851;&#38190;&#22312;&#20110;&#23545;&#25239;&#36825;&#31181;&#8220;&#22238;&#24402;&#22343;&#20540;&#8221;&#30340;&#26412;&#33021;&#12290;<a href="https://x.com/merowing_">Krzysztof Zab&#322;ocki</a> &#35814;&#32454;&#20171;&#32461;&#20102;&#22914;&#20309;&#21033;&#29992; Few-Shot Prompting&#65288;&#23569;&#26679;&#26412;&#25552;&#31034;&#65289;&#21644;&#19978;&#19979;&#25991;&#27880;&#20837;&#25216;&#26415;&#65292;&#36890;&#36807;&#25552;&#20379;&#20855;&#20307;&#30340;&#20195;&#30721;&#33539;&#20363;&#21644;&#26550;&#26500;&#35268;&#33539;&#65292;&#24378;&#36843; LLM &#8220;&#24536;&#35760;&#8221;&#24179;&#24248;&#30340;&#40664;&#35748;&#35774;&#32622;&#65292;&#36716;&#32780;&#29983;&#25104;&#31934;&#20934;&#21305;&#37197;&#39033;&#30446;&#26631;&#20934;&#30340;&#39640;&#36136;&#37327;&#20195;&#30721;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0118-07">swift-effect: &#19968;&#31181;&#22522;&#20110;&#31867;&#22411;&#39537;&#21160;&#30340;&#21103;&#20316;&#29992;&#22788;&#29702;&#26041;&#26696;</a></strong></h3><p><a href="https://x.com/AlexOzun">Alex Ozun</a> &#38271;&#26399;&#20851;&#27880; Swift &#20013;&#30340; <a href="https://swiftology.io/collections/type-driven-design/?utm_source=fatbobman%20weekly%20issue%20118&amp;utm_medium=web">&#31867;&#22411;&#39537;&#21160;&#35774;&#35745;</a>&#65292;&#36825;&#20010;&#24211;&#26159;&#20182;&#23545;&#8220;&#20195;&#25968;&#25928;&#24212;&#65288;Algebraic Effects&#65289;+ &#22788;&#29702;&#22120;&#65288;Effect Handlers&#65289;&#8221;&#22312; Swift &#37324;&#30340;&#23454;&#36341;&#12290;<br>swift-effect &#19981;&#26159;&#25226;&#21103;&#20316;&#29992;&#21464;&#25104;&#8220;&#25968;&#25454;&#32467;&#26500;&#20877;&#35299;&#37322;&#8221;&#65292;&#32780;&#26159;&#23558;&#21103;&#20316;&#29992;&#24314;&#27169;&#20026;&#21487;&#25318;&#25130;&#30340;&#20840;&#23616;&#25805;&#20316;&#65288;@Effect&#65289;&#65292;&#36890;&#36807; handler &#22312;&#36816;&#34892;&#26102;&#32452;&#21512;&#21644;&#26367;&#25442;&#34892;&#20026;&#65292;&#35753;&#19994;&#21153;&#20195;&#30721;&#20445;&#25345;&#32447;&#24615;/&#36807;&#31243;&#24335;&#39118;&#26684;&#65292;&#21516;&#26102;&#21448;&#33021;&#31934;&#32454;&#25511;&#21046; I/O&#12289;&#24182;&#21457;&#31561;&#34892;&#20026;&#12290;</p><p>&#26680;&#24515;&#20142;&#28857;&#65306;</p><ul><li><p><strong>&#20445;&#25345;&#20195;&#30721;&#32447;&#24615;</strong>&#65306;&#35843;&#29992; Console.print &#31561; effect &#23601;&#20687;&#26222;&#36890;&#20989;&#25968;&#65292;&#20294;&#34892;&#20026;&#21487;&#30001; handler &#21160;&#24577;&#20915;&#23450;&#12290;</p></li><li><p><strong>&#26080; Mock &#30340;&#34892;&#20026;&#27979;&#35797;</strong>&#65306;&#29992; <code>withTestHandler</code> &#36880;&#27493;&#25318;&#25130;/&#26029;&#35328; effect &#24207;&#21015;&#65292;&#20687;&#8220;&#20132;&#20114;&#24335;&#33050;&#26412;&#8221;&#19968;&#26679;&#27979;&#35797;&#27969;&#31243;&#12290;</p></li><li><p><strong>&#24182;&#21457;&#21487;&#25511;</strong>&#65306;&#25903;&#25345;&#23545; Task/AsyncSequence &#30340;&#30830;&#23450;&#24615;&#27979;&#35797;&#65292;&#35299;&#20915;&#24182;&#21457;&#39034;&#24207;&#19981;&#31283;&#23450;&#30340;&#38382;&#39064;&#12290;</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-08">Codex Skill Manager: &#19968;&#27454;&#38754;&#21521;&#20247;&#22810; CLI &#30340; macOS &#24037;&#20855;</a></strong></h3><p>&#24456;&#22810;&#24320;&#21457;&#32773;&#37117;&#20250;&#21516;&#26102;&#20351;&#29992;&#22810;&#31181; AI &#32534;&#31243;&#26381;&#21153;&#65292;&#23613;&#31649;&#23427;&#20204;&#25317;&#26377;&#31867;&#20284;&#30340;&#27010;&#24565;&#12289;&#35774;&#23450;&#21644;&#24037;&#20855;&#31867;&#22411;&#65292;&#20294;&#22312;&#20855;&#20307;&#35774;&#32622;&#21644;&#32454;&#33410;&#25551;&#36848;&#19978;&#20173;&#26377;&#24046;&#24322;&#65292;&#36825;&#23548;&#33268;&#24320;&#21457;&#32773;&#24456;&#38590;&#23545;&#25152;&#26377;&#26381;&#21153;&#36827;&#34892;&#32479;&#19968;&#31649;&#29702;&#12290;<a href="https://x.com/Dimillian">Thomas Ricouard</a> &#24320;&#21457;&#30340; Codex Skill Manager &#23558; Codex&#12289;Claude Code&#65288;&#20197;&#21450; OpenCode&#12289;Copilot&#65289;&#30340;&#25216;&#33021;&#38598;&#20013;&#22312;&#19968;&#20010; UI &#37324;&#26597;&#30475;&#12289;&#25628;&#32034;&#12289;&#21024;&#38500;&#21644;&#23548;&#20837;&#65292;&#36991;&#20813;&#22312;&#22810;&#20010;&#38544;&#34255;&#30446;&#24405;&#20013;&#25163;&#21160;&#23547;&#25214;&#12290;</p><p>&#26680;&#24515;&#21151;&#33021;</p><ul><li><p><strong>&#26412;&#22320;&#25216;&#33021;</strong>&#65306;&#25195;&#25551; <code>~/.codex/skills/public</code>&#12289;<code>~/.claude/skills</code> &#31561;&#36335;&#24452;&#65292;&#23637;&#31034;&#21015;&#34920;&#19982;&#35814;&#24773;</p></li><li><p><strong>&#35814;&#24773;&#28210;&#26579;</strong>&#65306;Markdown &#35270;&#22270;+&#24341;&#29992;&#39044;&#35272;</p></li><li><p><strong>&#36828;&#31243; Skill</strong>&#65306;Clawdhub &#25628;&#32034;/&#26368;&#26032;&#21015;&#34920;&#12289;&#35814;&#24773;&#25289;&#21462;&#19982;&#19979;&#36733;</p></li><li><p>&#23548;&#20837;/&#21024;&#38500;/&#33258;&#23450;&#20041;&#36335;&#24452;&#65306;&#25903;&#25345;&#20174; zip &#25110;&#25991;&#20214;&#22841;&#23548;&#20837;&#12289;&#20391;&#36793;&#26639;&#21024;&#38500;&#12289;&#28155;&#21152;&#33258;&#23450;&#20041;&#36335;&#24452;</p></li><li><p>&#22810;&#24179;&#21488;&#23433;&#35013;&#29366;&#24577;&#65306;&#20026;&#19981;&#21516;&#24179;&#21488;&#26631;&#35760;&#24050;&#23433;&#35013;&#29366;&#24577;</p></li></ul><h2><strong>&#27963;&#21160;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0118-09">LET&#8217;S VISION 2026&#65372;&#36992;&#35831;&#20320;&#19982;&#25105;&#20204;&#21516;&#34892;&#65281;</a></strong></h3><p><strong>&#10024; &#22823;&#20250;&#20027;&#39064;&#65306;Born to Create, Powered by AI</strong></p><ul><li><p>&#128205; <strong>&#22320;&#28857;</strong>&#65306;&#19978;&#28023;&#28437;&#27827;&#27902;&#20250;&#35758;&#20013;&#24515;</p></li><li><p>&#9200; <strong>&#26102;&#38388;</strong>&#65306;2026 &#24180; 3 &#26376; 27 &#26085; - 3 &#26376; 29 &#26085;</p></li><li><p>&#127937; <strong>&#37325;&#28857;</strong>&#65306;&#27719;&#32858;&#39030;&#23574;&#21019;&#20316;&#32773;&#19982; AI &#25216;&#26415;&#22823;&#21654;&#65292;&#20849;&#21516;&#25506;&#32034; AI &#24212;&#29992;&#30340;&#26410;&#26469;&#36793;&#30028;</p></li><li><p>&#127757; <strong>&#23448;&#32593;</strong>&#65306;<a href="https://l.fatbobman.com/w0118-09">letsvision.swiftgg.team</a></p></li></ul><p>&#21035;&#36208;&#24320;&#65281;&#35831;&#20851;&#27880;&#23448;&#26041;&#36134;&#21495;&#21644;&#20027;&#29702;&#20154; <a href="https://web.okjike.com/u/1E2FE012-3E79-489A-AC4B-C022F3715199">SwiftSIQI</a>&#65292;&#25105;&#20204;&#23558;&#25345;&#32493;&#25918;&#36865;&#26356;&#22810;&#31934;&#24425;&#20869;&#23481;&#65281;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0118-10">Swift Student Challenge 2026</a></strong></h3><p>&#27599;&#24180;&#19968;&#24230;&#30340;&#23398;&#29983;&#25361;&#25112;&#36187;&#20877;&#27425;&#30331;&#22330;&#12290;&#25361;&#25112;&#36187;&#20026;&#25968;&#20197;&#21315;&#35745;&#30340;&#23398;&#29983;&#24320;&#21457;&#32773;&#25552;&#20379;&#20102;&#23637;&#29616;&#21019;&#36896;&#21147;&#21644;&#32534;&#31243;&#33021;&#21147;&#30340;&#26426;&#20250;&#65292;&#35753;&#20182;&#20204;&#21487;&#20197;&#36890;&#36807; App Playground &#21576;&#29616;&#33258;&#24049;&#30340;&#20316;&#21697;&#65292;&#24182;&#20174;&#20013;&#23398;&#20064;&#22312;&#32844;&#19994;&#29983;&#28079;&#20013;&#21463;&#29992;&#30340;&#23454;&#38469;&#25216;&#33021;&#12290;</p><p><strong>&#20170;&#24180;&#20316;&#21697;&#25552;&#20132;&#36890;&#36947;&#23558;&#20110; 2026 &#24180; 2 &#26376; 6 &#26085;&#33267; 2 &#26376; 28 &#26085;&#24320;&#25918;&#12290;</strong></p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #117]]></title><description><![CDATA[2026: When AI Fades into the Workflow, Are You Ready?]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-117</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-117</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 05 Jan 2026 12:00:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!TfC-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TfC-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TfC-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 424w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 848w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 1272w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TfC-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp" width="1456" height="696" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:696,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/183428705?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TfC-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 424w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 848w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 1272w, https://substackcdn.com/image/fetch/$s_!TfC-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2227965-91ed-4705-9179-7f81d84bb3b8_1472x704.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>2026: When AI Fades into the Workflow, Are You Ready?</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-117/">Read on web &#8594;</a></p><p>Happy New Year, everyone! Over the past few years, AI has consistently occupied the center stage of the tech world. But looking back from the start of 2026, I&#8217;ve noticed a significant shift: since late 2025, the obsession with &#8220;trillion-parameter models&#8221; and &#8220;leaderboard benchmarks&#8221; has gradually cooled. In its place is a sober, hands-on focus on the meticulous cultivation of AI Workflows.</p><p>If the past two years were characterized by most people experimenting with chatbots, today, AI has shattered the constraints of the chat box. Through CLI tools, MCP (Model Context Protocol), and various Slash commands, Skills, and SubAgents, AI is no longer just an external utility for experienced developers. Instead, it has become like a plugin, permeating every capillary of our terminals, editors, and even the operating system itself.</p><p>In this regard, macOS has demonstrated a serendipitous, natural advantage. Leveraging mature automation tools like AppleScript and Shortcuts, even non-developers can grant AI access to their private data without complex API development. This &#8220;old tech finding new life&#8221; has provided Apple with a new moat in the AI era. If this capability is fully unleashed on iOS through system-level Agents, we may see a profound reshaping of hardware device form factors.</p><p>Meanwhile, some manufacturers are taking a more &#8220;radical&#8221; approach. ByteDance&#8217;s Doubao phone attempts to &#8220;brute-force&#8221; control over everything at the system level by reading the screen and simulating interactions. Huawei, on the other hand, employs an A2A strategy, attempting to build a unified agent scheduling mechanism in the background. Regardless of the path, 2026 marks a singularity for the average consumer: AI is no longer a tool for conversation; it is explicitly or implicitly taking over our digital lives.</p><p>As the old saying goes: When a technology is no longer constantly talked about, it means it has truly integrated into our lives, becoming as indispensable as the blood in our veins.</p><p>However, the more seamless it becomes, the more vigilant we must be. As AI sinks deep into every detail of our workflows, privacy will become the ultimate luxury. In our pursuit of extreme automation and efficiency, the core challenges of 2026 will be how we choose our service providers, how we balance local versus cloud-based models, and how we preserve that last bit of symbolic &#8220;privacy.&#8221;</p><p>2026 is here. Have you started integrating AI into your workflow?</p><p><a href="https://fatbobman.com/en/weekly/issue-116/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/zipic-1-from-0-to-1/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">The Indie Developer&#8217;s Trial: Zipic&#8217;s Productization Journey from 0 to 1</a></strong></h3><p><a href="https://l.fatbobman.com/zipic">Zipic</a> is an image compression tool I&#8217;ve been using frequently. I&#8217;ve personally witnessed how this app evolved from a small workplace necessity into an efficient, refined, and focused successful product through the continuous refinement by its author <a href="https://x.com/okooo5km">Shili</a>. Indie developers often operate as a &#8220;one-person army,&#8221; constantly switching between strategy, design, development, distribution, and promotion. To uncover the story behind this journey, I invited Shili to review Zipic&#8217;s entire process from 0 to 1. The complete series consists of three chapters: product design (this article), <a href="https://fatbobman.com/en/posts/zipic-2-selling-and-distribution/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">distribution and sales without relying on the Mac App Store</a>, and <a href="https://fatbobman.com/en/posts/zipic-3-technical-details/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">technical details review: SwiftUI pain points and performance bottlenecks</a>.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-01">Swift vs. Rust: 5 Surprising Facts Learned from the Ultimate Memory Management Showdown</a></strong></h3><p>In the developer community, discussions about Swift and Rust performance never cease. The conventional wisdom is: Swift is relatively slow due to Automatic Reference Counting (ARC), while Rust is renowned for its extreme speed and memory efficiency. However, <a href="https://x.com/rbbtsn0w">Snow</a> argues that these simple labels of &#8220;fast&#8221; and &#8220;slow&#8221; often obscure the fundamental differences in their design philosophies: Swift prioritizes developer experience and ecosystem compatibility, while Rust pursues ultimate performance and compile-time safety.</p><p>Through real-world examples, the article reveals five truths: Rust&#8217;s ownership rules are essentially zero-cost compile-time tools; Swift&#8217;s real performance burden comes from Objective-C compatibility rather than ARC itself; ARC&#8217;s core issue is performance unpredictability; for concurrency safety, Swift relies on runtime protection while Rust achieves compile-time guarantees; and why Swift cannot &#8220;become&#8221; Rust.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-02-1">StoreKit Subscriptions: A Practical Guide</a></strong></h3><p>Based on years of iOS development experience and real-world cases, <a href="https://x.com/azamsharp">Mohammad Azam</a> has written a comprehensive StoreKit subscription practical tutorial. The series covers: choosing monetization models (one-time purchases, subscriptions, consumable purchases, and hybrid strategies), <a href="https://l.fatbobman.com/w0117-02-2">paywall strategy comparison</a> (trade-offs between soft/hard paywalls and subscription trials), <a href="https://l.fatbobman.com/w0117-02-3">onboarding experience design</a> (evolving from static screenshots to an 8-step interactive onboarding that lets users experience core features and build emotional investment before paying), and <a href="https://l.fatbobman.com/w0117-02-4">complete technical implementation</a> (App Store Connect configuration, StoreKit integration, and code examples for product loading and purchase flows).</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-03">Skip 2025 Retrospective and 2026 Roadmap</a></strong></h3><p>In 2025, with the official release of Swift SDK for Android on swift.org, <a href="https://x.com/skiptools">Skip</a> provided native compilation support through Skip Fuse, unlocking thousands of native Swift packages for use on Android. New dual-platform frameworks were added for NFC, Stripe, PostHog, Auth0, Socket.IO, and more. iOS 26&#8217;s introduction of the Liquid Glass interface style became a litmus test for cross-platform frameworks. Skip, by adopting a &#8220;fully native&#8221; strategy (using native SwiftUI on iOS and mapping to Jetpack Compose on Android), automatically supported the new interface on day one without requiring rewrites or workarounds. In 2026, Skip plans to continue expanding integrated frameworks, optimizing the Skip Fuse toolchain, and improving performance and developer experience.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-04">How to use Claude Code</a></strong></h3><p>This is a practical guide compiled by <a href="https://x.com/onmyway133">Khoa Pham</a> after months of intensive Claude Code usage. Core tips include detailed application scenarios for various modes, especially how to use Extended Thinking mode judiciously to avoid wasting tokens. It also covers essential keyboard shortcuts, context management techniques, MCP integration, VS Code and Chrome extensions, GitHub Actions integration, Git Worktrees parallel workflows, plugin ecosystem, and prompt best practices. The content is detailed, specific, and targeted&#8212;not just a simple feature introduction manual.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-05-en">App Store Connect API Webhook&#65372;Automate CI/CD Workflows Seamlessly</a></strong></h3><p>Apple announced the App Store Connect API Webhook at WWDC 2025, supporting real-time push notifications for build status, app version status, TestFlight feedback, and other events. <a href="https://www.linkedin.com/in/zhgchgli/">Zhong Cheng</a> addresses the pain point of traditional polling methods requiring approximately 20 minutes of waiting after build uploads (wasting $1.24 per GitHub Runner instance), providing detailed instructions on applying this capability in CI/CD to achieve zero waiting costs; GitFlow merge-back timing can precisely align with actual app release time; developers can receive timely rejection notifications even with limited permissions.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-06">Setting up Embedded Linux with WendyOS</a></strong></h3><p>WendyOS is a Linux distribution designed for embedded devices, written in Swift, aiming to bring the convenience of iOS development to the embedded domain. <a href="https://x.com/JoannisOrlandos">Joannis Orlandos</a> provides a complete getting-started tutorial in this article: from installing Homebrew and Wendy tools, flashing WendyOS to devices like Raspberry Pi/Jetson Orin Nano, connecting devices via USB, configuring WiFi, creating Swift projects (including <code>wendy.json</code> permission configuration), to using VSCode extensions for remote debugging (supporting breakpoints and state inspection). Suitable as an introductory tutorial for developers wanting to apply Swift to embedded devices or IoT scenarios.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0117-07">Fucking Approachable Swift Concurrency</a></strong></h3><p>This is a learning resource created by <a href="https://x.com/pepicrft">Pedro Pi&#241;era</a>, based on <a href="https://mastodon.social/@mattiem">Matt Massicotte</a>&#8216;s Swift concurrency concepts, explaining core concepts like async/await, Task, Actor, and Sendable in an approachable way. Pedro uses an &#8220;Office Building&#8221; scenario to build intuitive mental models: comparing MainActor to a reception desk, actors to department offices, and await to knocking and waiting. Additionally, it provides a Skill.md file suitable for AI tools, allowing developers to directly embed these concurrency practices into their development workflow&#8217;s rule engine.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-08">Dimillian&#8217;s Skills - iOS/Swift Development AI Agent Skills Collection</a></strong></h3><p>A Skills repository for iOS/Swift development created by <a href="https://github.com/Dimillian">Thomas Ricouard</a>, containing six AI Agent Skills focused on practical workflows. Covers App Store Changelog generation (automatically generating release notes from git history), iOS Debugger Agent (building/debugging iOS projects using XcodeBuildMCP), Swift Concurrency Expert (fixing Swift 6.2 concurrency issues), SwiftUI Liquid Glass (implementing iOS 26+ Liquid Glass API), SwiftUI View Refactor (refactoring view structure and dependency patterns), and SwiftUI Performance Audit (reviewing performance bottlenecks and providing optimization recommendations).</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-09">StoreKit Helper - SwiftUI In-App Purchase Wrapper Library</a></strong></h3><p>A lightweight StoreKit 2 wrapper library developed by <a href="https://x.com/jaywcjlove">jaywcjlove</a>, designed specifically for SwiftUI, greatly simplifying in-app purchase implementation. Compared to using the StoreKit 2 API directly, StoreKitHelper reduces approximately 70% of boilerplate code, making it particularly suitable for SwiftUI developers who need to quickly integrate in-app purchases without dealing with underlying complexity.</p><p>Core features include: <code>@ObservableObject</code>-based state management, protocol-driven type-safe product definitions, real-time transaction monitoring and automatic state updates, and built-in <code>StoreKitHelperView</code> and <code>StoreKitHelperSelectionView</code> UI components. Interface display can be easily controlled through <code>hasNotPurchased</code>/<code>hasPurchased</code> properties, supporting fluent API configuration for various purchase popup callbacks.</p><h2><strong>Jobs</strong></h2><h3><strong><a href="https://github.com/photon-hq">macOS Systems Engineer</a></strong></h3><p><a href="https://github.com/photon-hq">Photon</a> is building open-source SDKs that let developers bring AI agents to interfaces that 99% of the world already knows how to use - iMessage, WhatsApp, phone calls, Discord, Signal, and more. On top of that, we&#8217;re building open-source Agent SDKs focused on interaction - things like multi-part messages, threading, reactions (Tapbacks), etc - so developers and enterprises can ship agents that actually feel human.</p><p>We are hiring a <strong>macOS Engineer</strong>. The ideal profile includes:</p><ul><li><p>Deep understanding of macOS internals and how system components interact</p></li><li><p>Experience with macOS system analysis and debugging</p></li><li><p>Hands-on experience working with system-level APIs and low-level mechanisms</p></li><li><p>Strong curiosity and passion for exploring the undocumented side of Apple services</p></li><li><p>(Optional but a plus) Experience with iMessage, IMAgent, or related messaging infrastructure</p></li></ul><p>We offer competitive compensation (US-based, remote-friendly). Photon is backed by top-tier investors.</p><p><strong>Contact:</strong> <a href="mailto:ryan@photon.codes">ryan@photon.codes</a></p><blockquote><p>This is a job posting from Photon, a friend&#8217;s startup team. They&#8217;re building infrastructure for AI Agents on platforms like iMessage/WhatsApp&#8212;it&#8217;s an early-stage project. If you&#8217;re interested in macOS low-level technologies and early startup opportunities, feel free to check it out.</p></blockquote><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-117?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-117?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>2026&#65306;&#24403; AI &#38544;&#20837;&#24037;&#20316;&#27969;&#65292;&#20320;&#20934;&#22791;&#22909;&#20102;&#21527;&#65311;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-117/">&#32593;&#39029;&#29256;</a></strong></p><p>&#22823;&#23478;&#26032;&#24180;&#22909;&#65281;&#22312;&#36807;&#21435;&#30340;&#20960;&#24180;&#20013;&#65292;AI &#22987;&#32456;&#21344;&#25454;&#30528;&#31185;&#25216;&#30028;&#26368;&#32768;&#30524;&#30340; C &#20301;&#12290;&#20294;&#31449;&#22312; 2026 &#24180;&#30340;&#36215;&#28857;&#22238;&#30475;&#65292;&#25105;&#21457;&#29616;&#19968;&#20010;&#26174;&#33879;&#30340;&#36716;&#25240;&#65306;&#20174; 2025 &#24180;&#26411;&#24320;&#22987;&#65292;&#20154;&#20204;&#23545;&#8220;&#19975;&#20159;&#21442;&#25968;&#8221;&#25110;&#8220;&#27036;&#21333;&#36305;&#20998;&#8221;&#30340;&#29378;&#28909;&#36880;&#28176;&#35114;&#21435;&#65292;&#21462;&#32780;&#20195;&#20043;&#30340;&#26159;&#23545; AI &#24037;&#20316;&#27969;&#28145;&#32789;&#32454;&#20316;&#30340;&#20919;&#38745;&#19982;&#23454;&#25112;&#12290;</p><p>&#22914;&#26524;&#35828;&#36807;&#21435;&#20004;&#24180;&#22823;&#22810;&#25968;&#20154;&#36824;&#22312;&#23581;&#35797;&#22914;&#20309;&#19982; Chat &#26426;&#22120;&#20154;&#32842;&#22825;&#65292;&#37027;&#20040;&#29616;&#22312;&#65292;AI &#24050;&#32463;&#36890;&#36807; CLI&#12289;MCP &#20197;&#21450;&#21508;&#31181; Slash&#12289;Skill&#12289;SubAgent&#65292;&#24443;&#24213;&#25171;&#30772;&#20102;&#23545;&#35805;&#26694;&#30340;&#38480;&#21046;&#12290;&#23545;&#20110;&#26377;&#32463;&#39564;&#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;AI &#24050;&#32463;&#19981;&#20877;&#26159;&#19968;&#20010;&#22806;&#37096;&#24037;&#20855;&#65292;&#32780;&#26159;&#20687;&#25554;&#20214;&#19968;&#26679;&#65292;&#28183;&#36879;&#36827;&#32456;&#31471;&#12289;&#32534;&#36753;&#22120;&#20035;&#33267;&#25972;&#20010;&#25805;&#20316;&#31995;&#32479;&#30340;&#27599;&#19968;&#20010;&#27611;&#32454;&#34880;&#31649;&#12290;</p><p>&#22312;&#36825;&#19968;&#28857;&#19978;&#65292;macOS &#23637;&#31034;&#20102;&#26576;&#31181;&#8220;&#26080;&#24515;&#25554;&#26611;&#8221;&#30340;&#22825;&#28982;&#20248;&#21183;&#12290;&#20511;&#21161; AppleScript &#21644;&#24555;&#25463;&#25351;&#20196;&#36825;&#20123;&#25104;&#29087;&#30340;&#33258;&#21160;&#21270;&#24037;&#20855;&#65292;&#21363;&#20415;&#19981;&#36890;&#36807;&#22797;&#26434;&#30340; API &#24320;&#21457;&#65292;&#26222;&#36890;&#29992;&#25143;&#20063;&#33021;&#35753; AI &#35775;&#38382;&#33258;&#24049;&#30340;&#31169;&#26377;&#25968;&#25454;&#12290;&#36825;&#31181;&#8220;&#32769;&#26641;&#21457;&#26032;&#33469;&#8221;&#30340;&#29616;&#35937;&#65292;&#35753;&#33529;&#26524;&#22312; AI &#26102;&#20195;&#25317;&#26377;&#20102;&#26032;&#30340;&#25252;&#22478;&#27827;&#12290;&#32780;&#22914;&#26524;&#36825;&#31181;&#33021;&#21147;&#22312; iOS &#19978;&#36890;&#36807;&#31995;&#32479;&#32423; Agent &#23436;&#20840;&#37322;&#25918;&#65292;&#30828;&#20214;&#35774;&#22791;&#30340;&#24418;&#24577;&#25110;&#35768;&#23558;&#36814;&#26469;&#26032;&#19968;&#36718;&#37325;&#22609;&#12290;</p><p>&#19982;&#27492;&#21516;&#26102;&#65292;&#26576;&#20123;&#21378;&#21830;&#30340;&#31574;&#30053;&#21017;&#26356;&#21152;&#8220;&#28608;&#36827;&#8221;&#12290;&#23383;&#33410;&#36339;&#21160;&#30340;&#35910;&#21253;&#25163;&#26426;&#23581;&#35797;&#20174;&#31995;&#32479;&#24213;&#23618;&#36890;&#36807;&#23631;&#24149;&#35835;&#21462;&#19982;&#27169;&#25311;&#20132;&#20114;&#26469;&#8220;&#26292;&#21147;&#8221;&#25509;&#31649;&#19968;&#20999;&#65307;&#21326;&#20026;&#21017;&#36890;&#36807; A2A&#65288;Agent to Agent&#65289;&#31574;&#30053;&#65292;&#35797;&#22270;&#22312;&#21518;&#21488;&#26500;&#24314;&#19968;&#22871;&#32479;&#19968;&#30340;&#20195;&#29702;&#35843;&#24230;&#26426;&#21046;&#12290;&#26080;&#35770;&#36335;&#32447;&#22914;&#20309;&#65292;2026 &#24180;&#23545;&#20110;&#26222;&#36890;&#28040;&#36153;&#32773;&#26469;&#35828;&#37117;&#26631;&#24535;&#30528;&#19968;&#20010;&#22855;&#28857;&#30340;&#21040;&#26469;&#65306;AI &#19981;&#20877;&#26159;&#32842;&#22825;&#24037;&#20855;&#65292;&#32780;&#26159;&#26174;&#24335;&#25110;&#38544;&#24335;&#22320;&#25509;&#31649;&#20102;&#25105;&#20204;&#30340;&#25968;&#23383;&#29983;&#27963;&#12290;</p><p>&#27491;&#22914;&#37027;&#21477;&#32769;&#35805;&#65306;&#24403;&#19968;&#20010;&#25216;&#26415;&#19981;&#20877;&#34987;&#21453;&#22797;&#25552;&#21450;&#65292;&#25165;&#35828;&#26126;&#23427;&#24050;&#30495;&#27491;&#34701;&#20837;&#29983;&#27963;&#65292;&#22914;&#21516;&#34880;&#28082;&#33324;&#19981;&#21487;&#25110;&#32570;&#12290;</p><p>&#28982;&#32780;&#65292;&#36234;&#26159;&#26080;&#24863;&#65292;&#36234;&#35201;&#35686;&#24789;&#12290;&#24403; AI &#28145;&#20837;&#24037;&#20316;&#27969;&#30340;&#27599;&#19968;&#20010;&#32454;&#33410;&#65292;&#38544;&#31169;&#23558;&#25104;&#20026;&#26368;&#26114;&#36149;&#30340;&#22882;&#20360;&#21697;&#12290;&#22312;&#36861;&#27714;&#26497;&#33268;&#33258;&#21160;&#21270;&#19982;&#25928;&#29575;&#30340;&#21516;&#26102;&#65292;&#22914;&#20309;&#36873;&#25321;&#26381;&#21153;&#21830;&#12289;&#22914;&#20309;&#24179;&#34913;&#26412;&#22320;&#19982;&#20113;&#31471;&#27169;&#22411;&#12289;&#22914;&#20309;&#20445;&#30041;&#26368;&#21518;&#19968;&#28857;&#35937;&#24449;&#24615;&#30340;&#8220;&#38544;&#31169;&#8221;&#65292;&#23558;&#26159;&#25105;&#20204;&#22312; 2026 &#24180;&#24517;&#39035;&#38754;&#23545;&#30340;&#21629;&#39064;&#12290;</p><p>2026 &#26469;&#20102;&#65292;&#20320;&#24320;&#22987;&#23558; AI &#38598;&#25104;&#21040;&#33258;&#24049;&#30340;&#24037;&#20316;&#27969;&#20013;&#20102;&#21527;&#65311;</p><p><a href="https://fatbobman.com/zh/weekly/issue-116/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/zipic-1-from-0-to-1/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">&#29420;&#31435;&#24320;&#21457;&#32773;&#30340;&#35797;&#28860;&#65306;Zipic &#20174; 0 &#21040; 1 &#30340;&#20135;&#21697;&#21270;&#20043;&#36335;</a></strong></h3><p><a href="https://l.fatbobman.com/zipic">Zipic</a> &#26159;&#25105;&#19968;&#30452;&#22312;&#39640;&#39057;&#20351;&#29992;&#30340;&#22270;&#29255;&#21387;&#32553;&#24037;&#20855;&#65292;&#25105;&#20146;&#30524;&#35265;&#35777;&#20102;&#36825;&#20010;&#24212;&#29992;&#22914;&#20309;&#20174;&#19968;&#20010;&#32844;&#22330;&#24037;&#20316;&#30340;&#23567;&#38656;&#27714;&#65292;&#36880;&#28176;&#22312;&#20316;&#32773; <a href="https://x.com/okooo5km">&#21313;&#37324;</a> &#30340;&#19981;&#26029;&#25171;&#30952;&#19979;&#25104;&#38271;&#20026;&#19968;&#20010;&#39640;&#25928;&#12289;&#31934;&#33268;&#12289;&#19987;&#27880;&#30340;&#25104;&#21151;&#20135;&#21697;&#12290;&#29420;&#31435;&#24320;&#21457;&#32773;&#24448;&#24448;&#24847;&#21619;&#30528;&#8220;&#19968;&#20154;&#25104;&#20891;&#8221;&#65292;&#26102;&#21051;&#22312;&#31574;&#30053;&#12289;&#35774;&#35745;&#12289;&#24320;&#21457;&#12289;&#20998;&#21457;&#19982;&#25512;&#24191;&#20043;&#38388;&#26469;&#22238;&#20999;&#25442;&#12290;&#20026;&#20102;&#25366;&#25496;&#36825;&#32972;&#21518;&#30340;&#25925;&#20107;&#65292;&#25105;&#36992;&#35831;&#20102;&#21313;&#37324;&#22797;&#30424;&#20102; Zipic &#20174; 0 &#21040; 1 &#30340;&#20840;&#36807;&#31243;&#12290;&#20840;&#25991;&#20849;&#20998;&#19977;&#20010;&#31687;&#31456;&#65306;&#20135;&#21697;&#35774;&#35745;&#65288;&#26412;&#25991;&#65289;&#12289;<a href="https://fatbobman.com/zh/posts/zipic-2-selling-and-distribution/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">&#19981;&#20381;&#36182; Mac App Store &#30340;&#20998;&#21457;&#19982;&#21806;&#21334;</a> &#20197;&#21450; <a href="https://fatbobman.com/zh/posts/zipic-3-technical-details/?utm_source=fatbobman%20weekly%20issue%20117&amp;utm_medium=web">&#25216;&#26415;&#32454;&#33410;&#22797;&#30424;&#65306;SwiftUI &#30171;&#28857;&#19982;&#24615;&#33021;&#29942;&#39048;</a>&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-01">Swift vs. Rust&#65306;&#20174;&#20869;&#23384;&#31649;&#29702;&#30340;&#32456;&#26497;&#23545;&#20915;&#20013;&#23398;&#21040;&#30340; 5 &#20010;&#24778;&#20154;&#20107;&#23454;</a></strong></h3><p>&#22312;&#24320;&#21457;&#32773;&#31038;&#21306;&#20013;&#65292;&#20851;&#20110; Swift &#21644; Rust &#24615;&#33021;&#30340;&#35752;&#35770;&#20174;&#26410;&#20572;&#27490;&#12290;&#36890;&#24120;&#30340;&#30475;&#27861;&#26159;&#65306;Swift &#22240;&#20026;&#33258;&#21160;&#24341;&#29992;&#35745;&#25968;&#65288;ARC&#65289;&#32780;&#30456;&#23545;&#36739;&#24930;&#65292;&#32780; Rust &#21017;&#20197;&#20854;&#26497;&#33268;&#30340;&#36895;&#24230;&#21644;&#20869;&#23384;&#25928;&#29575;&#33879;&#31216;&#12290;&#20294; <a href="https://x.com/rbbtsn0w">Snow</a> &#35748;&#20026;&#65292;&#36825;&#31181;&#8220;&#24555;&#8221;&#19982;&#8220;&#24930;&#8221;&#30340;&#31616;&#21333;&#26631;&#31614;&#24448;&#24448;&#25513;&#30422;&#20102;&#20004;&#32773;&#22312;&#35774;&#35745;&#21746;&#23398;&#19978;&#30340;&#26681;&#26412;&#24046;&#24322;&#65306;Swift &#20248;&#20808;&#24320;&#21457;&#20307;&#39564;&#21644;&#29983;&#24577;&#20860;&#23481;&#65292;Rust &#36861;&#27714;&#26497;&#33268;&#24615;&#33021;&#21644;&#32534;&#35793;&#26102;&#23433;&#20840;&#12290;</p><p>&#32467;&#21512;&#23454;&#38469;&#26696;&#20363;&#65292;&#25991;&#31456;&#25581;&#31034;&#20102;&#20116;&#20010;&#30495;&#30456;&#65306;Rust &#30340;&#25152;&#26377;&#26435;&#35268;&#21017;&#26412;&#36136;&#19978;&#26159;&#38646;&#24320;&#38144;&#30340;&#32534;&#35793;&#26102;&#24037;&#20855;&#65307;Swift &#30340;&#30495;&#27491;&#24615;&#33021;&#21253;&#34993;&#26469;&#33258; Objective-C &#20860;&#23481;&#24615;&#32780;&#38750; ARC &#26412;&#36523;&#65307;ARC &#30340;&#26680;&#24515;&#38382;&#39064;&#26159;&#24615;&#33021;&#30340;&#19981;&#21487;&#39044;&#27979;&#24615;&#65307;&#24182;&#21457;&#23433;&#20840;&#19978; Swift &#20381;&#36182;&#36816;&#34892;&#26102;&#20445;&#25252;&#32780; Rust &#23454;&#29616;&#32534;&#35793;&#26102;&#20445;&#35777;&#65307;&#20197;&#21450;&#20026;&#20309; Swift &#26080;&#27861;&#8220;&#21464;&#25104;&#8221;Rust&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-02-1">StoreKit &#35746;&#38405;&#23454;&#25112;&#25351;&#21335; (StoreKit Subscriptions: A Practical Guide)</a></strong></h3><p><a href="https://x.com/azamsharp">Mohammad Azam</a> &#22522;&#20110;&#22810;&#24180; iOS &#24320;&#21457;&#32463;&#39564;&#21644;&#30495;&#23454;&#26696;&#20363;&#65292;&#25776;&#20889;&#20102;&#23436;&#25972;&#30340; StoreKit &#35746;&#38405;&#23454;&#36341;&#25945;&#31243;&#12290;&#31995;&#21015;&#28085;&#30422;&#65306;&#21464;&#29616;&#27169;&#22411;&#36873;&#25321;&#65288;&#19968;&#27425;&#24615;&#36141;&#20080;&#12289;&#35746;&#38405;&#12289;&#28040;&#32791;&#22411;&#36141;&#20080;&#21450;&#28151;&#21512;&#31574;&#30053;&#65289;&#12289;<a href="https://l.fatbobman.com/w0117-02-2">&#20184;&#36153;&#22681;&#31574;&#30053;&#23545;&#27604;</a>&#65288;&#36719;/&#30828;&#20184;&#36153;&#22681;&#21450;&#35746;&#38405;&#35797;&#29992;&#30340;&#26435;&#34913;&#65289;&#12289;<a href="https://l.fatbobman.com/w0117-02-3">&#24341;&#23548;&#20307;&#39564;&#35774;&#35745;</a>&#65288;&#20174;&#38745;&#24577;&#25130;&#22270;&#28436;&#36827;&#21040; 8 &#27493;&#20132;&#20114;&#24335;&#24341;&#23548;&#65292;&#35753;&#29992;&#25143;&#22312;&#20184;&#36153;&#21069;&#23436;&#25104;&#26680;&#24515;&#21151;&#33021;&#20307;&#39564;&#24182;&#24314;&#31435;&#24773;&#24863;&#25237;&#20837;&#65289;&#12289;&#20197;&#21450;<a href="https://l.fatbobman.com/w0117-02-4">&#23436;&#25972;&#30340;&#25216;&#26415;&#23454;&#29616;</a>&#65288;App Store Connect &#37197;&#32622;&#12289;StoreKit &#38598;&#25104;&#12289;&#20135;&#21697;&#21152;&#36733;&#21644;&#36141;&#20080;&#27969;&#31243;&#30340;&#20195;&#30721;&#31034;&#20363;&#65289;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-03">Skip 2025 &#22238;&#39038;&#19982; 2026 &#36335;&#32447;&#22270; (Skip 2025 Retrospective and 2026 Roadmap)</a></strong></h3><p>&#22312; 2025 &#24180;&#65292;&#38543;&#30528; Swift SDK for Android &#22312; swift.org &#27491;&#24335;&#21457;&#24067;&#65292;<a href="https://x.com/skiptools">Skip</a> &#36890;&#36807; Skip Fuse &#25552;&#20379;&#21407;&#29983;&#32534;&#35793;&#25903;&#25345;&#65292;&#35299;&#38145;&#20102;&#25968;&#21315;&#20010;&#21407;&#29983; Swift &#21253;&#22312; Android &#19978;&#30340;&#20351;&#29992;&#12290;&#21516;&#26102;&#26032;&#22686; NFC&#12289;Stripe&#12289;PostHog&#12289;Auth0&#12289;Socket.IO &#31561;&#21452;&#24179;&#21488;&#26694;&#26550;&#12290;iOS 26 &#25512;&#20986;&#30340; Liquid Glass &#30028;&#38754;&#39118;&#26684;&#25104;&#20026;&#36328;&#24179;&#21488;&#26694;&#26550;&#30340;&#35797;&#37329;&#30707;&#12290;Skip &#22240;&#37319;&#29992;&#8220;&#23436;&#20840;&#21407;&#29983;&#8221;&#31574;&#30053;&#65288;iOS &#19978;&#20351;&#29992;&#21407;&#29983; SwiftUI&#65292;Android &#19978;&#26144;&#23556;&#21040; Jetpack Compose&#65289;&#32780;&#22312;&#31532;&#19968;&#22825;&#23601;&#33258;&#21160;&#25903;&#25345;&#26032;&#30028;&#38754;&#65292;&#26080;&#38656;&#37325;&#20889;&#25110;&#21464;&#36890;&#12290;&#22312; 2026 &#24180; Skip &#35745;&#21010;&#32487;&#32493;&#25193;&#23637;&#38598;&#25104;&#26694;&#26550;&#12289;&#20248;&#21270; Skip Fuse &#24037;&#20855;&#38142;&#12289;&#25552;&#21319;&#24615;&#33021;&#21644;&#24320;&#21457;&#20307;&#39564;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-04">&#22914;&#20309;&#20351;&#29992; Claude Code (How to use Claude Code)</a></strong></h3><p>&#36825;&#26159;&#19968;&#20221; <a href="https://x.com/onmyway133">Khoa Pham</a> &#22312;&#39640;&#24378;&#24230;&#20351;&#29992; Claude Code &#25968;&#26376;&#21518;&#25972;&#29702;&#30340;&#23454;&#25112;&#25351;&#21335;&#12290;&#26680;&#24515;&#25216;&#24039;&#21253;&#25324;&#21508;&#31181;&#19981;&#21516;&#27169;&#24335;&#30340;&#35814;&#32454;&#24212;&#29992;&#22330;&#26223;&#65292;&#23588;&#20854;&#26159;&#22914;&#20309;&#21512;&#29702;&#20351;&#29992; Extended Thinking &#27169;&#24335;&#20197;&#36991;&#20813;&#28010;&#36153; Token&#12290;&#21478;&#22806;&#36824;&#28085;&#30422;&#20102;&#20851;&#38190;&#24555;&#25463;&#38190;&#12289;&#19978;&#19979;&#25991;&#31649;&#29702;&#25216;&#24039;&#12289;MCP &#38598;&#25104;&#12289;VS Code &#21644; Chrome &#25193;&#23637;&#12289;GitHub Actions &#38598;&#25104;&#12289;Git Worktrees &#24182;&#34892;&#24037;&#20316;&#27969;&#12289;&#25554;&#20214;&#29983;&#24577;&#20197;&#21450;&#25552;&#31034;&#35789;&#26368;&#20339;&#23454;&#36341;&#31561;&#20247;&#22810;&#20869;&#23481;&#12290;&#20869;&#23481;&#35814;&#23454;&#12289;&#20855;&#20307;&#12289;&#26377;&#38024;&#23545;&#24615;&#65292;&#24182;&#38750;&#31616;&#21333;&#30340;&#21151;&#33021;&#20171;&#32461;&#25163;&#20876;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-05">App Store Connect API Webhook &#20018;&#25509;&#65372;&#25552;&#21319; iOS CI/CD &#33258;&#21160;&#21270;&#25928;&#29575;&#19982;&#36890;&#30693;&#27969;&#31243;</a></strong></h3><p>&#33529;&#26524;&#22312; WWDC 2025 &#20013;&#21457;&#24067;&#20102; App Store Connect API Webhook&#65292;&#25903;&#25345;&#26500;&#24314;&#29366;&#24577;&#12289;App &#29256;&#26412;&#29366;&#24577;&#12289;TestFlight &#21453;&#39304;&#31561;&#20107;&#20214;&#30340;&#23454;&#26102;&#25512;&#36865;&#12290;<a href="https://www.linkedin.com/in/zhgchgli/">Zhong Cheng</a> &#38024;&#23545;&#25171;&#21253;&#19978;&#20256;&#21518;&#20256;&#32479; Polling &#26041;&#24335;&#38656;&#31561;&#24453;&#32422; 20 &#20998;&#38047;&#65288;GitHub Runner &#28010;&#36153; $1.24/&#27425;&#65289;&#30340;&#30171;&#28857;&#65292;&#35814;&#32454;&#20171;&#32461;&#20102;&#22914;&#20309;&#22312; CI/CD &#20013;&#24212;&#29992;&#35813;&#33021;&#21147;&#65292;&#23454;&#29616;&#38646;&#31561;&#24453;&#25104;&#26412;&#65307;GitFlow &#22238; master &#26102;&#26426;&#21487;&#31934;&#30830;&#23545;&#40784; App &#23454;&#38469;&#21457;&#24067;&#26102;&#38388;&#65307;&#24320;&#21457;&#32773;&#26435;&#38480;&#21463;&#38480;&#26102;&#20063;&#33021;&#21450;&#26102;&#25910;&#21040;&#25298;&#23457;&#36890;&#30693;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-06">&#20351;&#29992; WendyOS &#24320;&#21457;&#23884;&#20837;&#24335; Linux &#24212;&#29992; (Setting up Embedded Linux with WendyOS)</a></strong></h3><p>WendyOS &#26159;&#19968;&#20010;&#19987;&#20026;&#23884;&#20837;&#24335;&#35774;&#22791;&#35774;&#35745;&#30340; Linux &#21457;&#34892;&#29256;&#65292;&#29992; Swift &#32534;&#20889;&#65292;&#26088;&#22312;&#23558; iOS &#24320;&#21457;&#30340;&#20415;&#25463;&#24615;&#24102;&#21040;&#23884;&#20837;&#24335;&#39046;&#22495;&#12290;<a href="https://x.com/JoannisOrlandos">Joannis Orlandos</a> &#22312;&#26412;&#25991;&#20013;&#25552;&#20379;&#20102;&#23436;&#25972;&#19978;&#25163;&#25945;&#31243;&#65306;&#20174;&#23433;&#35013; Homebrew &#21644; Wendy &#24037;&#20855;&#12289;&#21047;&#20889; WendyOS &#21040;&#26641;&#33683;&#27966;/Jetson Orin Nano &#31561;&#35774;&#22791;&#12289;&#36890;&#36807; USB &#36830;&#25509;&#35774;&#22791;&#12289;&#37197;&#32622; WiFi&#12289;&#21019;&#24314; Swift &#39033;&#30446;&#65288;&#21547; <code>wendy.json</code> &#26435;&#38480;&#37197;&#32622;&#65289;&#21040;&#20351;&#29992; VSCode &#25193;&#23637;&#36827;&#34892;&#36828;&#31243;&#35843;&#35797;&#65288;&#25903;&#25345;&#26029;&#28857;&#21644;&#29366;&#24577;&#26816;&#26597;&#65289;&#12290;&#36866;&#21512;&#24819;&#23558; Swift &#24212;&#29992;&#21040;&#23884;&#20837;&#24335;&#35774;&#22791;&#25110; IoT &#22330;&#26223;&#30340;&#24320;&#21457;&#32773;&#20316;&#20026;&#20837;&#38376;&#25945;&#31243;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0117-07">Swift &#24182;&#21457;&#65306;&#36890;&#20439;&#26131;&#25026;&#30340;&#23398;&#20064;&#25351;&#21335; (Fucking Approachable Swift Concurrency)</a></strong></h3><p>&#36825;&#26159;&#19968;&#20010;&#30001; <a href="https://x.com/pepicrft">Pedro Pi&#241;era</a> &#21019;&#24314;&#12289;&#22522;&#20110; <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#30340; Swift &#24182;&#21457;&#29702;&#24565;&#25972;&#29702;&#30340;&#23398;&#20064;&#36164;&#28304;&#65292;&#29992;&#36890;&#20439;&#26131;&#25026;&#30340;&#26041;&#24335;&#35299;&#37322; async/await&#12289;Task&#12289;Actor&#12289;Sendable &#31561;&#26680;&#24515;&#27010;&#24565;&#12290;Pedro &#36890;&#36807; &#8220;Office Building&#65288;&#21150;&#20844;&#27004;&#65289;&#8221; &#36825;&#19968;&#22330;&#26223;&#65292;&#23558; MainActor &#27604;&#20316;&#21069;&#21488;&#12289;actor &#27604;&#20316;&#37096;&#38376;&#21150;&#20844;&#23460;&#12289;await &#27604;&#20316;&#25970;&#38376;&#31561;&#24453;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#24314;&#31435;&#30452;&#35266;&#30340;&#24515;&#26234;&#27169;&#22411;&#12290; &#21478;&#22806;&#65292;&#36824;&#25552;&#20379;&#20102;&#19968;&#20010;&#36866;&#29992;&#20110; AI &#24037;&#20855;&#30340; Skill.md &#25991;&#20214;&#65292;&#26041;&#20415;&#24320;&#21457;&#32773;&#23558;&#19978;&#36848;&#24182;&#21457;&#23454;&#36341;&#30452;&#25509;&#23884;&#20837;&#21040;&#24320;&#21457;&#24037;&#20316;&#27969;&#30340;&#35268;&#21017;&#24341;&#25806;&#20013;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-08">Dimillian&#8217;s Skills - iOS/Swift &#24320;&#21457; AI Agent Skills &#38598;&#21512;</a></strong></h3><p><a href="https://github.com/Dimillian">Thomas Ricouard</a> &#21019;&#24314;&#30340;&#29992;&#20110; iOS/Swift &#24320;&#21457;&#30340; Skills &#20179;&#24211;&#65292;&#21253;&#21547;&#20845;&#20010;&#19987;&#27880;&#20110;&#23454;&#38469;&#24037;&#20316;&#27969;&#30340; AI Agent Skills&#12290;&#28085;&#30422; App Store Changelog &#29983;&#25104;&#65288;&#20174; git history &#33258;&#21160;&#29983;&#25104;&#21457;&#24067;&#35828;&#26126;&#65289;&#12289;iOS Debugger Agent&#65288;&#20351;&#29992; XcodeBuildMCP &#26500;&#24314;/&#35843;&#35797; iOS &#39033;&#30446;&#65289;&#12289;Swift Concurrency Expert&#65288;&#20462;&#22797; Swift 6.2 &#24182;&#21457;&#38382;&#39064;&#65289;&#12289;SwiftUI Liquid Glass&#65288;&#23454;&#29616; iOS 26+ Liquid Glass API&#65289;&#12289;SwiftUI View Refactor&#65288;&#37325;&#26500;&#35270;&#22270;&#32467;&#26500;&#21644;&#20381;&#36182;&#27169;&#24335;&#65289;&#12289;SwiftUI Performance Audit&#65288;&#23457;&#26597;&#24615;&#33021;&#29942;&#39048;&#24182;&#25552;&#20379;&#20248;&#21270;&#24314;&#35758;&#65289;&#31561;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0117-09">StoreKit Helper - SwiftUI &#24212;&#29992;&#20869;&#36141;&#20080;&#23553;&#35013;&#24211;</a></strong></h3><p>&#30001;<a href="https://x.com/jaywcjlove">jaywcjlove</a>&#24320;&#21457;&#30340;&#36731;&#37327;&#32423; StoreKit 2 &#23553;&#35013;&#24211;&#65292;&#19987;&#20026; SwiftUI &#35774;&#35745;&#65292;&#22823;&#24133;&#31616;&#21270;&#24212;&#29992;&#20869;&#36141;&#20080;&#23454;&#29616;&#12290;&#30456;&#27604;&#30452;&#25509;&#20351;&#29992; StoreKit 2 API&#65292;StoreKitHelper &#20943;&#23569;&#20102;&#32422; 70% &#30340;&#26679;&#26495;&#20195;&#30721;&#65292;&#29305;&#21035;&#36866;&#21512;&#38656;&#35201;&#24555;&#36895;&#38598;&#25104;&#24212;&#29992;&#20869;&#36141;&#20080;&#19988;&#19981;&#24819;&#22788;&#29702;&#24213;&#23618;&#22797;&#26434;&#24615;&#30340; SwiftUI &#24320;&#21457;&#32773;&#12290;</p><p>&#26680;&#24515;&#29305;&#24615;&#21253;&#25324;&#65306;&#22522;&#20110; <code>@ObservableObject</code> &#30340;&#29366;&#24577;&#31649;&#29702;&#12289;&#21327;&#35758;&#39537;&#21160;&#30340;&#31867;&#22411;&#23433;&#20840;&#20135;&#21697;&#23450;&#20041;&#12289;&#23454;&#26102;&#20132;&#26131;&#30417;&#21548;&#21644;&#33258;&#21160;&#29366;&#24577;&#26356;&#26032;&#12289;&#20869;&#32622;&#30340; <code>StoreKitHelperView</code> &#21644; <code>StoreKitHelperSelectionView</code> UI &#32452;&#20214;&#12290;&#36890;&#36807; <code>hasNotPurchased</code>/<code>hasPurchased</code> &#23646;&#24615;&#21487;&#20197;&#36731;&#26494;&#25511;&#21046;&#30028;&#38754;&#26174;&#31034;&#65292;&#25903;&#25345;&#38142;&#24335; API &#37197;&#32622;&#36141;&#20080;&#24377;&#31383;&#30340;&#21508;&#31181;&#22238;&#35843;&#12290;</p><h2><strong>&#27714;&#36132;</strong></h2><h3><strong><a href="https://github.com/photon-hq">Mac OS &#24037;&#31243;&#24072;</a></strong></h3><p><a href="https://github.com/photon-hq">Photon</a> &#27491;&#22312;&#26500;&#24314;&#24320;&#28304;&#22522;&#30784;&#35774;&#26045;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#23558; AI Agent &#24102;&#21040;&#20154;&#31867;&#24050;&#32463;&#29087;&#24713;&#30340;&#20132;&#20114;&#30028;&#38754;&#20013;&#65292;&#20363;&#22914; iMessage&#12289;WhatsApp&#12289;&#30005;&#35805;&#36890;&#35805;&#12289;Discord&#12289;Signal &#31561;&#12290;&#22312;&#27492;&#20043;&#19978;&#65292;&#25105;&#20204;&#36824;&#22312;&#25171;&#36896;&#20197;&#20132;&#20114;&#20026;&#26680;&#24515;&#30340;&#24320;&#28304; Agent SDK&#65292;&#35206;&#30422;&#22810;&#27573;&#28040;&#24687;&#22788;&#29702;&#12289;&#28040;&#24687;&#32447;&#31243;&#22788;&#29702;&#12289;&#34920;&#24773;/&#22238;&#24212;&#65288;Tapbacks&#65289;&#31561;&#33021;&#21147;&#65292;&#35753;&#24320;&#21457;&#32773;&#21644;&#20225;&#19994;&#33021;&#22815;&#24320;&#21457;&#30495;&#27491;&#8221;&#20687;&#20154;&#19968;&#26679;&#8221;&#20132;&#27969;&#30340; Agent&#12290;</p><p><strong>&#32844;&#20301;&#35201;&#27714;</strong></p><p>&#25105;&#20204;&#27491;&#22312;&#25307;&#32856; macOS &#24037;&#31243;&#24072;&#65292;&#29702;&#24819;&#30340;&#20505;&#36873;&#20154;&#24212;&#20855;&#22791;&#20197;&#19979;&#26465;&#20214;&#65306;</p><ul><li><p>&#23545; macOS &#20869;&#37096;&#26426;&#21046;&#20197;&#21450;&#31995;&#32479;&#32452;&#20214;&#20043;&#38388;&#30340;&#20132;&#20114;&#26377;&#28145;&#20837;&#29702;&#35299;</p></li><li><p>&#20855;&#22791; macOS &#31995;&#32479;&#20998;&#26512;&#19982;&#35843;&#35797;&#32463;&#39564;</p></li><li><p>&#29087;&#24713; macOS &#31995;&#32479;&#32423; API &#21450;&#24213;&#23618;&#26426;&#21046;</p></li><li><p>&#23545;&#25506;&#32034; Apple &#26381;&#21153;&#20013;&#30340;&#26410;&#30693;&#37096;&#20998;&#26377;&#22909;&#22855;&#24515;</p></li><li><p>&#21152;&#20998;&#39033;&#65306;&#26377; iMessage&#12289;IMAgent &#25110;&#30456;&#20851;&#28040;&#24687;&#22522;&#30784;&#35774;&#26045;&#30340;&#32463;&#39564;</p></li></ul><p><strong>&#34218;&#36164;&#24453;&#36935;</strong></p><p>&#25105;&#20204;&#23558;&#25552;&#20379;&#20855;&#26377;&#31454;&#20105;&#21147;&#30340;&#34218;&#36164;&#65288;&#24037;&#20316;&#22320;&#28857;&#65306;&#32654;&#22269;&#65292;&#25903;&#25345;&#36828;&#31243;&#21150;&#20844;&#65289;&#12290;&#27492;&#22806;&#65292;Photon &#33719;&#24471;&#22810;&#23478;&#30693;&#21517;&#25237;&#36164;&#26426;&#26500;&#30340;&#25903;&#25345;&#12290;</p><p><strong>&#32852;&#31995;&#26041;&#24335;</strong></p><p><a href="mailto:ryan@photon.codes">ryan@photon.codes</a></p><blockquote><p>&#36825;&#26159;&#26379;&#21451;&#21019;&#19994;&#22242;&#38431; Photon &#30340;&#25307;&#32856;&#12290;&#20182;&#20204;&#22312;&#20570; AI Agent &#22312; iMessage/WhatsApp &#31561;&#24179;&#21488;&#30340;&#22522;&#30784;&#35774;&#26045;&#65292;&#26159;&#20010;&#26089;&#26399;&#39033;&#30446;&#12290;&#22914;&#26524;&#20320;&#23545; macOS &#24213;&#23618;&#25216;&#26415;&#21644;&#26089;&#26399;&#21019;&#19994;&#26426;&#20250;&#24863;&#20852;&#36259;&#65292;&#21487;&#20197;&#20102;&#35299;&#19968;&#19979;&#12290;</p></blockquote>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #116]]></title><description><![CDATA[Swift, SwiftUI & SwiftData: A Mature 2025]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-116</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-116</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 22 Dec 2025 12:00:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!YRk2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YRk2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YRk2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YRk2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:46340,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/182224678?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YRk2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!YRk2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3417fc36-cd8f-4ef5-acff-5c9002027e77_1920x1080.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@barbirezvisual?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Barbara Rezende</a> on <a href="https://unsplash.com/photos/2-men-sitting-on-rock-formation-under-cloudy-sky-during-daytime-jB2TtTjxS_s?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Swift, SwiftUI &amp; SwiftData: A Mature 2025</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-116/">Read on web &#8594;</a></p><p>Over the past few days, I&#8217;ve been reflecting on the evolution of Swift, SwiftUI, and SwiftData throughout this year. My overall impression is that while there weren&#8217;t many &#8220;flashy&#8221; surprises, a palpable sense of maturity has quietly emerged.</p><p>Undoubtedly, the centerpiece of Swift this year was the continued refinement of the concurrency programming experience. Although the influx of new options and keywords caused its fair share of teething troubles for developers in the short term, after months of debate and practice, the community is finally beginning to consolidate best practices for this new paradigm. I don&#8217;t expect the full establishment and widespread adoption of this paradigm to be a simple or swift process. However, in a year or two, the community&#8217;s focus will likely shift from concurrency to cross-platform development, marking a brand-new phase for the language.</p><p>For SwiftUI, the focus this year was largely centered on adapting to Liquid Glass. Due to initial implementation hurdles at the system level, the visual results were somewhat underwhelming at first. However, since the release of iOS 26.2, both performance and stability have seen significant improvements. To be honest, I am actually quite pleased that SwiftUI didn&#8217;t introduce more &#8220;revolutionary&#8221; features this year. This has given both the framework team and the developers some much-needed breathing room to truly digest the existing framework. At this stage, resolving legacy issues and optimizing performance is far more meaningful than blindly piling on new features.</p><p>The trend of &#8220;subtle evolution&#8221; is most evident in SwiftData. That said, I believe SwiftData&#8217;s performance this year is highly commendable&#8212;particularly the fact that many improvements and new features were back-ported to earlier OS versions. I only wish it had been in this state when it was first released three years ago. While SwiftData still lacks some key functionalities, it is now more than capable of handling a significant proportion of projects. With this solid foundation, I look forward to its growth in performance and capability over the coming years.</p><p>Personally, I am satisfied with the &#8220;report card&#8221; delivered by the Swift trio in 2025. I wonder, how do you feel about it?</p><p>This is the final issue of the year. I want to express my heartfelt gratitude to all of you for your support and readership throughout the year.</p><p>Wishing you all a Happy New Year! Happy Coding!</p><p><a href="https://fatbobman.com/en/weekly/issue-115/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Event</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0116-08">iOS Conf SG 2026</a></strong></h3><p>Next month (January 21&#8211;23), iOS Conf SG will take place in Singapore. I&#8217;ll be there in person and will be speaking on the topic <strong>&#8220;Using SwiftUI as a Language&#8221;</strong>&#8212;a talk not just about code, but about a shift in mindset.</p><p>If you&#8217;ll be nearby or are planning to attend, feel free to come say hi! The organizers have also provided a special discount for my readers: <strong><a href="https://l.fatbobman.com/iosconfsg2026">Fatbobman reader-exclusive 10% off link</a></strong></p><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/my-eight-years-with-cloudkit/?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">My Eight Years with CloudKit: From Open Source IceCream to Commercial Apps</a></strong></h3><p>I&#8217;ve always believed that the so-called Apple ecosystem is shaped by a combination of hardware, software, services, culture, and overall sensibility. Within that ecosystem, CloudKit is undoubtedly a crucial piece. For developers, using CloudKit well not only leads to better user experiences, but also enables innovation at a relatively low cost.</p><p><a href="https://x.com/caiyue5">Cai Yue</a>, the creator of IceCream, shares his eight-year journey with CloudKit&#8212;from open-sourcing IceCream in 2017 and gaining official recognition from Apple, to applying CloudKit in real-world commercial products such as Music Mate and Setlists. The article takes a deep dive into CloudKit&#8217;s core strengths, key limitations, and more advanced usage patterns.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-01">What&#8217;s new in Swift: December 2025 Edition</a></strong></h3><p>This is a year-end wrap-up article for the Swift community, written by <a href="https://x.com/timsneath">Tim Sneath</a> and <a href="https://www.linkedin.com/in/davelester-dev/">Dave Lester</a>. It systematically reviews the major developments across the Swift ecosystem in 2025, spanning language features, platform expansion, and community growth.</p><p>The article not only summarizes how Swift 6.2 lowers the barrier to entry for concurrency through more approachable defaults&#8212;while continuing to advance C++ interoperability and memory safety&#8212;but also highlights sustained investments across Android, WASM, Windows, BSD, embedded systems, and AWS. Together, these efforts reinforce a clear signal: Swift is no longer a language focused solely on Apple platforms.</p><p>You may not agree with every change, but in the first year after entering its second decade, Swift has undeniably delivered a solid and substantial body of work.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-02">My PM insisted we switch to SwiftUI for a massive legacy app rewrite. The result is exactly what you&#8217;d expect</a></strong></h3><p>I came across this post on Reddit a few days ago. The author complains about their PM&#8217;s decision to adopt SwiftUI too casually, arguing that it is ill-suited for rewriting a seven-year-old app. I don&#8217;t fully agree or disagree with that take&#8212;but what really surprised me was the direction of the comments. The overwhelming majority firmly sided with SwiftUI.</p><p>Many developers argued that:</p><ul><li><p>SwiftUI itself is already mature enough; the real issues lie in how it&#8217;s implemented</p></li><li><p>Migration should be incremental, not a big-bang rewrite</p></li><li><p>SwiftUI&#8217;s weak spots can be avoided&#8212;for example, by keeping UIKit navigation and migrating only the view layer</p></li><li><p>Multiple large-scale projects (with over 10 years of history) have already completed successful migrations</p></li></ul><p>This discussion highlights a reality I didn&#8217;t quite expect: SwiftUI adoption in production environments is far more widespread than many assume, and developer confidence in SwiftUI is clearly established. By the end of 2025, the claim that &#8220;SwiftUI isn&#8217;t ready for serious work&#8221; may no longer hold up.</p><blockquote><p>As a strong advocate of SwiftUI, I both enjoy working with the framework and remain fully aware that it still has a long road ahead. If you&#8217;re still unsure whether SwiftUI is worth investing in, you might want to check out an article I wrote last year, <a href="https://fatbobman.com/en/posts/common-misconceptions-about-swiftui/?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">&#8220;Common Misconceptions About SwiftUI&#8221;</a>. Many of the misconceptions discussed there were echoed&#8212;and challenged&#8212;in this Reddit discussion.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-03">Non-Sendable First Design</a></strong></h3><p>With the arrival of the Swift 6 era, many developers have developed a habit: either make types conform to <code>Sendable</code>, or wrap them in <code>@MainActor</code> or an <code>actor</code>. In this article, <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> proposes a highly thought-provoking philosophy: <strong>&#8220;Non-Sendable First Design.&#8221;</strong></p><p>The key idea lies in rethinking &#8220;isolation.&#8221; Isolation is, at its core, a constraint. When a type is marked as <code>@MainActor</code>, it effectively loses the freedom to be accessed synchronously outside of UI contexts. By contrast, a non-isolated, non-Sendable plain type can be far more flexible&#8212;it can be owned by any actor and accessed synchronously within that context, while also conforming easily to basic protocols like <code>Equatable</code>, without the complexity of crossing isolation boundaries.</p><p>With the introduction of NonisolatedNonsendingByDefault in Swift, this &#8220;non-Sendable first&#8221; approach is no longer awkward or cumbersome. Instead, its advantages are becoming increasingly apparent: clearer semantics and lower architectural overhead achieved with less isolation. While it won&#8217;t fit every scenario, in Swift 6 and beyond it&#8217;s a &#8220;subtractive&#8221; design approach well worth serious consideration.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-04">Resolving Swift Packages faster With Registry from Tuist</a></strong></h3><p>Traditional Swift Package Manager dependency resolution is based on Git URLs. Xcode needs to clone entire repositories to retrieve version information and source code, which can be extremely time-consuming for projects with many dependencies (such as Firebase). Registry, on the other hand, is an alternative specification defined by Apple: it downloads archived artifacts for specific versions directly via package identifiers (IDs), bypassing the heavy Git operations.</p><p>Tuist recently announced that its Swift Package Registry is now open to all developers. The biggest change is that you no longer need to log in or create a Tuist account to use it.</p><p><a href="https://www.linkedin.com/in/gamehelper/">Lee Young-jun</a> tested the feature and found that dependency resolution (installation) time was reduced to about 35% of the original. However, project generation and build phases didn&#8217;t see the same gains, and in some cases even became slightly slower. In GitHub Actions, when combined with caching, dependency installation time for subsequent builds dropped from 53 seconds to 11 seconds&#8212;showing that the primary benefits are in CI environments.</p><p>Overall, Tuist Registry isn&#8217;t a &#8220;full pipeline accelerator,&#8221; but rather a targeted optimization focused on dependency resolution and cache friendliness. If your project has many dependencies and high CI costs, it&#8217;s well worth trying.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-05-2">iOS Timer vs DispatchSourceTimer&#65372;Safe Usage with Finite State Machine &amp; Design Patterns</a></strong></h3><p>For many developers, the most frustrating aspect of working with <code>DispatchSourceTimer</code> is its &#8220;fragile&#8221; state model: even a slight mistake in call order can lead to crashes. In this article, <a href="https://www.linkedin.com/in/zhgchgli">ZhgChgLi</a> proposes an engineering-focused solution to this highly sensitive state management problem. The article carefully outlines five common crash scenarios (such as calling <code>resume</code> repeatedly or releasing a timer while it&#8217;s suspended), and demonstrates how to use a finite state machine (FSM) to encapsulate operations, blocking illegal calls at the logic level while ensuring thread safety through a private serial queue.</p><blockquote><p>This is a hands-on case study that guides readers from &#8220;writing code&#8221; to &#8220;designing systems.&#8221; It not only explains how to correctly use GCD timers, but also shows how design patterns can turn a &#8220;dangerous&#8221; low-level API into a clear, safe, and maintainable industrial-grade component. In an era where Swift Concurrency is becoming the norm, understanding&#8212;and elegantly wrapping&#8212;these low-level GCD tools remains a core skill for senior iOS developers.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0116-06">ml-sharp: Turn Photos into 3D Scenes in Seconds</a></strong></h3><p>Apple open-sourced SHARP (Sharp Monocular View Synthesis) last week&#8212;an AI model capable of converting a single 2D photo into a 3D scene in under one second (model size: 2.8 GB). Compared to previous state-of-the-art models, it improves visual quality by 25&#8211;34% and achieves a 1000&#215; speedup.</p><p>The community widely believes SHARP could power future spatial photo features. Today, Spatial Scenes in iOS 26 rely on the Neural Engine for depth reconstruction, whereas SHARP uses the more advanced 3D Gaussian Splatting technique, resulting in significantly higher quality.</p><p>The model supports CPU, CUDA, and MPS execution, and developers have already successfully run it on M1, M2, and M3 Macs. The output <code>.ply</code> files are compatible with various 3DGS viewers, and Vision Pro users can view the results directly via Metal Splatter (<a href="https://x.com/SadlyItsBradley/status/2001294992145588232">demo</a>).</p><p>While Apple may not always stand out in general-purpose language models, its vertically focused AI models&#8212;deeply integrated with hardware and driven by clear application scenarios&#8212;continue to demonstrate strong competitiveness.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-07">MaterialView: Breaking the Limits of NSVisualEffectView</a></strong></h3><p><a href="https://x.com/oskargroth">Oskar Groth</a> (creator of <a href="https://cindori.com/sensei">Sensei</a>) has open-sourced MaterialView, a highly customizable material blur view that goes beyond the limitations of <code>NSVisualEffectView</code>. By reverse-engineering the implementation behind Control Center, Oskar achieved full control over blur radius, saturation, brightness, and tint, and documented the process in a detailed <a href="https://oskargroth.com/blog/reverse-engineering-nsvisualeffectview?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">technical article</a>.</p><p>Unlike system materials, which only allow you to &#8220;pick a type,&#8221; MaterialView fully parameterizes the blur effect. Developers can precisely control blur radius, saturation, brightness, tint color, and blend modes, while also supporting active / inactive / emphasized / accessibility states. This makes it an excellent fit for sidebars, floating panels, and utility windows where visual consistency is critical.</p><p>The library supports both SwiftUI and AppKit, and includes a demo app with real-time parameter tuning to quickly explore different material configurations.</p><blockquote><p>Note: MaterialView relies on some undocumented Core Animation capabilities (such as <code>CABackdropLayer</code> and <code>CAFilter</code>). While these APIs have been stable for years, there is still a potential risk of change in future macOS releases.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ONvE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ONvE!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 424w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 848w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 1272w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ONvE!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif" width="1158" height="942" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:942,&quot;width&quot;:1158,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;MaterialView&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="MaterialView" title="MaterialView" srcset="https://substackcdn.com/image/fetch/$s_!ONvE!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 424w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 848w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 1272w, https://substackcdn.com/image/fetch/$s_!ONvE!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27c6d331-67fc-437f-9f65-42e7648d5a01_1158x942.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-116?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-116?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>Swift&#12289;SwiftUI &#19982; SwiftData&#65306;&#36208;&#21521;&#25104;&#29087;&#30340; 2025</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-116/">&#32593;&#39029;&#29256;</a></strong></p><p>&#22312;&#36807;&#21435;&#30340;&#20960;&#22825;&#37324;&#65292;&#25105;&#22238;&#39038;&#20102;&#36825;&#19968;&#24180;&#26469; Swift&#12289;SwiftUI &#20197;&#21450; SwiftData &#30340;&#28436;&#36827;&#12290;&#24635;&#30340;&#24863;&#35273;&#26159;&#65306;&#24778;&#21916;&#34429;&#19981;&#31639;&#22810;&#65292;&#20294;&#8220;&#25104;&#29087;&#24863;&#8221;&#21364;&#22312;&#19981;&#32463;&#24847;&#38388;&#25169;&#38754;&#32780;&#26469;&#12290;</p><p>&#27595;&#24248;&#32622;&#30097;&#65292;Swift &#20170;&#24180;&#30340;&#37325;&#22836;&#25103;&#22312;&#20110;&#25913;&#21892;&#24182;&#21457;&#32534;&#31243;&#30340;&#20307;&#39564;&#12290;&#23613;&#31649;&#26032;&#22686;&#30340;&#36873;&#39033;&#21644;&#20851;&#38190;&#23383;&#22312;&#30701;&#26399;&#20869;&#21448;&#32473;&#24320;&#21457;&#32773;&#24102;&#26469;&#20102;&#19981;&#23567;&#30340;&#22256;&#25200;&#65292;&#20294;&#32463;&#36807;&#36825;&#20960;&#20010;&#26376;&#30340;&#35752;&#35770;&#19982;&#23454;&#36341;&#65292;&#31038;&#21306;&#24050;&#32463;&#26174;&#29616;&#20986;&#36880;&#28176;&#24635;&#32467;&#20986;&#26032;&#33539;&#24335;&#23454;&#36341;&#36335;&#24452;&#30340;&#36235;&#21183;&#12290;&#25105;&#19981;&#35748;&#20026;&#26032;&#33539;&#24335;&#34987;&#30830;&#31435;&#19988;&#24191;&#27867;&#25509;&#21463;&#20250;&#26159;&#19968;&#20010;&#31616;&#21333;&#12289;&#36805;&#36895;&#30340;&#36807;&#31243;&#65292;&#20294;&#25110;&#35768;&#20877;&#36807;&#19968;&#20004;&#24180;&#65292;&#24320;&#21457;&#32773;&#23545; Swift &#30340;&#35752;&#35770;&#37325;&#24515;&#23558;&#20174;&#24182;&#21457;&#36716;&#21521;&#36328;&#24179;&#21488;&#65292;&#23626;&#26102; Swift &#20063;&#23558;&#36808;&#20837;&#20840;&#26032;&#30340;&#21457;&#23637;&#38454;&#27573;&#12290;</p><p>&#20170;&#24180; SwiftUI &#30340;&#26356;&#26032;&#37325;&#24515;&#22823;&#22810;&#38598;&#20013;&#22312; Liquid Glass &#30340;&#36866;&#37197;&#19978;&#12290;&#21463;&#38480;&#20110;&#31995;&#32479;&#21021;&#26399;&#30340;&#23454;&#29616;&#65292;&#26174;&#31034;&#25928;&#26524;&#36215;&#21021;&#24182;&#19981;&#23613;&#22914;&#20154;&#24847;&#65292;&#20294;&#22312; iOS 26.2 &#29256;&#26412;&#21457;&#24067;&#21518;&#65292;&#24615;&#33021;&#19982;&#31283;&#23450;&#24615;&#37117;&#26377;&#20102;&#26174;&#33879;&#25913;&#21892;&#12290;&#22374;&#29575;&#22320;&#35828;&#65292;&#23545;&#20110;&#20170;&#24180; SwiftUI &#27809;&#26377;&#24341;&#20837;&#26356;&#22810;&#38761;&#21629;&#24615;&#30340;&#26032;&#21151;&#33021;&#65292;&#25105;&#20010;&#20154;&#26159;&#25402;&#39640;&#20852;&#30340;&#12290;&#36825;&#35753;&#26694;&#26550;&#22242;&#38431;&#21644;&#24320;&#21457;&#32773;&#37117;&#33021;&#33719;&#24471;&#19968;&#28857;&#21912;&#24687;&#20043;&#26426;&#65292;&#21435;&#36827;&#19968;&#27493;&#28040;&#21270;&#36825;&#20010;&#26694;&#26550;&#12290;&#22312;&#29616;&#38454;&#27573;&#65292;&#35299;&#20915;&#36951;&#30041;&#38382;&#39064;&#12289;&#20248;&#21270;&#24615;&#33021;&#19982;&#31283;&#23450;&#24615;&#65292;&#36828;&#27604;&#19968;&#21619;&#22534;&#30732;&#26032;&#29305;&#24615;&#26356;&#26377;&#24847;&#20041;&#12290;</p><p>&#8220;&#21464;&#21270;&#36739;&#23567;&#8221;&#22312; SwiftData &#36523;&#19978;&#20307;&#29616;&#24471;&#23588;&#20026;&#26126;&#26174;&#12290;&#20294;&#25105;&#35748;&#20026; SwiftData &#20170;&#24180;&#30340;&#34920;&#29616;&#23588;&#20026;&#20540;&#24471;&#32943;&#23450;&#65292;&#29305;&#21035;&#26159;&#35768;&#22810;&#25913;&#36827;&#19982;&#26032;&#21151;&#33021;&#37117;&#21521;&#19979;&#36866;&#37197;&#21040;&#20102;&#26356;&#26089;&#30340;&#31995;&#32479;&#29256;&#26412;&#12290;&#30495;&#24076;&#26395;&#23427;&#22312;&#19977;&#24180;&#21069;&#21021;&#27425;&#21457;&#24067;&#26102;&#65292;&#23601;&#33021;&#20855;&#22791;&#29616;&#22312;&#30340;&#29366;&#24577;&#12290;&#23613;&#31649; SwiftData &#30446;&#21069;&#20173;&#32570;&#22833;&#19968;&#20123;&#20851;&#38190;&#21151;&#33021;&#65292;&#20294;&#23545;&#20110;&#30456;&#24403;&#27604;&#20363;&#30340;&#39033;&#30446;&#32780;&#35328;&#65292;&#23427;&#24050;&#32463;&#36275;&#20197;&#32988;&#20219;&#12290;&#26377;&#20102;&#36825;&#20010;&#31283;&#22266;&#30340;&#22522;&#30784;&#65292;&#20854;&#26410;&#26469;&#20960;&#24180;&#22312;&#24615;&#33021;&#19982;&#21151;&#33021;&#19978;&#30340;&#25552;&#39640;&#38750;&#24120;&#20540;&#24471;&#26399;&#24453;&#12290;</p><p>&#23545;&#20110; 2025 &#24180; Swift &#19977;&#20214;&#22871;&#30340;&#20132;&#20986;&#30340;&#31572;&#21367;&#65292;&#25105;&#20010;&#20154;&#26159;&#28385;&#24847;&#30340;&#65292;&#19981;&#30693;&#20320;&#30340;&#24863;&#21463;&#22914;&#20309;&#65311;</p><p>&#36825;&#26159;&#26412;&#24180;&#24230;&#30340;&#26368;&#21518;&#19968;&#26399;&#21608;&#25253;&#65292;&#30001;&#34935;&#24863;&#35874;&#21508;&#20301;&#19968;&#24180;&#30340;&#38506;&#20276;&#19982;&#21402;&#29233;&#12290;</p><p>&#31069;&#22823;&#23478;&#26032;&#24180;&#24555;&#20048;&#65292;Happy Coding!</p><p><a href="https://fatbobman.com/zh/weekly/issue-115/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#27963;&#21160;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0116-08">iOS Conf SG 2026</a></strong></h3><p>&#19979;&#20010;&#26376;&#65288;1 &#26376; 21 &#26085; - 23 &#26085;&#65289;&#65292;iOS Conf SG &#23558;&#22312;&#26032;&#21152;&#22369;&#20030;&#34892;&#12290;&#25105;&#20063;&#23558;&#21069;&#24448;&#29616;&#22330;&#65292;&#24182;&#20316;&#20026;&#22025;&#23486;&#36827;&#34892;&#20027;&#39064;&#20026; <strong>&#8220;Using SwiftUI as a Language&#8221;</strong> &#30340;&#28436;&#35762;&#8212;&#8212;&#19981;&#20165;&#20851;&#20110;&#20195;&#30721;&#65292;&#26356;&#26159;&#20851;&#20110;&#24605;&#32500;&#26041;&#24335;&#30340;&#36716;&#25442;&#12290;</p><p>&#22914;&#26524;&#20320;&#20063;&#22312;&#38468;&#36817;&#65292;&#25110;&#32773;&#35745;&#21010;&#21069;&#24448;&#65292;&#27426;&#36814;&#26469;&#29616;&#22330;&#25171;&#25307;&#21628;&#65281;&#32452;&#22996;&#20250;&#19987;&#38376;&#20026;&#25105;&#30340;&#35835;&#32773;&#25552;&#20379;&#20102;&#20248;&#24800;&#65306;<strong><a href="https://l.fatbobman.com/iosconfsg2026">Fatbobman &#35835;&#32773;&#19987;&#23646;&#20061;&#25240;&#20248;&#24800;&#38142;&#25509;</a></strong></p><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/my-eight-years-with-cloudkit/?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">&#25105;&#21644; CloudKit &#30340;&#36825;&#20843;&#24180;&#65306;&#20174;&#24320;&#28304; IceCream &#21040;&#21830;&#19994;&#24212;&#29992;&#23454;&#25112;</a></strong></h3><p>&#25105;&#19968;&#30452;&#35748;&#20026;&#65292;&#25152;&#35859;&#30340;&#33529;&#26524;&#29983;&#24577;&#26159;&#30001;&#24456;&#22810;&#30340;&#30828;&#20214;&#12289;&#36719;&#20214;&#12289;&#26381;&#21153;&#12289;&#20154;&#25991;&#12289;&#27668;&#36136;&#31561;&#32508;&#21512;&#26500;&#24314;&#36215;&#26469;&#30340;&#12290;&#22312;&#36825;&#20854;&#20013;&#65292;CloudKit &#26080;&#30097;&#26159;&#38750;&#24120;&#37325;&#35201;&#30340;&#19968;&#29615;&#12290;&#32780;&#19988;&#23545;&#20110;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#29992;&#22909; CloudKit &#19981;&#20165;&#21487;&#20197;&#32473;&#29992;&#25143;&#26356;&#22909;&#30340;&#20307;&#39564;&#65292;&#20063;&#33021;&#20302;&#25104;&#26412;&#30340;&#20026;&#33258;&#24049;&#30340;&#24212;&#29992;&#24102;&#26469;&#21019;&#26032;&#12290;</p><p>IceCream &#20316;&#32773; <a href="https://x.com/caiyue5">Cai Yue</a> &#20998;&#20139;&#20182;&#19982; CloudKit &#20843;&#24180;&#30340;&#24320;&#21457;&#21382;&#31243;&#65306;&#20174; 2017 &#24180;&#24320;&#28304; IceCream &#24182;&#33719;&#24471; Apple &#23448;&#26041;&#35748;&#21487;&#65292;&#21040;&#23558; CloudKit &#24212;&#29992;&#20110; Music Mate &#21644; Setlists &#31561;&#21830;&#19994;&#39033;&#30446;&#30340;&#23454;&#25112;&#32463;&#39564;&#12290;&#25991;&#31456;&#28145;&#20837;&#25506;&#35752;&#20102; CloudKit &#30340;&#26680;&#24515;&#20248;&#21183;&#12289;&#20851;&#38190;&#23616;&#38480;&#20197;&#21450;&#36827;&#38454;&#29609;&#27861;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-01">Swift 2025 &#24180;&#24230;&#24635;&#32467; (What&#8217;s new in Swift: December 2025 Edition)</a></strong></h3><p>&#36825;&#26159;&#19968;&#31687;&#38754;&#21521; Swift &#31038;&#21306;&#30340;&#24180;&#24230;&#25910;&#23448;&#32508;&#36848;&#25991;&#31456;&#65292;&#30001; <a href="https://x.com/timsneath">Tim Sneath</a> &#21644; <a href="https://www.linkedin.com/in/davelester-dev/">Dave Lester</a> &#25776;&#20889;&#65292;&#31995;&#32479;&#22238;&#39038;&#20102; 2025 &#24180; Swift &#29983;&#24577;&#22312;&#35821;&#35328;&#29305;&#24615;&#12289;&#24179;&#21488;&#35206;&#30422;&#19982;&#31038;&#21306;&#24314;&#35774;&#26041;&#38754;&#30340;&#20851;&#38190;&#36827;&#23637;&#12290;</p><p>&#25991;&#31456;&#19981;&#20165;&#24635;&#32467;&#20102; Swift 6.2 &#22312;&#24182;&#21457;&#27169;&#22411;&#19978;&#36890;&#36807;&#26356;&#28201;&#21644;&#30340;&#40664;&#35748;&#31574;&#30053;&#38477;&#20302;&#20351;&#29992;&#38376;&#27099;&#65292;&#21516;&#26102;&#32487;&#32493;&#25512;&#36827; C++ &#20114;&#25805;&#20316;&#19982;&#20869;&#23384;&#23433;&#20840;&#33021;&#21147;&#65307;&#26356;&#37325;&#35201;&#30340;&#26159;&#65292;&#20174; Android&#12289;WASM&#12289;Windows&#12289;BSD&#12289;&#23884;&#20837;&#24335;&#21040; AWS &#31561;&#26041;&#21521;&#30340;&#25345;&#32493;&#25237;&#20837;&#65292;&#21453;&#22797;&#24378;&#21270;&#20102;&#19968;&#20010;&#28165;&#26224;&#20449;&#21495;&#8212;&#8212;Swift &#24050;&#19981;&#20877;&#21482;&#26159;&#22260;&#32469; Apple &#24179;&#21488;&#23637;&#24320;&#30340;&#35821;&#35328;&#12290;</p><p>&#25110;&#35768;&#20320;&#26410;&#24517;&#20250;&#35748;&#21516;&#20854;&#20013;&#30340;&#27599;&#19968;&#39033;&#21464;&#21270;&#65292;&#20294;&#22312;&#36808;&#20837;&#31532;&#20108;&#20010;&#21313;&#24180;&#21518;&#30340;&#31532;&#19968;&#20010;&#24180;&#22836;&#37324;&#65292;Swift &#20381;&#28982;&#20132;&#20986;&#20102;&#19968;&#20221;&#30456;&#24403;&#25166;&#23454;&#30340;&#31572;&#21367;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-02">&#20851;&#20110; SwiftUI &#30340;&#35752;&#35770; (My PM insisted we switch to SwiftUI for a massive legacy app rewrite. The result is exactly what you&#8217;d expect)</a></strong></h3><p>&#20960;&#22825;&#21069;&#26080;&#24847;&#38388;&#22312; Reddit &#19978;&#30475;&#21040;&#30340;&#24086;&#23376;&#65292;&#20316;&#32773;&#23545; PM &#36731;&#26131;&#36873;&#25321; SwiftUI &#26377;&#25152;&#25265;&#24616;&#65292;&#35748;&#20026;&#20854;&#26080;&#27861;&#32988;&#20219;&#20182;&#20204;&#19968;&#20010;&#19971;&#24180;&#21069;&#24320;&#21457;&#30340;&#24212;&#29992;&#36716;&#25442;&#12290;&#23545;&#20110;&#36825;&#20010;&#35266;&#28857;&#25105;&#19981;&#32622;&#21487;&#21542;&#65292;&#20294;&#35780;&#35770;&#21306;&#30340;&#36208;&#21521;&#21364;&#20986;&#20046;&#24847;&#26009;&#8212;&#8212;&#32477;&#22823;&#22810;&#25968;&#21442;&#19982;&#32773;&#37117;&#22362;&#23450;&#22320;&#31449;&#22312;&#20102; SwiftUI &#30340;&#19968;&#36793;&#12290;</p><p>&#22823;&#37327;&#24320;&#21457;&#32773;&#35748;&#20026;&#65306;</p><ul><li><p>SwiftUI &#26412;&#36523;&#24050;&#32463;&#36275;&#22815;&#25104;&#29087;&#65292;&#38382;&#39064;&#20986;&#22312;&#23454;&#26045;&#26041;&#24335;&#19978;</p></li><li><p>&#24212;&#35813;&#28176;&#36827;&#24335;&#36801;&#31227;&#65292;&#32780;&#19981;&#26159;&#19968;&#27425;&#24615;&#37325;&#20889;</p></li><li><p>&#36991;&#24320; SwiftUI &#30340;&#24369;&#39033;&#8212;&#8212;&#27604;&#22914;&#21487;&#20197;&#20445;&#30041; UIKit &#23548;&#33322;&#65292;&#21482;&#36801;&#31227;&#35270;&#22270;&#23618;</p></li><li><p>&#22810;&#20010;&#22823;&#22411;&#39033;&#30446;&#65288;10+ &#24180;&#21382;&#21490;&#65289;&#24050;&#25104;&#21151;&#23436;&#25104;&#36801;&#31227;</p></li></ul><p>&#36825;&#20010;&#24086;&#23376;&#23637;&#29616;&#20102;&#19968;&#20010;&#20986;&#20046;&#25105;&#39044;&#26009;&#30340;&#29616;&#23454;&#65306;SwiftUI &#22312;&#23454;&#38469;&#29983;&#20135;&#29615;&#22659;&#20013;&#30340;&#37319;&#29992;&#29575;&#27604;&#25105;&#20204;&#24819;&#35937;&#30340;&#39640;&#24471;&#22810;&#65307;&#24320;&#21457;&#32773;&#31038;&#21306;&#23545; SwiftUI &#30340;&#20449;&#24515;&#24050;&#32463;&#24314;&#31435;&#12290;&#22312; 2025 &#24180;&#24213;&#65292;&#8220;SwiftUI &#38590;&#22570;&#22823;&#20219;&#8221;&#30340;&#35770;&#35843;&#25110;&#35768;&#24050;&#32463;&#31449;&#19981;&#20303;&#33050;&#20102;&#12290;</p><blockquote><p>&#20316;&#20026; SwiftUI &#26694;&#26550;&#30340;&#25512;&#23815;&#32773;&#65292;&#25105;&#26082;&#21916;&#27426;&#35813;&#26694;&#26550;&#65292;&#20063;&#24456;&#28165;&#26970;&#23427;&#20173;&#26377;&#24456;&#38271;&#30340;&#36335;&#35201;&#36208;&#12290;&#22914;&#26524;&#20320;&#20173;&#22312;&#29369;&#35947;&#26159;&#21542;&#24212;&#35813;&#22312; SwiftUI &#19978;&#19979;&#21151;&#22827;&#65292;&#25110;&#35768;&#21487;&#20197;&#30475;&#19968;&#19979;&#25105;&#22312;&#21435;&#24180;&#20889;&#30340;<a href="https://fatbobman.com/zh/posts/common-misconceptions-about-swiftui/?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">&#12298;&#20960;&#20010;&#24120;&#35265;&#30340;&#20851;&#20110; SwiftUI &#30340;&#35823;&#35299;&#12299;</a>&#8212;&#8212;&#36825;&#31687;&#25991;&#31456;&#35752;&#35770;&#30340;&#24456;&#22810;&#35823;&#35299;&#65292;&#24688;&#22909;&#22312;&#36825;&#27425; Reddit &#35752;&#35770;&#20013;&#24471;&#21040;&#20102;&#21360;&#35777;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-03">&#38750; Sendable &#20248;&#20808;&#35774;&#35745; (Non-Sendable First Design)</a></strong></h3><p>&#38543;&#30528; Swift 6 &#26102;&#20195;&#30340;&#21040;&#26469;&#65292;&#24320;&#21457;&#32773;&#36880;&#28176;&#20859;&#25104;&#20102;&#19968;&#31181;&#24815;&#24615;&#65306;&#35201;&#20040;&#35753;&#31867;&#22411;&#31526;&#21512; <code>Sendable</code>&#65292;&#35201;&#20040;&#32473;&#23427;&#22871;&#19978; <code>@MainActor</code> &#25110; <code>actor</code>&#12290;&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#25552;&#20986;&#20102;&#19968;&#20010;&#26497;&#20855;&#21551;&#21457;&#24615;&#30340;&#21746;&#23398;&#65306;<strong>&#8220;&#38750; Sendable &#20248;&#20808;&#35774;&#35745;&#8221;</strong>&#12290;</p><p>&#36825;&#19968;&#24605;&#36335;&#30340;&#20851;&#38190;&#22312;&#20110;&#23545;&#8220;&#38548;&#31163;&#65288;Isolation&#65289;&#8221;&#30340;&#37325;&#26032;&#35748;&#35782;&#65306;&#38548;&#31163;&#26412;&#36523;&#26159;&#19968;&#31181;&#32422;&#26463;&#12290;&#24403;&#19968;&#20010;&#31867;&#22411;&#34987;&#26631;&#35760;&#20026; <code>@MainActor</code>&#65292;&#23427;&#23454;&#38469;&#19978;&#23601;&#22833;&#21435;&#20102;&#22312;&#38750; UI &#29615;&#22659;&#19979;&#36827;&#34892;&#21516;&#27493;&#35843;&#29992;&#30340;&#33258;&#30001;&#24230;&#12290;&#30456;&#27604;&#20043;&#19979;&#65292;&#19968;&#20010;&#38750;&#38548;&#31163;&#12289;&#38750; Sendable &#30340;&#26222;&#36890;&#31867;&#22411;&#21453;&#32780;&#20855;&#26377;&#26356;&#39640;&#30340;&#36890;&#29992;&#24615;&#8212;&#8212;&#23427;&#21487;&#20197;&#34987;&#20219;&#24847; Actor &#25345;&#26377;&#65292;&#24182;&#22312;&#20854;&#20869;&#37096;&#23433;&#20840;&#22320;&#36827;&#34892;&#21516;&#27493;&#35775;&#38382;&#65292;&#21516;&#26102;&#20063;&#26356;&#23481;&#26131;&#36981;&#24490; <code>Equatable</code> &#31561;&#22522;&#30784;&#21327;&#35758;&#65292;&#32780;&#26080;&#38656;&#22788;&#29702;&#36328;&#38548;&#31163;&#22495;&#24102;&#26469;&#30340;&#22797;&#26434;&#24615;&#12290;</p><p>&#38543;&#30528; Swift &#24341;&#20837; NonisolatedNonsendingByDefault&#65292;&#36825;&#31181;&#8220;&#38750; Sendable &#20248;&#20808;&#8221;&#30340;&#35774;&#35745;&#36335;&#24452;&#19981;&#20877;&#20687;&#36807;&#21435;&#37027;&#26679;&#31528;&#37325;&#25110;&#21035;&#25197;&#65292;&#21453;&#32780;&#36880;&#28176;&#26174;&#29616;&#20986;&#20854;&#20248;&#21183;&#65306;&#20197;&#26356;&#23569;&#30340;&#38548;&#31163;&#12289;&#25442;&#21462;&#26356;&#28165;&#26224;&#30340;&#35821;&#20041;&#19982;&#26356;&#20302;&#30340;&#26550;&#26500;&#36127;&#25285;&#12290;&#36825;&#25110;&#35768;&#24182;&#38750;&#36866;&#29992;&#20110;&#25152;&#26377;&#22330;&#26223;&#65292;&#20294;&#22312; Swift 6 &#20043;&#21518;&#65292;&#23427;&#24050;&#32463;&#25104;&#20026;&#19968;&#31181;&#20540;&#24471;&#35748;&#30495;&#32771;&#34385;&#30340;&#12289;&#31526;&#21512;&#35821;&#35328;&#30452;&#35273;&#30340;&#8220;&#20943;&#27861;&#8221;&#26041;&#26696;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-04">&#20351;&#29992; Registry &#21152;&#36895;&#20381;&#36182;&#35299;&#26512; (Resolving Swift Packages faster With Registry from Tuist)</a></strong></h3><p>&#20256;&#32479;&#30340; SPM &#20381;&#36182;&#35299;&#26512;&#26159;&#22522;&#20110; Git URL &#30340;&#65292;Xcode &#38656;&#35201;&#20811;&#38534;&#25972;&#20010; Git &#20179;&#24211;&#26469;&#33719;&#21462;&#29256;&#26412;&#20449;&#24687;&#21644;&#20195;&#30721;&#65292;&#36825;&#22312;&#20381;&#36182;&#36739;&#22810;&#65288;&#22914; Firebase&#65289;&#26102;&#38750;&#24120;&#32791;&#26102;&#12290;&#32780; Registry &#26159;&#33529;&#26524;&#23450;&#20041;&#30340;&#21478;&#19968;&#31181;&#35268;&#33539;&#65306;&#36890;&#36807;&#21253;&#30340;&#26631;&#35782;&#31526;&#65288;ID&#65289;&#30452;&#25509;&#19979;&#36733;&#29305;&#23450;&#29256;&#26412;&#30340;&#24402;&#26723;&#25991;&#20214;&#65292;&#36339;&#36807;&#20102;&#32321;&#37325;&#30340; Git &#25805;&#20316;&#12290;Tuist &#26368;&#36817;&#23459;&#24067;&#23558;&#20854; Swift Package Registry &#21151;&#33021;&#21521;&#25152;&#26377;&#24320;&#21457;&#32773;&#24320;&#25918;&#65292;&#26368;&#22823;&#30340;&#21464;&#21270;&#26159;&#29616;&#22312;&#26080;&#38656;&#30331;&#24405;&#25110;&#21019;&#24314; Tuist &#36134;&#21495;&#21363;&#21487;&#20351;&#29992;&#12290;</p><p><a href="https://www.linkedin.com/in/gamehelper/">Lee Young-jun</a> &#23454;&#27979;&#21457;&#29616;&#65292;&#20351;&#29992; Registry &#21518;&#65292;&#20381;&#36182;&#35299;&#26512;&#65288;Installation&#65289;&#26102;&#38388;&#32553;&#30701;&#33267;&#21407;&#26469;&#30340;&#32422; 35%&#65307;&#20294;&#39033;&#30446;&#29983;&#25104;&#19982;&#26500;&#24314;&#38454;&#27573;&#24182;&#26410;&#33719;&#24471;&#21516;&#31561;&#25910;&#30410;&#65292;&#29978;&#33267;&#30053;&#26377;&#22238;&#36864;&#12290;&#22312; GitHub Actions &#20013;&#37197;&#21512;&#32531;&#23384;&#20351;&#29992;&#26102;&#65292;&#20108;&#27425;&#26500;&#24314;&#30340;&#20381;&#36182;&#23433;&#35013;&#26102;&#38388;&#21017;&#20174; 53s &#38477;&#33267; 11s&#65292;&#20248;&#21183;&#20027;&#35201;&#20307;&#29616;&#22312; CI &#22330;&#26223;&#12290;</p><p>&#24635;&#20307;&#26469;&#30475;&#65292;Tuist Registry &#24182;&#38750;&#8220;&#20840;&#27969;&#31243;&#21152;&#36895;&#22120;&#8221;&#65292;&#32780;&#26159;&#19968;&#20010;&#19987;&#27880;&#20110;&#20381;&#36182;&#35299;&#26512;&#19982;&#32531;&#23384;&#21451;&#22909;&#24615;&#30340;&#20248;&#21270;&#28857;&#12290;&#22914;&#26524;&#20320;&#30340;&#39033;&#30446;&#20381;&#36182;&#25968;&#37327;&#24222;&#22823;&#12289;CI &#25104;&#26412;&#36739;&#39640;&#65292;&#23427;&#20540;&#24471;&#20248;&#20808;&#23581;&#35797;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-05-1">iOS Timer &#19982; DispatchSourceTimer &#36873;&#25321;&#19982;&#23433;&#20840;&#23553;&#35013;&#25216;&#24039;&#65372;&#26377;&#38480;&#29366;&#24577;&#26426;&#38450;&#27490;&#38378;&#36864;</a></strong></h3><p>&#24456;&#22810;&#24320;&#21457;&#32773;&#22312;&#22788;&#29702; <code>DispatchSourceTimer</code> &#26102;&#65292;&#26368;&#22836;&#30140;&#30340;&#23601;&#26159;&#23427;&#37027;&#8220;&#26131;&#30862;&#8221;&#30340;&#29366;&#24577;&#65306;&#35843;&#29992;&#39034;&#24207;&#31245;&#26377;&#19981;&#23545;&#20415;&#20250;&#24341;&#21457;&#38378;&#36864;&#12290;<a href="https://x.com/zhgchgli">ZhgChgLi</a> &#22312;&#26412;&#25991;&#20013;&#38024;&#23545;&#36825;&#31181;&#26497;&#20854;&#25935;&#24863;&#30340;&#29366;&#24577;&#31649;&#29702;&#25552;&#20986;&#20102;&#24037;&#31243;&#21270;&#30340;&#35299;&#20915;&#26041;&#26696;&#12290;&#25991;&#31456;&#35814;&#23613;&#21015;&#20030;&#20102;&#23548;&#33268;&#23849;&#28291;&#30340;&#20116;&#22823;&#24120;&#35265;&#22330;&#26223;&#65288;&#22914;&#37325;&#22797; resume&#12289;suspend &#29366;&#24577;&#19979;&#30452;&#25509;&#37322;&#25918;&#31561;&#65289;&#65292;&#24182;&#20998;&#20139;&#20102;&#22914;&#20309;&#21033;&#29992;&#26377;&#38480;&#29366;&#24577;&#26426; (FSM) &#23553;&#35013;&#25805;&#20316;&#65292;&#20174;&#36923;&#36753;&#23618;&#23631;&#34109;&#38750;&#27861;&#35843;&#29992;&#65292;&#21516;&#26102;&#37197;&#21512;&#31169;&#26377;&#20018;&#34892;&#38431;&#21015;&#30830;&#20445;&#22810;&#32447;&#31243;&#29615;&#22659;&#19979;&#30340;&#35843;&#29992;&#23433;&#20840;&#12290;</p><blockquote><p>&#36825;&#26159;&#19968;&#31687;&#24341;&#23548;&#35835;&#32773;&#20174;&#8220;&#20889;&#20195;&#30721;&#8221;&#36716;&#21521;&#8220;&#20570;&#35774;&#35745;&#8221;&#30340;&#23454;&#25112;&#26696;&#20363;&#12290;&#23427;&#19981;&#20165;&#35762;&#28165;&#20102; GCD &#23450;&#26102;&#22120;&#30340;&#27491;&#30830;&#20351;&#29992;&#26041;&#24335;&#65292;&#26356;&#23637;&#31034;&#20102;&#22914;&#20309;&#20511;&#21161;&#35774;&#35745;&#27169;&#24335;&#65292;&#23558;&#19968;&#20010;&#8220;&#21361;&#38505;&#8221;&#30340;&#24213;&#23618; API&#65292;&#23553;&#35013;&#20026;&#35821;&#20041;&#28165;&#26224;&#12289;&#20351;&#29992;&#23433;&#20840;&#12289;&#21487;&#38271;&#26399;&#32500;&#25252;&#30340;&#24037;&#19994;&#32423;&#32452;&#20214;&#12290;&#22312; Swift Concurrency &#26085;&#30410;&#25104;&#20026;&#20027;&#27969;&#30340;&#20170;&#22825;&#65292;&#29702;&#35299;&#24182;&#20248;&#38597;&#22320;&#23553;&#35013;&#36825;&#20123;&#24213;&#23618; GCD &#24037;&#20855;&#65292;&#20381;&#28982;&#26159;&#39640;&#32423; iOS &#24320;&#21457;&#32773;&#30340;&#37325;&#35201;&#22522;&#26412;&#21151;&#12290;</p></blockquote><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0116-06">ml-sharp&#65306;&#29031;&#29255;&#31186;&#21464; 3D &#22330;&#26223;</a></strong></h3><p>&#33529;&#26524;&#22312;&#19978;&#21608;&#24320;&#28304;&#20102; SHARP (Sharp Monocular View Synthesis)&#65292;&#19968;&#20010;&#33021;&#22312;&#19981;&#21040; 1 &#31186;&#20869;&#23558;&#21333;&#24352; 2D &#29031;&#29255;&#36716;&#25442;&#20026; 3D &#22330;&#26223;&#30340; AI &#27169;&#22411;&#65288;&#27169;&#22411;&#22823;&#23567; 2.8 GB&#65289;&#12290;&#30456;&#27604;&#20043;&#21069;&#30340;&#26368;&#20339;&#27169;&#22411;&#65292;&#35270;&#35273;&#36136;&#37327;&#25552;&#21319; 25-34%&#65292;&#36895;&#24230;&#25552;&#21319; 1000 &#20493;&#12290;</p><p>&#31038;&#21306;&#26222;&#36941;&#35748;&#20026; SHARP &#21487;&#33021;&#29992;&#20110;&#26410;&#26469;&#29256;&#26412;&#30340;&#31354;&#38388;&#29031;&#29255;&#21151;&#33021;&#12290;&#30446;&#21069; iOS 26 &#30340; Spatial Scenes &#20351;&#29992; Neural Engine &#36827;&#34892;&#28145;&#24230;&#37325;&#24314;&#65292;&#32780; SHARP &#37319;&#29992;&#26356;&#20808;&#36827;&#30340; 3D Gaussian Splatting &#25216;&#26415;&#65292;&#36136;&#37327;&#26174;&#33879;&#25552;&#21319;&#12290;</p><p>&#27169;&#22411;&#25903;&#25345; CPU/CUDA/MPS &#36816;&#34892;&#65292;&#24050;&#26377;&#24320;&#21457;&#32773;&#22312; M1/M2/M3 Mac &#19978;&#25104;&#21151;&#36816;&#34892;&#12290;&#36755;&#20986;&#30340; .ply &#25991;&#20214;&#20860;&#23481;&#21508;&#31181; 3DGS &#26597;&#30475;&#22120;&#65292;Vision Pro &#29992;&#25143;&#21487;&#36890;&#36807; Metal Splatter &#30452;&#25509;<a href="https://x.com/SadlyItsBradley/status/2001294992145588232">&#26597;&#30475;&#25928;&#26524;</a>&#12290;</p><p>&#23613;&#31649;&#33529;&#26524;&#22312;&#36890;&#29992;&#35821;&#35328;&#22823;&#27169;&#22411;&#19978;&#19981;&#22914;&#31454;&#20105;&#23545;&#25163;&#24778;&#33395;&#65292;&#20294;&#22312;&#22402;&#30452;&#22330;&#26223;&#30340; AI &#27169;&#22411;&#19978;&#65292;&#20973;&#20511;&#30828;&#20214;&#28145;&#24230;&#25972;&#21512;&#19982;&#26126;&#30830;&#30340;&#24212;&#29992;&#23548;&#21521;&#65292;&#20381;&#28982;&#23637;&#29616;&#20986;&#24378;&#22823;&#30340;&#31454;&#20105;&#21147;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0116-07">MaterialView: &#31361;&#30772; NSVisualEffectView &#38480;&#21046;&#30340;&#27611;&#29627;&#29827;&#35270;&#22270;</a></strong></h3><p><a href="https://x.com/oskargroth">Oskar Groth</a> (<a href="https://cindori.com/sensei">Sensei</a> &#20316;&#32773;)&#24320;&#28304;&#20102; MaterialView&#65292;&#19968;&#20010;&#33021;&#22815;&#31361;&#30772; <code>NSVisualEffectView</code> &#38480;&#21046;&#30340;&#39640;&#24230;&#21487;&#23450;&#21046;&#27611;&#29627;&#29827;&#35270;&#22270;&#24211;&#12290;&#36890;&#36807;&#36870;&#21521; Control Center &#30340;&#23454;&#29616;&#65292;Oskar &#23454;&#29616;&#20102;&#23545;&#27169;&#31946;&#21322;&#24452;&#12289;&#39281;&#21644;&#24230;&#12289;&#20142;&#24230;&#21644;&#33394;&#35843;&#30340;&#23436;&#20840;&#25511;&#21046;&#65292;&#24182;&#25776;&#20889;&#20102;&#35814;&#32454;&#30340;<a href="https://oskargroth.com/blog/reverse-engineering-nsvisualeffectview?utm_source=fatbobman%20weekly%20issue%20116&amp;utm_medium=web">&#25216;&#26415;&#25991;&#31456;</a>&#35762;&#35299;&#23454;&#29616;&#21407;&#29702;&#12290;</p><p>&#19982;&#31995;&#32479;&#21407;&#29983;&#26448;&#36136;&#21482;&#33021;&#8220;&#36873;&#31867;&#22411;&#8221;&#19981;&#21516;&#65292;MaterialView &#23558;&#27169;&#31946;&#25928;&#26524;&#24443;&#24213;&#21442;&#25968;&#21270;&#65292;&#20801;&#35768;&#24320;&#21457;&#32773;&#31934;&#30830;&#25511;&#21046;&#27169;&#31946;&#21322;&#24452;&#12289;&#39281;&#21644;&#24230;&#12289;&#20142;&#24230;&#12289;tint &#39068;&#33394;&#19982;&#28151;&#21512;&#27169;&#24335;&#65292;&#24182;&#25903;&#25345; active / inactive / emphasized / accessibility &#31561;&#29366;&#24577;&#37197;&#32622;&#12290;&#36825;&#20351;&#24471;&#23427;&#38750;&#24120;&#36866;&#21512;&#29992;&#20110;&#20391;&#36793;&#26639;&#12289;&#28014;&#23618;&#38754;&#26495;&#12289;&#24037;&#20855;&#31383;&#21475;&#31561;&#23545;&#35270;&#35273;&#19968;&#33268;&#24615;&#35201;&#27714;&#26497;&#39640;&#30340;&#22330;&#26223;&#12290;</p><p>&#35813;&#24211;&#21516;&#26102;&#25903;&#25345; SwiftUI &#19982; AppKit&#65292;&#24182;&#25552;&#20379;&#20102;&#19968;&#20010;&#21487;&#23454;&#26102;&#35843;&#21442;&#30340; Demo App&#65292;&#26041;&#20415;&#24555;&#36895;&#25506;&#32034;&#19981;&#21516;&#26448;&#36136;&#32452;&#21512;&#30340;&#25928;&#26524;&#12290;</p><blockquote><p>&#38656;&#35201;&#27880;&#24847;&#30340;&#26159;&#65292;&#23427;&#20381;&#36182;&#37096;&#20998;&#26410;&#20844;&#24320;&#30340; Core Animation &#33021;&#21147;&#65288;&#22914; <code>CABackdropLayer</code>&#12289;<code>CAFilter</code> &#31561;&#65289;&#12290;&#23613;&#31649;&#36825;&#20123; API &#22810;&#24180;&#26469;&#30456;&#24403;&#31283;&#23450;&#65292;&#20294;&#20173;&#23384;&#22312;&#26410;&#26469;&#31995;&#32479;&#29256;&#26412;&#21464;&#21160;&#30340;&#28508;&#22312;&#39118;&#38505;&#12290;</p></blockquote>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #115]]></title><description><![CDATA[A Sunday Incident]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-115</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-115</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 15 Dec 2025 12:01:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!lKk3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lKk3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lKk3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 424w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 848w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 1272w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lKk3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp" width="1200" height="628" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8158,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/181573861?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lKk3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 424w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 848w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 1272w, https://substackcdn.com/image/fetch/$s_!lKk3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff40eade5-9548-4dea-b171-b69733b34e46_1200x628.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>A Sunday Incident</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-115/">Read on web &#8594;</a></p><p>Sunday afternoon, I was preparing Monday&#8217;s weekly newsletter as usual. The moment I stood up, my right pinky finger seemed to bump into something, and then it wouldn&#8217;t straighten.</p><p>Somewhat bizarre&#8212;no pain, no swelling, but just couldn&#8217;t extend. The ER doctor&#8217;s initial assessment was pinky extensor tendon injury. I scheduled further examination for Monday, and surgery will likely be needed for repair.</p><p>It was only then that I realized how important this usually low-profile pinky finger is. Now wearing a finger splint, typing has become significantly difficult. Fortunately, it shouldn&#8217;t be anything serious, just that I&#8217;ll be typing less for a while.</p><p>Life is unpredictable; face it with a smile.</p><p><strong>Monday Update</strong>: After further examination today, they found no fracture requiring reduction, just a simple tendon rupture. This means no surgery needed&#8212;just wearing the finger splint for 6 weeks should restore it to normal.</p><p><a href="https://fatbobman.com/en/weekly/issue-114/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/watchos-development-pitfalls-and-practical-tips/?utm_source=fatbobman%20weekly%20issue%20115&amp;utm_medium=web">From YaoYao to Tooboo: watchOS Development Pitfalls and Practical Tips</a></strong></h3><p>As the creator of popular watchOS apps YaoYao, Tooboo, and DunDun, <a href="https://yaoyaojumprope.com/about">Haozes</a> shares high-quality practical experience in watchOS development, covering version compatibility, app wake-up communication, data synchronization, restart recovery, memory leaks, and battery optimization. This article encompasses a complete guide from HealthKit to WCSession, from HKWorkoutSession to TimelineSchedule, providing invaluable reference for developers who are building or planning to build Apple Watch applications.</p><blockquote><p>As a long-time Apple Watch user and Swift blogger, I often marvel at the &#8220;mystique&#8221; of watchOS development&#8212;countless details beyond the documentation, with very few truly in-depth practical articles available online. For this reason, I specially invited Haozes, a leading independent developer in the watchOS space, to share his development insights.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-01">My journey to Swift 6 and Strict Concurrency</a></strong></h3><p>A crash that &#8220;only appeared on real user devices&#8221; forced <a href="https://www.linkedin.com/in/irvingpop/overlay/about-this-profile/">Irving Popovetsky</a> to migrate an entire production iOS app to Swift 6 + Strict Concurrency. This article comprehensively documents the journey from the initial 76 errors and 238 warnings, through the gradual introduction of <code>@preconcurrency</code>, <code>actor</code>, <code>@MainActor</code>, <code>Sendable</code>, and <code>nonisolated(unsafe)</code>, to verification with real devices and Thread Sanitizer. Irving points out that Swift 6&#8217;s runtime validates actor isolation the moment a closure is called&#8212;even if you use <code>Task { @MainActor in }</code> inside the closure, it may be too late. The article provides clear, reusable patterns for addressing this behavior.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-02">Monitoring app performance with MetricKit</a></strong></h3><p>MetricKit is a system-level performance diagnostics framework introduced by Apple in iOS 13, designed to provide developers with app performance and stability data from real user devices. It only works in real device environments, with data sourced from long-term sampling and aggregation by the system in the background, thus more accurately reflecting app behavior in actual usage scenarios.</p><p>In this article, <a href="https://x.com/mecid">Majid Jabrayilov</a> demonstrates how to subscribe to system-level performance data through <code>MXMetricManager</code>, progressively extracting and reporting key metrics from background abnormal exits, CPU/memory resource limits, to crash diagnostics, thereby building a more complete and traceable app performance monitoring dashboard. Majid also specifically reminds readers that MetricKit data is typically aggregated and delivered daily rather than in real-time callbacks, and actual analysis requires understanding the time range covered by each payload in combination with timestamps.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-03">Rebuilding MistKit with Claude Code - From CloudKit Docs to Type-Safe Swift</a></strong></h3><p>When <a href="https://x.com/leogdion">Leo Dion</a> rebuilt MistKit, his long-dormant CloudKit server-side library, he discovered that <a href="https://github.com/apple/swift-openapi-generator">swift-openapi-generator</a> could significantly reduce refactoring complexity: by simply converting CloudKit&#8217;s REST documentation into OpenAPI specifications, he could automatically generate large-scale, type-safe Swift client code. To this end, he brought in Claude Code, specifically responsible for the translation work &#8220;from Apple documentation to OpenAPI YAML.&#8221;</p><p>The most valuable aspect of the article isn&#8217;t &#8220;how much code AI generated,&#8221; but rather how Leo uses AI. He didn&#8217;t let Claude directly implement MistKit, but positioned it as a &#8220;documentation translator and pattern amplifier,&#8221; while keeping the truly complex parts requiring engineering judgment and architectural trade-offs under his own control. Rather than having AI directly &#8220;write code,&#8221; it&#8217;s better to have it <strong>turn complex problems into generatable, verifiable problems</strong>&#8212;this is the most valuable lesson from this MistKit rebuilding process.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-04">I Reverse Engineered ChatGPT&#8217;s Memory System, and Here&#8217;s What I Found!</a></strong></h3><p>Through extensive conversation experiments, <a href="https://x.com/manthanguptaa">Manthan Gupta</a> reverse-engineered ChatGPT&#8217;s &#8220;memory&#8221; behavior and found its implementation far simpler than imagined: no vector database, no RAG across historical conversations, but rather composed of four layers of context&#8212;one-time injected Session Metadata, explicitly stored long-term user memories, lightweight summaries of recent conversations, and a sliding window of the current session. Manthan believes this design has obvious advantages in performance, latency, and token costs: trading pre-computed summaries and explicit fact injection for &#8220;good enough&#8221; continuity, rather than expensive full historical retrieval. Manthan also has <a href="https://l.fatbobman.com/w0115-05">another study on Claude&#8217;s memory system</a>.</p><blockquote><p>When using ChatGPT, I&#8217;m often surprised by how much it knows about me. Although I understand this &#8220;familiarity&#8221; comes from its memory and context mechanisms, this is also one of the important reasons why I&#8217;ve long preferred using the official client. Of course, if you&#8217;re particularly sensitive about privacy, this capability itself might be exactly the part you&#8217;re unwilling to accept.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-06">Swift Configuration 1.0 released</a></strong></h3><p><a href="https://bsky.app/profile/czechboy0.dev">Honza Dvorsky</a> announced the official release of Swift Configuration 1.0 on the Swift official blog. This library provides a unified, type-safe configuration reading abstraction for Swift applications and libraries. The key isn&#8217;t about supporting how many configuration formats, but completely separating &#8220;how configuration is read&#8221; from &#8220;where configuration comes from.&#8221; This design is particularly important for library authors&#8212;libraries can accept configuration without binding to specific sources, thus maintaining good composability across different deployment environments. With the 1.0 release, Swift Configuration&#8217;s API has entered a stable phase and is being explored for integration by projects like Vapor and Hummingbird.</p><blockquote><p>At first glance, introducing such an abstraction layer for configuration management seems somewhat &#8220;heavyweight,&#8221; but once configuration sources are no longer limited to a single file, or when code needs to be reused across different environments and projects, the advantages in structural clarity and extensibility quickly become apparent.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-07">TCA Architecture: A Glorified Antipattern</a></strong></h3><p>This is an extremely opinionated long-form article. <a href="https://medium.com/@redhotbits">Lazar Otasevic</a> systematically argues against TCA&#8217;s <code>Action</code> enum + <code>Reducer</code> core design from the perspective of functional programming and SwiftUI&#8217;s runtime model, considering it a classic antipattern of &#8220;encoding behavior as data&#8221; that unnecessarily takes away SwiftUI&#8217;s inherent state ownership. Unlike many &#8220;anti-TCA&#8221; discussions that remain at the emotional or preference level, this article provides a complete, runnable alternative approach: treating <strong>State</strong> as pure data, <strong>Logic</strong> as stateless implementation details, and exposing behavior through closures (capabilities), thereby maintaining testability and composability while better aligning with SwiftUI&#8217;s declarative data flow model.</p><blockquote><p>Considering the period when TCA first emerged, many developers still struggled with <code>ObservableObject</code>&#8216;s insufficient response granularity, lack of <code>@MainActor</code> and <code>Task</code> tools, and heavy reliance on Combine for asynchronous calls&#8212;TCA effectively solved a series of pain points at that time. However, as Swift and SwiftUI continue to evolve, some of TCA&#8217;s once-prominent advantages are no longer as obvious, and its composability model still has considerable learning and usage costs for many developers. Nevertheless, TCA remains a development paradigm that many developers and teams have adapted to and love&#8212;ultimately, what suits you is what&#8217;s best.</p></blockquote><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0115-08">FluidAudio: Local Audio AI Toolkit for Apple Platforms</a></strong></h3><p>FluidAudio is a Swift audio AI SDK designed specifically for Apple platforms, providing fully local speech recognition, speaker diarization, voice activity detection, and other features, primarily developed by <a href="https://www.linkedin.com/in/brandonweng/">Brandon Weng</a> and <a href="https://www.linkedin.com/in/hanweng/">Alex Weng</a>. All inference runs on the Apple Neural Engine (ANE), achieving low-latency, low-power audio processing capabilities.</p><p><strong>Core Features:</strong></p><ul><li><p><strong>Fully Local</strong>: All models run on-device, no network connection required, fully protecting user privacy</p></li><li><p><strong>ANE Optimized</strong>: Leverages Apple Neural Engine, avoids GPU/MPS usage, reducing CPU usage and power consumption</p></li><li><p><strong>Open and Transparent</strong>: Based on MIT/Apache 2.0 licensed open-source models, available on Hugging Face</p></li><li><p><strong>Easy Integration</strong>: Install via Swift Package Manager, with clean and intuitive API design</p></li><li><p><strong>Production Ready</strong>: Adopted by well-known apps including Voice Ink, Spokenly, Slipbox, and BoltAI</p></li></ul><p>FluidAudio supports automatic speech recognition (Parakeet TDT v3, 25 European languages), speaker diarization (offline/online dual modes), voice activity detection (Silero VAD), and text-to-speech (Beta). On M4 Pro, speech recognition achieves a real-time factor of approximately 190x, processing 1 hour of audio in just 19 seconds.</p><p>If you&#8217;re developing iOS/macOS applications involving speech processing, FluidAudio is definitely worth trying.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-09">Navigable: Unified SwiftUI Navigation Management</a></strong></h3><p>A major pain point in SwiftUI is how to uniformly manage multi-level routing, sheets, full-screen covers, and alerts across different navigation and presentation mechanisms. Navigable, developed by <a href="https://www.linkedin.com/in/coreyd303/">Corey Davis</a>, provides a more centralized and testable solution: it consolidates all navigation behavior into an observable <code>NavigationState</code> as the single source of truth.</p><p>Through this approach, Navigable maintains type-safety and modern Swift (@Observable, Swift 6) features while extracting navigation logic from views, supporting complex flows, deep linking, and unit testing. Additionally, it supports both declarative view construction and imperative APIs (like <code>push</code> / <code>pop</code>) for driving state changes, offering more controllability in complex scenarios similar to traditional routing systems.</p><blockquote><p>The library is still in early development, but its implementation approach is worth continued attention.</p></blockquote><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-115?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-115?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#21608;&#26085;&#23567;&#25554;&#26354;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-115/">&#32593;&#39029;&#29256;</a></strong></p><p>&#21608;&#26085;&#19979;&#21320;&#65292;&#25105;&#27491;&#20934;&#22791;&#21608;&#19968;&#30340;&#21608;&#25253;&#12290;&#36215;&#36523;&#30340;&#30636;&#38388;&#65292;&#21491;&#25163;&#23567;&#25351;&#20284;&#20046;&#30896;&#21040;&#20102;&#20160;&#20040;&#65292;&#28982;&#21518;&#23427;&#23601;&#20280;&#19981;&#30452;&#20102;&#12290;</p><p>&#26377;&#20123;&#35809;&#24322;&#8212;&#8212;&#19981;&#30171;&#12289;&#19981;&#32959;&#65292;&#20294;&#23601;&#26159;&#26080;&#27861;&#20280;&#30452;&#12290;&#24613;&#35786;&#21307;&#29983;&#21021;&#27493;&#21028;&#26029;&#26159;&#23567;&#25351;&#20280;&#32908;&#33137;&#25439;&#20260;&#65292;&#32422;&#20102;&#21608;&#19968;&#20570;&#36827;&#19968;&#27493;&#26816;&#26597;&#65292;&#24456;&#21487;&#33021;&#38656;&#35201;&#25163;&#26415;&#20462;&#22797;&#12290;</p><p>&#36825;&#25165;&#24847;&#35782;&#21040;&#65292;&#24179;&#26102;&#23384;&#22312;&#24863;&#19981;&#24378;&#30340;&#23567;&#25351;&#65292;&#21407;&#26469;&#22914;&#27492;&#37325;&#35201;&#12290;&#29616;&#22312;&#25140;&#30528;&#22266;&#23450;&#25351;&#22871;&#65292;&#25171;&#23383;&#21464;&#24471;&#27604;&#36739;&#22256;&#38590;&#12290;&#22909;&#22312;&#24212;&#35813;&#19981;&#26159;&#20160;&#20040;&#22823;&#38382;&#39064;&#65292;&#21482;&#26159;&#25509;&#19979;&#26469;&#19968;&#27573;&#26102;&#38388;&#20250;&#20943;&#23569;&#25171;&#23383;&#37327;&#12290;</p><p>&#20154;&#29983;&#26080;&#24120;&#65292;&#24494;&#31505;&#23545;&#24453;&#12290;</p><p><strong>&#21608;&#19968;&#26356;&#26032;</strong>&#65306;&#20170;&#22825;&#36827;&#19968;&#27493;&#26816;&#26597;&#21518;&#65292;&#21457;&#29616;&#27809;&#26377;&#38656;&#35201;&#22797;&#20301;&#30340;&#39592;&#25240;&#65292;&#21482;&#26159;&#21333;&#32431;&#30340;&#32908;&#33137;&#26029;&#35010;&#12290;&#36825;&#26679;&#23601;&#19981;&#29992;&#25163;&#26415;&#20102;&#65292;&#21482;&#38656;&#35201;&#25140;&#25351;&#22871;&#22266;&#23450; 6 &#21608;&#23601;&#22522;&#26412;&#33021;&#24674;&#22797;&#20102;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-113/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/watchos-development-pitfalls-and-practical-tips/?utm_source=fatbobman%20weekly%20issue%20115&amp;utm_medium=web">&#20174; YaoYao &#21040; Tooboo&#65306;watchOS &#24320;&#21457;&#36991;&#22353;&#19982;&#23454;&#25112;</a></strong></h3><p>&#20316;&#20026;&#30693;&#21517; watchOS &#24212;&#29992; YaoYao&#12289;Tooboo&#12289;DunDun &#30340;&#20316;&#32773;&#65292;<a href="https://yaoyaojumprope.com/about">Haozes</a> &#20998;&#20139;&#20102; watchOS &#24320;&#21457;&#20013;&#20851;&#20110;&#29256;&#26412;&#20860;&#23481;&#12289;App &#21796;&#36215;&#36890;&#20449;&#12289;&#25968;&#25454;&#21516;&#27493;&#12289;&#37325;&#21551;&#24674;&#22797;&#12289;&#20869;&#23384;&#27844;&#38706;&#21644;&#30005;&#37327;&#20248;&#21270;&#31561;&#39640;&#36136;&#37327;&#23454;&#25112;&#32463;&#39564;&#12290;&#36825;&#31687;&#25991;&#31456;&#28085;&#30422;&#20102;&#20174; HealthKit &#21040; WCSession&#12289;&#20174; HKWorkoutSession &#21040; TimelineSchedule &#30340;&#23436;&#25972;&#24320;&#21457;&#36991;&#22353;&#19982;&#24615;&#33021;&#35843;&#20248;&#25351;&#21335;&#65292;&#23545;&#20110;&#27491;&#22312;&#24320;&#21457;&#25110;&#35745;&#21010;&#24320;&#21457; Apple Watch &#24212;&#29992;&#30340;&#24320;&#21457;&#32773;&#20855;&#26377;&#26497;&#39640;&#21442;&#32771;&#20215;&#20540;&#12290;</p><blockquote><p>&#20316;&#20026;&#19968;&#20010;&#38271;&#26399;&#30340; Apple Watch &#29992;&#25143;&#21644; Swift &#21338;&#20027;&#65292;&#25105;&#24120;&#24863;&#21497; watchOS &#24320;&#21457;&#30340;&#8220;&#31070;&#31192;&#8221;&#8212;&#8212;&#25991;&#26723;&#20043;&#22806;&#32454;&#33410;&#32321;&#22810;&#65292;&#19988;&#32593;&#32476;&#19978;&#30495;&#27491;&#26377;&#28145;&#24230;&#30340;&#23454;&#25112;&#25991;&#31456;&#23525;&#23525;&#26080;&#20960;&#12290;&#20026;&#27492;&#65292;&#25105;&#29305;&#21035;&#36992;&#35831;&#20102; watchOS &#39046;&#22495;&#30340;&#22836;&#37096;&#29420;&#31435;&#24320;&#21457;&#32773; Haozes&#65292;&#26469;&#20998;&#20139;&#20182;&#30340;&#24320;&#21457;&#20307;&#20250;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-01">Swift 6 &#20005;&#26684;&#24182;&#21457;&#36801;&#31227;&#23454;&#25112; (My journey to Swift 6 and Strict Concurrency)</a></strong></h3><p>&#19968;&#27425;&#8220;&#21482;&#22312;&#30495;&#23454;&#29992;&#25143;&#35774;&#22791;&#19978;&#25165;&#20250;&#20986;&#29616;&#8221;&#30340;&#23849;&#28291;&#65292;&#36843;&#20351; <a href="https://www.linkedin.com/in/irvingpop/overlay/about-this-profile/">Irving Popovetsky</a> &#23558;&#19968;&#25972;&#20010;&#24050;&#19978;&#32447;&#30340; iOS &#24212;&#29992;&#36801;&#31227;&#21040; Swift 6 + Strict Concurrency&#12290;&#36825;&#31687;&#25991;&#31456;&#23436;&#25972;&#35760;&#24405;&#20102;&#20174;&#36801;&#31227;&#20043;&#21021;&#30340; 76 &#20010; error&#12289;238 &#20010; warning &#24320;&#22987;&#65292;&#21040;&#36880;&#27493;&#24341;&#20837; <code>@preconcurrency</code>&#12289;<code>actor</code>&#12289;<code>@MainActor</code>&#12289;<code>Sendable</code>&#12289;<code>nonisolated(unsafe)</code>&#65292;&#20877;&#21040;&#30495;&#26426; + Thread Sanitizer &#39564;&#35777;&#30340;&#20840;&#36807;&#31243;&#12290;Irving &#25351;&#20986;&#65292;Swift 6 &#30340;&#36816;&#34892;&#26102;&#20250;&#22312;&#38381;&#21253;&#34987;&#35843;&#29992;&#30340;&#30636;&#38388;&#39564;&#35777; actor &#38548;&#31163;&#65292;&#21738;&#24597;&#20320;&#22312;&#38381;&#21253;&#20869;&#37096;&#20877; <code>Task { @MainActor in }</code> &#20063;&#21487;&#33021;&#20026;&#26102;&#24050;&#26202;&#12290;&#25991;&#31456;&#20013;&#23545;&#36825;&#19968;&#34892;&#20026;&#32473;&#20986;&#20102;&#28165;&#26224;&#12289;&#21487;&#22797;&#29992;&#30340;&#20462;&#22797;&#27169;&#24335;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-02">&#29992; MetricKit &#30417;&#25511;&#24212;&#29992;&#24615;&#33021; (Monitoring app performance with MetricKit)</a></strong></h3><p>MetricKit &#26159; Apple &#22312; iOS 13 &#24341;&#20837;&#30340;&#31995;&#32479;&#32423;&#24615;&#33021;&#35786;&#26029;&#26694;&#26550;&#65292;&#29992;&#20110;&#21521;&#24320;&#21457;&#32773;&#25552;&#20379;&#26469;&#33258;&#30495;&#23454;&#29992;&#25143;&#35774;&#22791;&#30340;&#24212;&#29992;&#24615;&#33021;&#19982;&#31283;&#23450;&#24615;&#25968;&#25454;&#12290;&#23427;&#21482;&#22312;&#30495;&#26426;&#29615;&#22659;&#20013;&#24037;&#20316;&#65292;&#25968;&#25454;&#26469;&#28304;&#20110;&#31995;&#32479;&#22312;&#21518;&#21488;&#38271;&#26399;&#37319;&#26679;&#24182;&#32858;&#21512;&#30340;&#32467;&#26524;&#65292;&#22240;&#27492;&#33021;&#22815;&#26356;&#30495;&#23454;&#22320;&#21453;&#26144;&#24212;&#29992;&#22312;&#23454;&#38469;&#20351;&#29992;&#22330;&#26223;&#19979;&#30340;&#34892;&#20026;&#12290;</p><p><a href="https://x.com/mecid">Majid Jabrayilov</a> &#22312;&#26412;&#25991;&#20013;&#23637;&#31034;&#20102;&#22914;&#20309;&#36890;&#36807; <code>MXMetricManager</code> &#35746;&#38405;&#31995;&#32479;&#32423;&#24615;&#33021;&#25968;&#25454;&#65292;&#20174;&#21518;&#21488;&#24322;&#24120;&#36864;&#20986;&#12289;CPU / &#20869;&#23384;&#36164;&#28304;&#38480;&#21046;&#65292;&#21040;&#23849;&#28291;&#35786;&#26029;&#20449;&#24687;&#65292;&#36880;&#27493;&#25552;&#21462;&#20851;&#38190;&#25351;&#26631;&#24182;&#19978;&#25253;&#65292;&#20174;&#32780;&#26500;&#24314;&#19968;&#20010;&#26356;&#23436;&#25972;&#12289;&#21487;&#36861;&#28335;&#30340;&#24212;&#29992;&#24615;&#33021;&#30417;&#25511;&#38754;&#26495;&#12290;Majid &#20063;&#29305;&#21035;&#25552;&#37266;&#65292;MetricKit &#30340;&#25968;&#25454;&#36890;&#24120;&#25353;&#22825;&#32858;&#21512;&#19979;&#21457;&#65292;&#32780;&#38750;&#23454;&#26102;&#22238;&#35843;&#65292;&#23454;&#38469;&#20998;&#26512;&#26102;&#38656;&#35201;&#32467;&#21512;&#26102;&#38388;&#25139;&#29702;&#35299;&#20854;&#25152;&#35206;&#30422;&#30340;&#26102;&#38388;&#21306;&#38388;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-03">&#29992; Claude Code &#37325;&#26500; MistKit (Rebuilding MistKit with Claude Code - From CloudKit Docs to Type-Safe Swift)</a></strong></h3><p><a href="https://x.com/leogdion">Leo Dion</a> &#22312;&#37325;&#24314;&#33258;&#24049;&#20572;&#26356;&#22810;&#24180;&#30340; CloudKit &#26381;&#21153;&#31471;&#24211; MistKit &#26102;&#65292;&#21457;&#29616; <a href="https://github.com/apple/swift-openapi-generator">swift-openapi-generator</a> &#33021;&#26174;&#33879;&#38477;&#20302;&#37325;&#26500;&#22797;&#26434;&#24230;&#65306;&#21482;&#35201;&#23558; CloudKit &#30340; REST &#25991;&#26723;&#36716;&#21270;&#20026; OpenAPI &#35268;&#33539;&#65292;&#23601;&#21487;&#20197;&#33258;&#21160;&#29983;&#25104;&#22823;&#35268;&#27169;&#12289;&#31867;&#22411;&#23433;&#20840;&#30340; Swift &#23458;&#25143;&#31471;&#20195;&#30721;&#12290;&#20026;&#27492;&#65292;&#20182;&#24341;&#20837; Claude Code&#65292;&#19987;&#38376;&#36127;&#36131;&#23436;&#25104;&#8220;&#20174; Apple &#25991;&#26723;&#21040; OpenAPI YAML&#8221;&#30340;&#32763;&#35793;&#24037;&#20316;&#12290;</p><p>&#25991;&#31456;&#26368;&#26377;&#20215;&#20540;&#30340;&#22320;&#26041;&#65292;&#24182;&#19981;&#22312;&#20110;&#8220;AI &#29983;&#25104;&#20102;&#22810;&#23569;&#20195;&#30721;&#8221;&#65292;&#32780;&#22312;&#20110; Leo &#22914;&#20309;&#20351;&#29992; AI&#12290;&#20182;&#24182;&#27809;&#26377;&#35753; Claude &#30452;&#25509;&#23454;&#29616; MistKit&#65292;&#32780;&#26159;&#23558;&#20854;&#23450;&#20301;&#20026;&#8220;&#25991;&#26723;&#32763;&#35793;&#19982;&#27169;&#24335;&#25918;&#22823;&#22120;&#8221;&#65292;&#32780;&#30495;&#27491;&#22797;&#26434;&#12289;&#38656;&#35201;&#24037;&#31243;&#21028;&#26029;&#19982;&#26550;&#26500;&#21462;&#33293;&#30340;&#37096;&#20998;&#65292;&#22987;&#32456;&#30001;&#20316;&#32773;&#20146;&#33258;&#25226;&#25511;&#12290;&#19982;&#20854;&#35753; AI &#30452;&#25509;&#8220;&#20889;&#20195;&#30721;&#8221;&#65292;&#19981;&#22914;&#35753;&#23427;&#25226;&#22797;&#26434;&#38382;&#39064;<strong>&#21464;&#25104;&#21487;&#29983;&#25104;&#12289;&#21487;&#26657;&#39564;&#30340;&#38382;&#39064;</strong>&#8212;&#8212;&#36825;&#27491;&#26159;&#36825;&#27425; MistKit &#37325;&#24314;&#36807;&#31243;&#20013;&#26368;&#20540;&#24471;&#20511;&#37492;&#30340;&#22320;&#26041;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-04">ChatGPT &#35760;&#24518;&#31995;&#32479;&#36870;&#21521;&#20998;&#26512; (I Reverse Engineered ChatGPT&#8217;s Memory System, and Here&#8217;s What I Found!)</a></strong></h3><p><a href="https://x.com/manthanguptaa">Manthan Gupta</a> &#36890;&#36807;&#22823;&#37327;&#23545;&#35805;&#23454;&#39564;&#65292;&#23545; ChatGPT &#30340;&#8220;&#35760;&#24518;&#8221;&#34892;&#20026;&#36827;&#34892;&#20102;&#36870;&#21521;&#20998;&#26512;&#65292;&#21457;&#29616;&#20854;&#23454;&#29616;&#26041;&#24335;&#36828;&#27604;&#24819;&#35937;&#20013;&#31616;&#21333;&#65306;&#27809;&#26377;&#21521;&#37327;&#25968;&#25454;&#24211;&#12289;&#27809;&#26377;&#36328;&#21382;&#21490;&#23545;&#35805;&#30340; RAG&#65292;&#32780;&#26159;&#30001;&#22235;&#23618;&#19978;&#19979;&#25991;&#20849;&#21516;&#26500;&#25104;&#8212;&#8212;&#19968;&#27425;&#24615;&#27880;&#20837;&#30340; Session Metadata&#12289;&#26174;&#24335;&#23384;&#20648;&#30340;&#38271;&#26399;&#29992;&#25143;&#35760;&#24518;&#12289;&#36817;&#26399;&#23545;&#35805;&#30340;&#36731;&#37327;&#25688;&#35201;&#65292;&#20197;&#21450;&#24403;&#21069;&#20250;&#35805;&#30340;&#28369;&#21160;&#31383;&#21475;&#12290;Manthan &#35748;&#20026;&#65292;&#36825;&#31181;&#35774;&#35745;&#22312;&#24615;&#33021;&#12289;&#24310;&#36831;&#21644; token &#25104;&#26412;&#19978;&#30340;&#20248;&#21183;&#38750;&#24120;&#26126;&#26174;&#65306;&#36890;&#36807;&#39044;&#35745;&#31639;&#25688;&#35201;&#21644;&#26174;&#24335;&#20107;&#23454;&#27880;&#20837;&#65292;&#25442;&#21462;&#8220;&#36275;&#22815;&#22909;&#8221;&#30340;&#36830;&#32493;&#24615;&#65292;&#32780;&#19981;&#26159;&#26114;&#36149;&#30340;&#20840;&#37327;&#21382;&#21490;&#26816;&#32034;&#12290;Manthan &#36824;&#26377;&#21478;&#19968;&#31687;&#38024;&#23545; <a href="https://l.fatbobman.com/w0115-05">Claude &#35760;&#24518;&#31995;&#32479;&#30340;&#30740;&#31350;</a>&#12290;</p><blockquote><p>&#22312;&#20351;&#29992; ChatGPT &#30340;&#36807;&#31243;&#20013;&#65292;&#25105;&#26102;&#24120;&#20250;&#23545;&#23427;&#23545;&#25105;&#30340;&#20102;&#35299;&#31243;&#24230;&#24863;&#21040;&#24778;&#35766;&#12290;&#23613;&#31649;&#25105;&#28165;&#26970;&#65292;&#36825;&#31181;&#8220;&#29087;&#24713;&#24863;&#8221;&#26469;&#33258;&#20854;&#35760;&#24518;&#19982;&#19978;&#19979;&#25991;&#26426;&#21046;&#65292;&#20294;&#36825;&#20063;&#27491;&#26159;&#25105;&#38271;&#26399;&#20559;&#21521;&#20351;&#29992;&#23448;&#26041;&#23458;&#25143;&#31471;&#30340;&#37325;&#35201;&#21407;&#22240;&#20043;&#19968;&#12290;&#24403;&#28982;&#65292;&#22914;&#26524;&#20320;&#23545;&#38544;&#31169;&#38382;&#39064;&#26684;&#22806;&#25935;&#24863;&#65292;&#37027;&#20040;&#36825;&#31181;&#33021;&#21147;&#26412;&#36523;&#65292;&#21487;&#33021;&#27491;&#26159;&#20320;&#19981;&#24895;&#25509;&#21463;&#30340;&#37027;&#19968;&#37096;&#20998;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-06">Swift Configuration 1.0 released</a></strong></h3><p><a href="https://bsky.app/profile/czechboy0.dev">Honza Dvorsky</a> &#22312; Swift &#23448;&#26041;&#21338;&#23458;&#20013;&#23459;&#24067; Swift Configuration 1.0 &#27491;&#24335;&#21457;&#24067;&#12290;&#35813;&#24211;&#20026; Swift &#24212;&#29992;&#19982;&#24211;&#25552;&#20379;&#20102;&#19968;&#22871;&#32479;&#19968;&#12289;&#31867;&#22411;&#23433;&#20840;&#30340;&#37197;&#32622;&#35835;&#21462;&#25277;&#35937;&#65292;&#20854;&#20851;&#38190;&#24182;&#19981;&#22312;&#20110;&#25903;&#25345;&#22810;&#23569;&#37197;&#32622;&#26684;&#24335;&#65292;&#32780;&#26159;&#24443;&#24213;&#20998;&#31163;&#12300;&#37197;&#32622;&#22914;&#20309;&#35835;&#21462;&#12301;&#19982;&#12300;&#37197;&#32622;&#26469;&#33258;&#21738;&#37324;&#12301;&#12290;&#36825;&#19968;&#35774;&#35745;&#23545;&#24211;&#20316;&#32773;&#23588;&#20026;&#37325;&#35201;&#8212;&#8212;&#24211;&#21487;&#20197;&#25509;&#21463;&#37197;&#32622;&#32780;&#19981;&#32465;&#23450;&#20855;&#20307;&#26469;&#28304;&#65292;&#20174;&#32780;&#22312;&#19981;&#21516;&#37096;&#32626;&#29615;&#22659;&#20013;&#20445;&#25345;&#33391;&#22909;&#30340;&#21487;&#32452;&#21512;&#24615;&#12290;&#38543;&#30528; 1.0 &#21457;&#24067;&#65292;Swift Configuration &#30340; API &#24050;&#36827;&#20837;&#31283;&#23450;&#38454;&#27573;&#65292;&#24182;&#24320;&#22987;&#34987; Vapor&#12289;Hummingbird &#31561;&#39033;&#30446;&#25506;&#32034;&#38598;&#25104;&#12290;</p><blockquote><p>&#20045;&#30475;&#20043;&#19979;&#65292;&#20026;&#37197;&#32622;&#31649;&#29702;&#24341;&#20837;&#36825;&#26679;&#19968;&#20010;&#25277;&#35937;&#23618;&#20284;&#20046;&#26174;&#24471;&#26377;&#20123;&#8220;&#37325;&#37327;&#32423;&#8221;&#65292;&#20294;&#19968;&#26086;&#37197;&#32622;&#26469;&#28304;&#19981;&#20877;&#23616;&#38480;&#20110;&#21333;&#19968;&#25991;&#20214;&#65292;&#25110;&#32773;&#20195;&#30721;&#38656;&#35201;&#22312;&#19981;&#21516;&#29615;&#22659;&#19982;&#39033;&#30446;&#20013;&#22797;&#29992;&#65292;&#20854;&#24102;&#26469;&#30340;&#32467;&#26500;&#28165;&#26224;&#24230;&#19982;&#25193;&#23637;&#24615;&#20248;&#21183;&#23601;&#20250;&#36805;&#36895;&#26174;&#29616;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-07">TCA &#26550;&#26500;&#65306;&#19968;&#20010;&#34987;&#32654;&#21270;&#30340;&#21453;&#27169;&#24335;&#65311; (TCA Architecture: A Glorified Antipattern)</a></strong></h3><p>&#36825;&#26159;&#19968;&#31687;&#31435;&#22330;&#26497;&#20854;&#40092;&#26126;&#30340;&#38271;&#25991;&#12290;<a href="https://medium.com/@redhotbits">Lazar Otasevic</a> &#20174;&#20989;&#25968;&#24335;&#32534;&#31243;&#19982; SwiftUI &#30340;&#36816;&#34892;&#27169;&#22411;&#20986;&#21457;&#65292;&#31995;&#32479;&#24615;&#22320;&#21453;&#23545;&#20102; TCA &#20197; <code>Action</code> enum + <code>Reducer</code> &#20026;&#26680;&#24515;&#30340;&#35774;&#35745;&#65292;&#35748;&#20026;&#36825;&#26159;&#19968;&#31181;&#8220;&#23558;&#34892;&#20026;&#32534;&#30721;&#20026;&#25968;&#25454;&#8221;&#30340;&#32463;&#20856;&#21453;&#27169;&#24335;&#65292;&#24182;&#19988;&#19981;&#24517;&#35201;&#22320;&#22842;&#36208;&#20102; SwiftUI &#21407;&#26412;&#24212;&#24403;&#25317;&#26377;&#30340;&#29366;&#24577;&#25152;&#26377;&#26435;&#12290;&#19982;&#35768;&#22810;&#20572;&#30041;&#22312;&#24773;&#32490;&#25110;&#20559;&#22909;&#23618;&#38754;&#30340;&#8220;&#21453; TCA&#8221;&#35752;&#35770;&#19981;&#21516;&#65292;&#26412;&#25991;&#32473;&#20986;&#20102;&#19968;&#22871;&#23436;&#25972;&#12289;&#21487;&#36816;&#34892;&#30340;&#26367;&#20195;&#24605;&#36335;&#65306;&#23558; <strong>State</strong> &#35270;&#20026;&#32431;&#25968;&#25454;&#12289;<strong>Logic</strong> &#35270;&#20026;&#26080;&#29366;&#24577;&#30340;&#23454;&#29616;&#32454;&#33410;&#65292;&#24182;&#36890;&#36807;&#38381;&#21253;&#65288;capabilities&#65289;&#26292;&#38706;&#34892;&#20026;&#65292;&#20174;&#32780;&#22312;&#20445;&#25345;&#21487;&#27979;&#35797;&#24615;&#19982;&#21487;&#32452;&#21512;&#24615;&#30340;&#21516;&#26102;&#65292;&#26356;&#36148;&#21512; SwiftUI &#30340;&#22768;&#26126;&#24335;&#25968;&#25454;&#27969;&#27169;&#22411;&#12290;</p><blockquote><p>&#32771;&#34385;&#21040; TCA &#21018;&#20986;&#29616;&#30340;&#26102;&#26399;&#65292;&#24456;&#22810;&#24320;&#21457;&#32773;&#20173;&#38590;&#20197;&#24212;&#23545; <code>ObservableObject</code> &#21709;&#24212;&#39063;&#31890;&#24230;&#19981;&#36275;&#12289;&#32570;&#20047; <code>@MainActor</code>&#12289;<code>Task</code> &#31561;&#24037;&#20855;&#12289;&#24322;&#27493;&#35843;&#29992;&#39640;&#24230;&#20381;&#36182; Combine &#30340;&#29616;&#23454;&#22788;&#22659;&#65292;TCA &#30830;&#23454;&#26377;&#25928;&#35299;&#20915;&#20102;&#24403;&#26102;&#30340;&#19968;&#31995;&#21015;&#30171;&#28857;&#12290;&#20294;&#38543;&#30528; Swift &#19982; SwiftUI &#30340;&#19981;&#26029;&#28436;&#36827;&#65292;TCA &#20013;&#19968;&#20123;&#26366;&#32463;&#31361;&#20986;&#30340;&#20248;&#21183;&#24050;&#19981;&#20877;&#26126;&#26174;&#65292;&#32780;&#20854;&#21487;&#32452;&#21512;&#24615;&#27169;&#22411;&#23545;&#19981;&#23569;&#24320;&#21457;&#32773;&#32780;&#35328;&#65292;&#20351;&#29992;&#19982;&#29702;&#35299;&#25104;&#26412;&#20063;&#20381;&#28982;&#19981;&#20302;&#12290;&#21363;&#20415;&#22914;&#27492;&#65292;TCA &#20173;&#28982;&#26159;&#35768;&#22810;&#24320;&#21457;&#32773;&#21644;&#22242;&#38431;&#24050;&#32463;&#36866;&#24212;&#24182;&#21916;&#29233;&#30340;&#24320;&#21457;&#33539;&#24335;&#8212;&#8212;&#24402;&#26681;&#32467;&#24213;&#65292;&#36866;&#21512;&#33258;&#24049;&#30340;&#65292;&#25165;&#26159;&#26368;&#22909;&#30340;&#12290;</p></blockquote><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0115-08">FluidAudio: &#20026; Apple &#24179;&#21488;&#25171;&#36896;&#30340;&#26412;&#22320;&#21270;&#38899;&#39057; AI &#24037;&#20855;&#21253;</a></strong></h3><p>FluidAudio &#26159;&#19968;&#20010;&#19987;&#20026; Apple &#24179;&#21488;&#35774;&#35745;&#30340; Swift &#38899;&#39057; AI SDK&#65292;&#25552;&#20379;&#23436;&#20840;&#26412;&#22320;&#21270;&#30340;&#35821;&#38899;&#35782;&#21035;&#12289;&#35828;&#35805;&#20154;&#20998;&#31163;&#12289;&#35821;&#38899;&#27963;&#21160;&#26816;&#27979;&#31561;&#21151;&#33021;&#65292;&#30001; <a href="https://www.linkedin.com/in/brandonweng/">Brandon Weng</a> &#21644; <a href="https://www.linkedin.com/in/hanweng/">Alex Weng</a> &#20027;&#23548;&#24320;&#21457;&#12290;&#25152;&#26377;&#25512;&#29702;&#37117;&#22312; Apple Neural Engine (ANE) &#19978;&#36816;&#34892;&#65292;&#23454;&#29616;&#20102;&#20302;&#24310;&#36831;&#12289;&#20302;&#21151;&#32791;&#30340;&#38899;&#39057;&#22788;&#29702;&#33021;&#21147;&#12290;</p><p><strong>&#26680;&#24515;&#29305;&#24615;&#65306;</strong></p><ul><li><p><strong>&#23436;&#20840;&#26412;&#22320;&#21270;</strong>&#65306;&#25152;&#26377;&#27169;&#22411;&#22312;&#35774;&#22791;&#31471;&#36816;&#34892;&#65292;&#26080;&#38656;&#32593;&#32476;&#36830;&#25509;&#65292;&#20805;&#20998;&#20445;&#25252;&#29992;&#25143;&#38544;&#31169;</p></li><li><p><strong>ANE &#20248;&#21270;</strong>&#65306;&#20805;&#20998;&#21033;&#29992; Apple Neural Engine&#65292;&#36991;&#20813;&#20351;&#29992; GPU/MPS&#65292;&#38477;&#20302; CPU &#20351;&#29992;&#29575;&#21644;&#21151;&#32791;</p></li><li><p><strong>&#24320;&#28304;&#36879;&#26126;</strong>&#65306;&#22522;&#20110; MIT/Apache 2.0 &#35768;&#21487;&#30340;&#24320;&#28304;&#27169;&#22411;&#65292;&#21487;&#22312; Hugging Face &#33719;&#21462;</p></li><li><p><strong>&#26131;&#20110;&#38598;&#25104;</strong>&#65306;&#36890;&#36807; Swift Package Manager &#23433;&#35013;&#65292;API &#35774;&#35745;&#31616;&#27905;&#30452;&#35266;</p></li><li><p><strong>&#29983;&#20135;&#23601;&#32490;</strong>&#65306;&#24050;&#34987; Voice Ink&#12289;Spokenly&#12289;Slipbox&#12289;BoltAI &#31561;&#30693;&#21517;&#24212;&#29992;&#37319;&#29992;</p></li></ul><p>FluidAudio &#25903;&#25345;&#33258;&#21160;&#35821;&#38899;&#35782;&#21035;&#65288;Parakeet TDT v3&#65292;25 &#31181;&#27431;&#27954;&#35821;&#35328;&#65289;&#12289;&#35828;&#35805;&#20154;&#20998;&#31163;&#65288;&#31163;&#32447;/&#22312;&#32447;&#21452;&#27169;&#24335;&#65289;&#12289;&#35821;&#38899;&#27963;&#21160;&#26816;&#27979;&#65288;Silero VAD&#65289;&#20197;&#21450;&#25991;&#23383;&#36716;&#35821;&#38899;&#65288;Beta&#65289;&#12290;&#22312; M4 Pro &#19978;&#65292;&#35821;&#38899;&#35782;&#21035;&#30340;&#23454;&#26102;&#31995;&#25968;&#21487;&#36798;&#32422; 190x&#65292;&#22788;&#29702; 1 &#23567;&#26102;&#38899;&#39057;&#20165;&#38656; 19 &#31186;&#12290;</p><p>&#22914;&#26524;&#20320;&#27491;&#22312;&#24320;&#21457;&#28041;&#21450;&#35821;&#38899;&#22788;&#29702;&#30340; iOS/macOS &#24212;&#29992;&#65292;FluidAudio &#32477;&#23545;&#20540;&#24471;&#23581;&#35797;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0115-09">Navigable: &#32479;&#19968; SwiftUI &#23548;&#33322;&#31649;&#29702;</a></strong></h3><p>SwiftUI &#20013;&#30340;&#19968;&#22823;&#30171;&#28857;&#65292;&#22312;&#20110;&#22914;&#20309;&#23558;&#22810;&#32423;&#36335;&#30001;&#12289;sheet&#12289;full-screen cover &#20197;&#21450; alert &#31561;&#19981;&#21516;&#23548;&#33322;&#19982;&#23637;&#31034;&#26426;&#21046;&#32479;&#19968;&#31649;&#29702;&#12290;&#30001; <a href="https://www.linkedin.com/in/coreyd303/">Corey Davis</a> &#24320;&#21457;&#30340; Navigable &#25552;&#20379;&#20102;&#19968;&#31181;&#26356;&#38598;&#20013;&#12289;&#21487;&#27979;&#35797;&#30340;&#35299;&#20915;&#26041;&#26696;&#65306;&#23427;&#23558;&#25152;&#26377;&#23548;&#33322;&#34892;&#20026;&#32479;&#19968;&#25910;&#25947;&#21040;&#19968;&#20010;&#21487;&#35266;&#23519;&#30340; <code>NavigationState</code> &#20013;&#65292;&#20316;&#20026;&#21807;&#19968;&#30340;&#29366;&#24577;&#26469;&#28304;&#12290;</p><p>&#36890;&#36807;&#36825;&#31181;&#26041;&#24335;&#65292;Navigable &#33021;&#22815;&#22312;&#20445;&#25345; type-safe &#19982;&#29616;&#20195; Swift&#65288;@Observable&#12289;Swift 6&#65289; &#29305;&#24615;&#30340;&#21516;&#26102;&#65292;&#23558;&#23548;&#33322;&#36923;&#36753;&#20174;&#35270;&#22270;&#20013;&#21093;&#31163;&#20986;&#26469;&#65292;&#25903;&#25345;&#22797;&#26434;&#27969;&#31243;&#12289;&#28145;&#38142;&#20197;&#21450;&#21333;&#20803;&#27979;&#35797;&#12290;&#21516;&#26102;&#65292;&#23427;&#26082;&#25903;&#25345;&#22768;&#26126;&#24335;&#30340;&#35270;&#22270;&#26500;&#24314;&#65292;&#20063;&#20801;&#35768;&#36890;&#36807;&#21629;&#20196;&#24335; API&#65288;&#22914; <code>push</code> / <code>pop</code>&#65289;&#39537;&#21160;&#29366;&#24577;&#21464;&#21270;&#65292;&#22312;&#22797;&#26434;&#22330;&#26223;&#19979;&#26356;&#25509;&#36817;&#20256;&#32479;&#36335;&#30001;&#31995;&#32479;&#30340;&#21487;&#25511;&#24615;&#12290;</p><blockquote><p>&#35813;&#24211;&#20173;&#22788;&#22312;&#24320;&#21457;&#26089;&#26399;&#65292;&#20294;&#20854;&#23454;&#29616;&#24605;&#36335;&#20540;&#24471;&#25345;&#32493;&#20851;&#27880;&#12290;</p></blockquote>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #114]]></title><description><![CDATA[Unearthing "Silent Experts"]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-114</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-114</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 08 Dec 2025 12:00:58 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Wks7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wks7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wks7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 424w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 848w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 1272w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wks7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp" width="1456" height="960" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:960,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31080,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/181000830?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wks7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 424w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 848w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 1272w, https://substackcdn.com/image/fetch/$s_!Wks7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae00fbc4-9e13-4b82-ae42-abcae3254510_1920x1266.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@alex_gruber?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alex Gruber</a> on <a href="https://unsplash.com/photos/a-man-working-in-a-shop-rgSLzr82Kd8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><h2><strong>Unearthing &#8220;Silent Experts&#8221;</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-114/">Read on web &#8594;</a></p><p>Regular readers of my blog may have noticed that I haven&#8217;t published many personal pieces lately. Instead, over the past few weeks, I&#8217;ve shared a series of guest posts from developers across different domains. This is part of a special initiative I recently launched&#8212;inviting practitioners who have deep experience and meaningful accomplishments in their respective fields to share their hands-on insights, hard-won lessons, unique perspectives, and personal journeys.</p><p>As a blogger, I&#8217;ve inadvertently written hundreds of articles over the years. While I still believe my content holds value, I must admit that, like many writers who publish regularly, I have gradually fallen into a kind of &#8220;formulaic&#8221; rhythm. My articles tend to focus on API usage and internal mechanisms, but they are often constructed with a &#8220;demo mindset.&#8221; Even when discussing bug fixes or pitfalls, they typically address isolated &#8220;points&#8221; rather than connected &#8220;lines,&#8221; let alone full &#8220;planes.&#8221;</p><p>As a newsletter editor, I&#8217;ve also noticed another pattern: although the internet produces an endless stream of high-quality technical articles every week, truly deep, domain-specific, and frontline-driven content remains surprisingly rare. Over time, I realized the root cause: developers working on the front lines simply lack the time or energy to write such pieces. So, a few months ago, I began planning this initiative&#8212;reaching out to these developers, hoping to unearth these &#8220;silent experts&#8221; and make their tacit knowledge explicit.</p><p>During conversations with these authors, one scenario appears again and again: they don&#8217;t know what to write about. Even though they tackle complex engineering problems every day, long-term immersion makes these challenges feel ordinary or unremarkable to them. Many wonder, &#8220;Isn&#8217;t this just common knowledge? Would anyone really care about this?&#8221; At moments like this, I switch to the perspective of both a developer and a reader, and I tell them&#8212;yes, these are exactly the stories and insights we want to learn about. These are the &#8220;industry secrets&#8221; that rarely make it into writing.</p><p>In the era of AI, large models may well master vast amounts of API usage and coding patterns. But for humans, genuine emotion, real-world constraints, the friction of working with imperfect systems, and the lessons forged through countless failures&#8212;these remain our most precious and irreplaceable assets.</p><p>I am deeply grateful to the authors who generously carved out time from their busy schedules to share their knowledge. Many of the insights in their writing could only come from long-term engineering practice and the experience of being repeatedly &#8220;battered&#8221; by challenges.</p><p>This effort to unearth &#8220;silent experts&#8221; is still ongoing, with more articles already lined up. If the response continues to be positive, I will keep inviting more of these practitioners to share their stories.</p><p>We do this for ourselves, for the community, and perhaps to preserve a few distinct voices forged through lived experience in a world increasingly homogenized by AI.</p><p><a href="https://fatbobman.com/en/weekly/issue-113/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2>&#128226; <strong><a href="https://fatbobman.com/en/sponsorship/">Sponsor Fatbobman&#8217;s Swift Weekly</a></strong></h2><p>Promote your product to Swift &amp; iOS developers across:</p><p>- Blog: <strong>50,000</strong>+ monthly visitors<br>- Newsletter: <strong>4,000</strong>+ subscribers, <strong>53</strong>% open rate </p><p>Perfect for developer tools, courses, and services.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://fatbobman.com/en/sponsorship/&quot;,&quot;text&quot;:&quot;&#128226; View Sponsorship Options&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://fatbobman.com/en/sponsorship/"><span>&#128226; View Sponsorship Options</span></a></p><p>Enjoyed this issue? <strong><a href="https://buymeacoffee.com/fatbobman">Buy me a coffee </a></strong><a href="https://buymeacoffee.com/fatbobman">&#9749;&#65039;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/a-deep-dive-into-swiftui-rich-text-layout/?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">A Deep Dive into SwiftUI Rich Text Layout: Beyond AttributedString &#8212; Inside MarkdownView and RichText</a></strong></h3><p>Although <code>AttributedString</code> has been around for years, SwiftUI still lacks official support for <strong>full Markdown rendering, text&#8211;image mixed layout, selectable text, and fine-grained interactions</strong>. As the author of both <a href="https://github.com/LiYanan2004/MarkdownView?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">MarkdownView</a> and <a href="https://github.com/LiYanan2004/RichText?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">RichText</a>, <a href="https://x.com/LiYanan2004">LiYanan</a> walks through the technical journey behind solving these challenges&#8212;from early attempts with the Layout protocol, to hitting the limits of <code>TextRenderer</code>, and finally building an interactive, high-performance Markdown renderer on top of TextKit. This piece is both a record of persistence and growth, and one of the rare, in-depth resources available today on SwiftUI text rendering.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-01">What Setting Should I Use?</a></strong></h3><p>Ten-year-old Swift has never been more powerful&#8212;nor more complex. Beyond added language features, developers now face an ever-growing list of compiler settings whose combinations effectively define <strong>different eras, philosophies, and semantics</strong> of Swift.</p><p>In this article, <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> provides a grounded, highly practical answer to a real question: <strong>Which compiler settings should I actually enable in the Swift 6.2 / Xcode 26 era?</strong><br>If you&#8217;re debating whether to adopt Swift 6 language mode, or can&#8217;t decide whether <code>StrictConcurrency</code> should be set to <em>minimal</em>, <em>targeted</em>, or <em>complete</em>, this article serves as a decision-making guide to help you migrate in a more controlled and incremental way.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-02">Swift Enum Hidden Magic Tricks</a></strong></h3><p>Enums are one of Swift&#8217;s most distinctive language features, far beyond &#8220;switch cases with associated values.&#8221; For many experienced Swift/iOS developers, enums function as <strong>a modeling tool that shapes architectural boundaries</strong>, especially when managing complex state. In this article, <a href="https://www.linkedin.com/in/valentebruno/">Bruno Valente Pimentel</a> systematically explains how enums help us <strong>make invalid states unrepresentable</strong>, illustrating how this principle evolves from a &#8220;syntax trick&#8221; into a genuine &#8220;design methodology&#8221; through real project examples.</p><blockquote><p>&#8220;Make invalid states unrepresentable&#8221; is one of the core principles emphasized in type-driven design. If you&#8217;d like to dive deeper into the underlying concepts, the <a href="https://swiftology.io/collections/type-driven-design/?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">Type-Driven Design with Swift</a> series by <a href="https://x.com/AlexOzun">Alex Ozun</a> is highly recommended.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-03">Make Your App Visible with Alternative App Names</a></strong></h3><p>You may have noticed that some iOS apps can be found via Spotlight using multiple names&#8212;an incredibly convenient user experience. Behind this behavior is a SiriKit capability that allows developers to define up to <strong>three alternative app names</strong> in the app&#8217;s Info.plist, making the app easier to discover through different keywords. In this article, <a href="https://x.com/0xWDG">Wesley de Groot</a> explains how to implement this feature.</p><blockquote><p>With macOS 26 removing Launchpad, more users are turning to Spotlight to open apps. It wouldn&#8217;t be surprising if a similar alternative-names mechanism eventually comes to macOS as well.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-04">Organizing SwiftUI Views with TabContent and @TabContentBuilder</a></strong></h3><p>In the last two SwiftUI releases, Apple significantly expanded the capabilities of tab-based navigation&#8212;extending it from classic bottom tab bars to more flexible, structured navigation patterns (such as sidebar-like behavior on larger screens). As a result, many real projects now have increasingly bloated <code>TabView</code> declarations: role-based screens, conditional branches, navigation stacks, label configurations, and team conventions often end up intertwined inside a single block.</p><p><a href="https://www.linkedin.com/in/artem-mirzabekian/">Artem Mirzabekian</a> suggests a cleaner approach: extracting tab definitions into a dedicated, composable configuration using a custom <code>@TabContentBuilder</code>. This greatly improves readability and scalability, making tab navigation easier to maintain in large SwiftUI projects.</p><blockquote><p>Beyond <code>@ViewBuilder</code>, SwiftUI provides many domain-specific result builders&#8212;such as <code>TableColumnBuilder</code>, <code>CommandsBuilder</code>, <code>SceneBuilder</code>, <code>ToolbarContentBuilder</code>, and <code>ChartContentBuilder</code>. Using the right builder not only clarifies structure but can significantly reduce type-inference load in complex layouts (e.g., combining Charts and Table), helping avoid the infamous SwiftUI &#8220;type-checking explosion&#8221;.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-05">LLDB Power User Guide: Essential Commands &amp; SwiftUI Debugging</a></strong></h3><p>Debugging SwiftUI has never been easy. While many developers rely on sprinkling <code>print</code> statements throughout their code, the far more powerful capabilities of LLDB often go overlooked. In this article, <a href="https://www.linkedin.com/in/jai-krishna-chandrasekar/">Jai Krishna</a> demonstrates&#8212;using extensive SwiftUI examples&#8212;how to inspect and modify the internal state of <code>@State</code>, <code>@Binding</code>, and <code>@Published</code> at runtime, trace redraw triggers with <code>Self._printChanges()</code>, and use targeted breakpoint strategies to pinpoint layout and interaction issues.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-06">Identifying Hangs in iOS Apps</a></strong></h3><p>Many developers encounter UI hangs caused by main-thread blocking, yet identifying the exact source is often difficult. <a href="https://x.com/tiagodhenriques">Tiago Henriques</a> walks through a purposefully laggy demo app to show how to use Instruments&#8217; Time Profiler to determine the nature and scope of the issue. Reproduction and identification are only the first steps&#8212;Tiago also notes that deeper performance-analysis content may follow if readers show interest.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0114-07">SwiftUI Ratings</a></strong></h3><p>If you need to build an in-app rating/review interface or guide users more naturally toward leaving an App Store review, <strong>SwiftUI-Ratings</strong>, developed by <a href="https://x.com/jsedlacekjr">James Sedlacek</a>, offers a plug-and-play solution. It provides a highly customizable UI modeled after the App Store&#8217;s ratings and reviews page and allows developers to integrate any data source through the <code>AppRatingProviding</code> protocol (with mock and Supabase / App Store Connect examples included). A lightweight, modern, and extensible choice for implementing an in-app rating prompt.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-08">Swift Hugging Face</a></strong></h3><p>Hugging Face is the world&#8217;s leading open-source AI community and model hub, offering a vast ecosystem of models, datasets, tools, and collaboration spaces&#8212;serving as essential infrastructure for building and deploying modern AI applications.</p><p>As Hugging Face&#8217;s official Swift client, <strong>Swift Hugging Face</strong> provides two major capabilities:<br>First, it fully wraps the Hugging Face Hub API, giving Swift developers native access to models, datasets, Spaces, and more. Second, it integrates the Inference API, enabling tasks such as chat completion, embeddings, text-to-image/video generation, and speech-to-text to run directly on iOS, macOS, visionOS, as well as Linux and Windows.</p><p>In the article <a href="https://l.fatbobman.com/w0114-09">Introducing swift-huggingface: The Complete Swift Client for Hugging Face</a>, <a href="https://x.com/mattt">Mattt</a> explains the library&#8217;s design and usage in depth, opening the door for Swift developers to fully leverage the Hugging Face AI ecosystem.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-114?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-114?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#25366;&#25496;&#8220;&#27785;&#40664;&#30340;&#19987;&#23478;&#8221;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-114/">&#32593;&#39029;&#29256;</a></strong></p><p>&#20851;&#27880;&#25105;&#21338;&#23458;&#30340;&#35835;&#32773;&#21487;&#33021;&#30041;&#24847;&#21040;&#65292;&#26368;&#36817;&#19968;&#27573;&#26102;&#38388;&#25105;&#36739;&#23569;&#21457;&#34920;&#20010;&#20154;&#30340;&#20316;&#21697;&#65292;&#21462;&#32780;&#20195;&#20043;&#30340;&#26159;&#65292;&#25105;&#38470;&#32493;&#21457;&#24067;&#20102;&#22810;&#31687;&#26469;&#33258;&#19981;&#21516;&#24320;&#21457;&#32773;&#30340;&#23458;&#24231;&#25991;&#31456;&#12290;&#27809;&#38169;&#65292;&#36825;&#26159;&#25105;&#36817;&#26399;&#21457;&#36215;&#30340;&#19968;&#39033;&#29305;&#21035;&#20225;&#21010;&#8212;&#8212;&#36992;&#35831;&#37027;&#20123;&#22312;&#21508;&#33258;&#39046;&#22495;&#28145;&#32789;&#19988;&#21331;&#26377;&#24314;&#26641;&#30340;&#24320;&#21457;&#32773;&#65292;&#20998;&#20139;&#20182;&#20204;&#30340;&#23454;&#25112;&#32463;&#21382;&#12289;&#29420;&#23478;&#31192;&#31821;&#12289;&#29420;&#29305;&#35270;&#35282;&#20197;&#21450;&#24515;&#36335;&#21382;&#31243;&#12290;</p><p>&#20316;&#20026;&#19968;&#21517;&#21338;&#20027;&#65292;&#19981;&#30693;&#19981;&#35273;&#38388;&#25105;&#24050;&#32463;&#20889;&#20102;&#20960;&#30334;&#31687;&#25991;&#31456;&#12290;&#34429;&#28982;&#25105;&#30456;&#20449;&#36825;&#20123;&#20869;&#23481;&#20173;&#20855;&#20215;&#20540;&#65292;&#20294;&#19981;&#24471;&#19981;&#25215;&#35748;&#65292;&#21644;&#35768;&#22810;&#23450;&#26399;&#36755;&#20986;&#30340;&#20316;&#32773;&#19968;&#26679;&#65292;&#25105;&#36880;&#28176;&#38519;&#20837;&#20102;&#19968;&#31181;&#8220;&#31243;&#24335;&#21270;&#8221;&#30340;&#20889;&#20316;&#24815;&#24615;&#20013;&#12290;&#25105;&#30340;&#25991;&#31456;&#24448;&#24448;&#20391;&#37325;&#20110;&#25506;&#35752; API &#30340;&#29992;&#27861;&#12289;&#21078;&#26512;&#20869;&#37096;&#32454;&#33410;&#65292;&#20294;&#26356;&#22810;&#26159;&#22522;&#20110;&#8220;Demo&#8221;&#24605;&#32500;&#26469;&#26500;&#24314;&#30340;&#12290;&#21363;&#20415;&#28041;&#21450; Bug &#20462;&#22797;&#25110;&#36991;&#22353;&#25351;&#21335;&#65292;&#24448;&#24448;&#20063;&#21482;&#26159;&#22788;&#29702;&#19968;&#20010;&#20010;&#23396;&#31435;&#30340;&#8220;&#28857;&#8221;&#65292;&#32780;&#38750;&#36830;&#36143;&#30340;&#8220;&#32447;&#8221;&#25110;&#8220;&#38754;&#8221;&#12290;</p><p>&#20316;&#20026;&#21608;&#25253;&#32534;&#36753;&#65292;&#25105;&#20063;&#35266;&#23519;&#21040;&#65306;&#23613;&#31649;&#20114;&#32852;&#32593;&#19978;&#27599;&#21608;&#37117;&#26377;&#22823;&#37327;&#20248;&#31168;&#25216;&#26415;&#25991;&#31456;&#28044;&#29616;&#65292;&#20294;&#38024;&#23545;&#29305;&#23450;&#39046;&#22495;&#12289;&#33021;&#23637;&#24320;&#28145;&#24230;&#35752;&#35770;&#19988;&#36148;&#36817;&#19968;&#32447;&#23454;&#25112;&#30340;&#20869;&#23481;&#21364;&#26174;&#24471;&#31232;&#32570;&#12290;&#36880;&#28176;&#25105;&#24847;&#35782;&#21040;&#65292;&#20027;&#35201;&#21407;&#22240;&#26159;&#37027;&#20123;&#22859;&#25112;&#22312;&#19968;&#32447;&#30340;&#24320;&#21457;&#32773;&#24448;&#24448;&#32570;&#20047;&#26102;&#38388;&#25110;&#31934;&#21147;&#26469;&#25776;&#20889;&#36825;&#31867;&#38271;&#25991;&#12290;&#20026;&#27492;&#65292;&#20960;&#20010;&#26376;&#21069;&#25105;&#24320;&#22987;&#31574;&#21010;&#36825;&#39033;&#27963;&#21160;&#65292;&#20027;&#21160;&#21521;&#36825;&#31867;&#24320;&#21457;&#32773;&#32422;&#31295;&#65292;&#35797;&#22270;&#25366;&#25496;&#36825;&#20123;&#8220;&#27785;&#40664;&#30340;&#19987;&#23478;&#8221;&#65292;&#23558;&#20182;&#20204;&#33041;&#28023;&#20013;&#30340;&#8220;&#38544;&#24615;&#30693;&#35782;&#8221;&#26174;&#24615;&#21270;&#12290;</p><p>&#22312;&#19982;&#20316;&#32773;&#20204;&#30340;&#27807;&#36890;&#20013;&#65292;&#25105;&#24120;&#36935;&#21040;&#36825;&#26679;&#30340;&#22330;&#26223;&#65306;&#23545;&#26041;&#19981;&#30693;&#36947;&#35813;&#20889;&#20160;&#20040;&#12290;&#23613;&#31649;&#20182;&#20204;&#27599;&#22825;&#37117;&#22312;&#35299;&#20915;&#26840;&#25163;&#30340;&#38590;&#39064;&#65292;&#20294;&#22240;&#38271;&#26399;&#28024;&#28139;&#20854;&#20013;&#65292;&#24448;&#24448;&#8220;&#36523;&#22312;&#24208;&#23665;&#19981;&#30693;&#30495;&#38754;&#30446;&#8221;&#65292;&#36880;&#28176;&#24573;&#30053;&#20102;&#36825;&#20123;&#32463;&#39564;&#30340;&#26222;&#36866;&#20215;&#20540;&#12290;&#35768;&#22810;&#20154;&#35748;&#20026;&#33258;&#24049;&#30340;&#24037;&#20316;&#31232;&#26494;&#24179;&#24120;&#8212;&#8212;&#8220;&#38590;&#36947;&#36825;&#20123;&#19981;&#26159;&#24120;&#35782;&#21527;&#65311;&#30495;&#30340;&#20250;&#26377;&#20154;&#24819;&#20102;&#35299;&#36825;&#20123;&#65311;&#8221;&#27599;&#24403;&#27492;&#26102;&#65292;&#25105;&#20415;&#20250;&#20999;&#25442;&#22238;&#24320;&#21457;&#32773;&#21644;&#35835;&#32773;&#30340;&#35270;&#35282;&#65292;&#21521;&#20182;&#20204;&#34920;&#36798;&#25105;&#23545;&#35813;&#39046;&#22495;&#30340;&#22909;&#22855;&#65292;&#20197;&#21450;&#25105;&#28212;&#26395;&#25506;&#31350;&#30340;&#37027;&#20123;&#8220;&#34892;&#19994;&#31192;&#23494;&#8221;&#12290;</p><p>&#22312; AI &#26102;&#20195;&#65292;&#22823;&#27169;&#22411;&#25110;&#35768;&#24050;&#32463;&#25484;&#25569;&#20102;&#28023;&#37327;&#30340; API &#29992;&#27861;&#21644;&#20195;&#30721;&#33539;&#24335;&#12290;&#20294;&#23545;&#20110;&#20154;&#31867;&#32780;&#35328;&#65292;&#37027;&#20123;&#30495;&#25370;&#30340;&#24773;&#24863;&#12289;&#19982;&#29289;&#29702;&#19990;&#30028;&#30340;&#30495;&#23454;&#30896;&#25758;&#12289;&#20197;&#21450;&#20174;&#26080;&#25968;&#27425;&#22833;&#36133;&#23454;&#36341;&#20013;&#25552;&#28860;&#20986;&#30340;&#25945;&#35757;&#65292;&#20173;&#26159;&#25105;&#20204;&#26368;&#23453;&#36149;&#19988;&#29420;&#29305;&#30340;&#36130;&#23500;&#12290;</p><p>&#38750;&#24120;&#24863;&#35874;&#36825;&#20123;&#20316;&#32773;&#65292;&#33021;&#22312;&#32321;&#24537;&#30340;&#24037;&#20316;&#20013;&#25277;&#35843;&#26102;&#38388;&#19982;&#31934;&#21147;&#65292;&#26080;&#31169;&#22320;&#20998;&#20139;&#20182;&#20204;&#30340;&#30693;&#35782;&#23453;&#34255;&#12290;&#25991;&#20013;&#30340;&#35768;&#22810;&#20869;&#23481;&#65292;&#33509;&#38750;&#32463;&#36807;&#38271;&#26399;&#30340;&#24037;&#31243;&#23454;&#36341;&#21644;&#34987;&#22256;&#38590;&#21453;&#22797;&#22320;&#8220;&#25240;&#30952;&#8221;&#65292;&#26159;&#32477;&#19981;&#21487;&#33021;&#20135;&#29983;&#22914;&#27492;&#28145;&#21051;&#30340;&#20307;&#24735;&#30340;&#12290;</p><p>&#36825;&#39033;&#25366;&#25496;&#8220;&#27785;&#40664;&#19987;&#23478;&#8221;&#30340;&#35745;&#21010;&#20173;&#22312;&#32487;&#32493;&#12290;&#36825;&#19981;&#20165;&#26159;&#20026;&#20102;&#20016;&#23500;&#21338;&#23458;&#30340;&#20869;&#23481;&#65292;&#26356;&#26159;&#20026;&#20102;&#25105;&#20204;&#33258;&#24049;&#65292;&#20026;&#20102;&#31038;&#21306;&#12290;&#22312;&#36825;&#20010;&#20449;&#24687;&#36880;&#28176;&#34987; AI &#21516;&#36136;&#21270;&#30340;&#20170;&#22825;&#65292;&#25105;&#24076;&#26395;&#33021;&#20026;&#22823;&#23478;&#20445;&#30041;&#24182;&#21576;&#29616;&#26356;&#22810;&#30001;&#40092;&#27963;&#32463;&#39564;&#38136;&#23601;&#30340;&#12289;&#19981;&#19968;&#26679;&#30340;&#22768;&#38899;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-113/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/a-deep-dive-into-swiftui-rich-text-layout/?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">SwiftUI &#22270;&#25991;&#28151;&#25490;&#28145;&#24230;&#21078;&#26512;&#65306;&#36229;&#36234; AttributedString &#8212;&#8212; MarkdownView &#19982; RichText &#30340;&#23454;&#29616;</a></strong></h3><p>&#34429;&#28982; AttributedString &#24050;&#32463;&#25512;&#20986;&#22810;&#24180;&#65292;&#20294; SwiftUI &#20173;&#28982;&#32570;&#20047;&#12300;&#23436;&#25972; Markdown &#28210;&#26579; + &#22270;&#25991;&#28151;&#25490; + &#21487;&#36873;&#20013;&#25991;&#26412; + &#31934;&#32454;&#20132;&#20114;&#12301;&#30340;&#23448;&#26041;&#25903;&#25345;&#12290;&#20316;&#20026; <a href="https://github.com/LiYanan2004/MarkdownView?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">MarkdownView</a> &#21644; <a href="https://github.com/LiYanan2004/RichText?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">RichText</a> &#30340;&#20316;&#32773;&#65292;<a href="https://x.com/LiYanan2004">LiYanan</a> &#22312;&#26412;&#25991;&#20013;&#31995;&#32479;&#22238;&#39038;&#20102;&#20182;&#20026;&#35299;&#20915;&#36825;&#20123;&#38382;&#39064;&#25152;&#36827;&#34892;&#30340;&#25216;&#26415;&#25506;&#32034;&#8212;&#8212;&#20174;&#26368;&#21021;&#23581;&#35797; Layout &#21327;&#35758;&#65292;&#21040;&#36393;&#36807; TextRenderer &#30340;&#31181;&#31181;&#38480;&#21046;&#65292;&#20877;&#21040;&#26368;&#32456;&#22522;&#20110; TextKit &#25171;&#36896;&#21487;&#20132;&#20114;&#12289;&#39640;&#24615;&#33021;&#30340; Markdown &#28210;&#26579;&#32452;&#20214;&#12290;&#36825;&#26082;&#26159;&#19968;&#20221;&#20851;&#20110;&#22362;&#25345;&#19982;&#25104;&#38271;&#30340;&#25216;&#26415;&#22797;&#30424;&#65292;&#20063;&#26159;&#30446;&#21069; SwiftUI &#25991;&#26412;&#28210;&#26579;&#39046;&#22495;&#38590;&#24471;&#30340;&#36164;&#26009;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-01">&#25105;&#35813;&#24320;&#21551;&#21738;&#20123; Swift &#32534;&#35793;&#22120;&#35774;&#32622;&#65311; (What Setting Should I Use?)</a></strong></h3><p>&#21313;&#23681;&#30340; Swift &#20174;&#26410;&#20687;&#20170;&#22825;&#36825;&#26679;&#24378;&#22823;&#65292;&#20294;&#38543;&#20043;&#32780;&#26469;&#30340;&#22797;&#26434;&#24230;&#20063;&#26174;&#32780;&#26131;&#35265;&#12290;&#38500;&#20102;&#26356;&#22810;&#30340;&#35821;&#35328;&#29305;&#24615;&#65292;&#20320;&#36824;&#35201;&#38754;&#23545;&#19981;&#26029;&#25193;&#24352;&#30340;&#32534;&#35793;&#22120;&#35774;&#32622;&#8212;&#8212;&#23427;&#20204;&#24444;&#27492;&#32452;&#21512;&#65292;&#36275;&#20197;&#26500;&#24314;&#20986;&#8220;&#19981;&#21516;&#24180;&#20195;&#12289;&#19981;&#21516;&#21746;&#23398;&#12289;&#19981;&#21516;&#35821;&#20041;&#8221;&#30340; Swift&#12290;</p><p>&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#29992;&#38750;&#24120;&#25509;&#22320;&#27668;&#30340;&#26041;&#24335;&#22238;&#31572;&#20102;&#19968;&#20010;&#29616;&#23454;&#38382;&#39064;&#65306;**&#22312; Swift 6.2 / Xcode 26 &#26102;&#20195;&#65292;&#25105;&#31350;&#31455;&#24212;&#35813;&#25171;&#24320;&#21738;&#20123;&#32534;&#35793;&#22120;&#35774;&#32622;&#65311;&#22914;&#26524;&#20320;&#27491;&#29369;&#35947;&#26159;&#21542;&#20999;&#25442;&#21040; 6 &#35821;&#35328;&#27169;&#24335;&#65292;&#25110;&#36831;&#36831;&#25343;&#19981;&#23450;&#20027;&#24847; <code>StrictConcurrency</code> &#24212;&#35774;&#20026; minimal&#12289;targeted &#25110; complete&#65292;&#36825;&#31687;&#25991;&#31456;&#21487;&#20197;&#35270;&#20316;&#19968;&#20221;&#20915;&#31574;&#36741;&#21161;&#28165;&#21333;&#65292;&#24110;&#21161;&#20320;&#25353;&#26356;&#21487;&#25511;&#12289;&#28176;&#36827;&#30340;&#26041;&#24335;&#23436;&#25104;&#36801;&#31227;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-02">&#26522;&#20030;&#32972;&#21518;&#30340;&#21147;&#37327; (Swift Enum Hidden Magic Tricks)</a></strong></h3><p>&#26522;&#20030;&#26159; Swift &#20013;&#26497;&#20855;&#36776;&#35782;&#24230;&#30340;&#35821;&#35328;&#29305;&#24615;&#65292;&#20854;&#33021;&#21147;&#36828;&#36229;&#8220;&#24102;&#28857;&#20851;&#32852;&#20540;&#30340;&#20998;&#25903;&#35821;&#21477;&#8221;&#12290;&#22312;&#35768;&#22810;&#36164;&#28145; Swift/iOS &#24320;&#21457;&#32773;&#30524;&#20013;&#65292;&#26522;&#20030;&#26356;&#20687;&#26159;&#19968;&#31181;<strong>&#29992;&#20110;&#22609;&#36896;&#26550;&#26500;&#36793;&#30028;&#30340;&#24314;&#27169;&#24037;&#20855;</strong>&#65292;&#23588;&#20854;&#22312;&#31649;&#29702;&#22797;&#26434;&#29366;&#24577;&#26102;&#26684;&#22806;&#31361;&#20986;&#12290;<a href="https://www.linkedin.com/in/valentebruno/">Bruno Valente Pimentel</a>&#22312;&#26412;&#25991;&#20013;&#31995;&#32479;&#38416;&#36848;&#20102;&#26522;&#20030;&#22914;&#20309;&#24110;&#21161;&#25105;&#20204;<strong>&#35753;&#26080;&#25928;&#29366;&#24577;&#19981;&#21487;&#34920;&#31034;&#65288;Make Invalid States Unrepresentable&#65289;</strong>&#65292;&#24182;&#36890;&#36807;&#22810;&#20010;&#30495;&#23454;&#39033;&#30446;&#30340;&#28436;&#21270;&#36807;&#31243;&#23637;&#31034;&#36825;&#19968;&#24605;&#24819;&#22914;&#20309;&#20174;&#8220;&#35821;&#27861;&#25216;&#24039;&#8221;&#21319;&#32423;&#20026;&#8220;&#35774;&#35745;&#26041;&#27861;&#35770;&#8221;&#12290;</p><blockquote><p>&#8220;&#35753;&#26080;&#25928;&#29366;&#24577;&#19981;&#21487;&#34920;&#31034;&#8221;&#26159;&#31867;&#22411;&#39537;&#21160;&#35774;&#35745;&#25512;&#23815;&#30340;&#20851;&#38190;&#24605;&#24819;&#20043;&#19968;&#12290;&#22914;&#26524;&#20320;&#24819;&#36827;&#19968;&#27493;&#29702;&#35299;&#36825;&#19968;&#29702;&#24565;&#30340;&#24213;&#23618;&#24605;&#24819;&#65292;&#38750;&#24120;&#24314;&#35758;&#19968;&#24182;&#38405;&#35835; <a href="https://x.com/AlexOzun">Alex Ozun</a> &#30340; <a href="https://swiftology.io/collections/type-driven-design/?utm_source=fatbobman%20weekly%20issue%20114&amp;utm_medium=web">Type-Driven Design with Swift</a> &#31995;&#21015;&#25991;&#31456;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-03">&#20026;&#24212;&#29992;&#35774;&#32622;&#26367;&#20195;&#21517; (Make Your App Visible with Alternative App Names)</a></strong></h3><p>&#22312;&#26085;&#24120;&#20351;&#29992;&#20013;&#65292;&#20320;&#21487;&#33021;&#27880;&#24847;&#21040;&#26576;&#20123; iOS &#24212;&#29992;&#21487;&#20197;&#36890;&#36807;&#22810;&#20010;&#21517;&#31216;&#22312; Spotlight &#20013;&#34987;&#25628;&#32034;&#21040;&#65292;&#36825;&#22312;&#23454;&#38469;&#20351;&#29992;&#22330;&#26223;&#20013;&#38750;&#24120;&#20415;&#21033;&#12290;&#20854;&#32972;&#21518;&#27491;&#26159; SiriKit &#25552;&#20379;&#30340;&#33021;&#21147;&#65306;&#24320;&#21457;&#32773;&#21487;&#20197;&#22312;&#24212;&#29992;&#30340; Info.plist &#20013;&#37197;&#32622;&#26368;&#22810; 3 &#20010;&#26367;&#20195;&#21517;&#31216;&#65292;&#20351;&#29992;&#25143;&#33021;&#22815;&#36890;&#36807;&#19981;&#21516;&#30340;&#20851;&#38190;&#35789;&#26356;&#36731;&#26494;&#22320;&#25214;&#21040;&#20320;&#30340;&#24212;&#29992;&#12290;<a href="https://x.com/0xWDG">Wesley de Groot</a> &#22312;&#26412;&#25991;&#20013;&#20171;&#32461;&#20102;&#36825;&#19968;&#21151;&#33021;&#30340;&#20855;&#20307;&#23454;&#29616;&#26041;&#24335;&#12290;</p><blockquote><p>&#38543;&#30528; macOS 26 &#31227;&#38500;&#20102;&#8220;&#21551;&#21160;&#21488;&#8221;&#65288;Launchpad&#65289;&#65292;&#36234;&#26469;&#36234;&#22810;&#30340;&#29992;&#25143;&#24320;&#22987;&#20381;&#36182; Spotlight &#21551;&#21160;&#24212;&#29992;&#12290;&#25110;&#35768;&#26410;&#26469;&#65292;&#31867;&#20284;&#30340;&#26367;&#20195;&#21517;&#31216;&#26426;&#21046;&#20063;&#20250;&#34987;&#24341;&#20837;&#21040; macOS &#24179;&#21488;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-04">&#29992; @TabContentBuilder &#32452;&#32455;&#20320;&#30340; Tab &#22768;&#26126; (Organizing SwiftUI Views with TabContent and @TabContentBuilder)</a></strong></h3><p>&#22312;&#26368;&#36817;&#30340;&#20004;&#20010;&#29256;&#26412;&#20013;&#65292;SwiftUI &#23545; Tab &#25903;&#25345;&#36827;&#34892;&#20102;&#22823;&#24133;&#25193;&#23637;&#65306;&#20174;&#20256;&#32479;&#30340;&#24213;&#37096;&#20998;&#39029;&#23548;&#33322;&#65292;&#24310;&#20280;&#21040;&#26356;&#28789;&#27963;&#30340;&#32467;&#26500;&#21270;&#22330;&#26223;&#65292;&#20363;&#22914;&#22312;&#22823;&#23631;&#35774;&#22791;&#19978;&#34920;&#29616;&#31867;&#20284;&#20391;&#36793;&#26639;&#30340;&#23548;&#33322;&#27169;&#24335;&#12290;&#22240;&#27492;&#65292;&#35768;&#22810;&#39033;&#30446;&#30340; Tab &#22768;&#26126;&#24320;&#22987;&#21464;&#24471;&#36234;&#26469;&#36234;&#24222;&#22823;&#65306;&#35282;&#33394;&#25511;&#21046;&#12289;&#26465;&#20214;&#20998;&#25903;&#12289;&#23548;&#33322;&#26632;&#12289;&#26631;&#31614;&#37197;&#32622;&#19982;&#22242;&#38431;&#32422;&#23450;&#24448;&#24448;&#28151;&#26434;&#22312;&#21516;&#19968;&#20010; <code>TabView</code> &#20013;&#12290;<a href="https://www.linkedin.com/in/artem-mirzabekian/">Artem Mirzabekian</a> &#22312;&#25991;&#20013;&#24314;&#35758;&#23558;&#19982; Tab &#30456;&#20851;&#30340;&#37197;&#32622;&#20174;&#20027;&#24067;&#23616;&#20013;&#25277;&#31163;&#65292;&#20511;&#21161;&#33258;&#23450;&#20041;&#30340; <code>@TabContentBuilder</code> &#25645;&#24314;&#19968;&#20010;&#19987;&#23646;&#30340;&#12289;&#21487;&#32452;&#21512;&#30340; tab &#23450;&#20041;&#21306;&#22495;&#12290;&#36825;&#31181;&#32452;&#32455;&#26041;&#24335;&#33021;&#22815;&#26174;&#33879;&#25552;&#21319;&#21487;&#35835;&#24615;&#19982;&#21487;&#25193;&#23637;&#24615;&#65292;&#35753; Tab &#23548;&#33322;&#30340;&#32500;&#25252;&#19981;&#20877;&#25104;&#20026; SwiftUI &#39033;&#30446;&#30340;&#38590;&#28857;&#12290;</p><blockquote><p>&#38500;&#20102; <code>@ViewBuilder</code> &#22806;&#65292;SwiftUI &#36824;&#25552;&#20379;&#20102;&#22823;&#37327;&#39046;&#22495;&#19987;&#29992;&#30340; result builder&#65292;&#22914; <code>TableColumnBuilder</code>&#12289;<code>CommandsBuilder</code>&#12289;<code>SceneBuilder</code>&#12289;<code>ToolbarContentBuilder</code>&#12289;<code>ChartContentBuilder</code> &#31561;&#12290;&#26356;&#31934;&#30830;&#22320;&#36873;&#29992;&#36825;&#20123; builder&#65292;&#19981;&#20165;&#33021;&#35753;&#35270;&#22270;&#32467;&#26500;&#26356;&#28165;&#26224;&#65292;&#20063;&#33021;&#22312;&#22797;&#26434;&#22330;&#26223;&#65288;&#20363;&#22914;&#24182;&#29992; Charts &#19982; Table&#65289;&#20943;&#23569;&#31867;&#22411;&#25512;&#26029;&#36127;&#25285;&#65292;&#36991;&#20813;&#35302;&#21457; SwiftUI &#24120;&#35265;&#30340; &#8220;type-checking explosion&#8221;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-05">&#29992; LLDB &#35843;&#35797; SwiftUI &#24212;&#29992; (LLDB Power User Guide: Essential Commands &amp; SwiftUI Debugging)</a></strong></h3><p>&#35843;&#35797; SwiftUI &#21521;&#26469;&#19981;&#36731;&#26494;&#12290;&#30456;&#27604;&#22312;&#20195;&#30721;&#37324;&#19981;&#26029;&#25554;&#20837; <code>print</code>&#65292;&#23613;&#31649; LLDB &#30340;&#33021;&#21147;&#26356;&#24378;&#22823;&#65292;&#20294;&#21364;&#24448;&#24448;&#34987;&#24573;&#30053;&#12290;&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;<a href="https://www.linkedin.com/in/jai-krishna-chandrasekar/">Jai Krishna</a> &#36890;&#36807;&#22823;&#37327; SwiftUI &#31034;&#20363;&#28436;&#31034;&#20102;&#22914;&#20309;&#22312; LLDB &#20013;&#23454;&#26102;&#26597;&#30475;&#21644;&#20462;&#25913; <code>@State</code>&#12289;<code>@Binding</code>&#12289;<code>@Published</code> &#30340;&#20869;&#37096;&#29366;&#24577;&#65292;&#20351;&#29992; <code>Self._printChanges()</code> &#36861;&#36394;&#35270;&#22270;&#30340;&#37325;&#32472;&#26469;&#28304;&#65292;&#24182;&#20511;&#21161;&#31934;&#32454;&#21270;&#30340;&#26029;&#28857;&#31574;&#30053;&#23450;&#20301;&#24067;&#23616;&#19982;&#20132;&#20114;&#38382;&#39064;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-06">&#22914;&#20309;&#26597;&#25214;&#24212;&#29992;&#30340;&#25346;&#36215;&#21407;&#22240; (Identifying Hangs in iOS Apps)</a></strong></h3><p>&#35768;&#22810;&#24320;&#21457;&#32773;&#37117;&#20250;&#36935;&#21040;&#20027;&#32447;&#31243;&#38459;&#22622;&#23548;&#33268;&#30340; UI &#25346;&#36215;&#65292;&#20294;&#20855;&#20307;&#21345;&#22312;&#20160;&#20040;&#20301;&#32622;&#12289;&#30001;&#20309;&#24341;&#36215;&#65292;&#24182;&#19981;&#26159;&#27599;&#20010;&#20154;&#37117;&#33021;&#20934;&#30830;&#35843;&#35797;&#12290;<a href="https://x.com/tiagodhenriques">Tiago Henriques</a> &#36890;&#36807;&#19968;&#20010;&#21051;&#24847;&#21046;&#36896;&#21345;&#39039;&#30340;&#31034;&#20363; App&#65292;&#28436;&#31034;&#20102;&#22914;&#20309;&#21033;&#29992; Instruments &#30340; Time Profiler &#26469;&#21021;&#27493;&#21028;&#26029;&#38382;&#39064;&#30340;&#24615;&#36136;&#21644;&#33539;&#22260;&#12290;&#22797;&#29616;&#19982;&#35782;&#21035;&#21482;&#26159;&#35299;&#20915;&#38382;&#39064;&#30340;&#31532;&#19968;&#27493;&#65292;&#20316;&#32773;&#20063;&#34920;&#31034;&#22914;&#26524;&#35835;&#32773;&#24863;&#20852;&#36259;&#65292;&#26410;&#26469;&#36824;&#20250;&#32487;&#32493;&#25512;&#20986;&#36825;&#19968;&#20027;&#39064;&#30340;&#28145;&#20837;&#20869;&#23481;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0114-07">SwiftUI Ratings</a></strong></h3><p>&#22914;&#26524;&#20320;&#27491;&#22312;&#20026; App &#26500;&#24314;&#35780;&#20998;/&#35780;&#35770;&#30028;&#38754;&#65292;&#25110;&#24076;&#26395;&#22312;&#24212;&#29992;&#20869;&#26356;&#33258;&#28982;&#22320;&#24341;&#23548;&#29992;&#25143;&#21069;&#24448; App Store &#30041;&#19979;&#35780;&#20215;&#65292;&#30001; <a href="https://x.com/jsedlacekjr">James Sedlacek</a> &#24320;&#21457;&#30340; SwiftUI-Ratings &#25552;&#20379;&#20102;&#19968;&#22871;&#21363;&#25554;&#21363;&#29992;&#30340;&#35299;&#20915;&#26041;&#26696;&#12290;&#23427;&#23454;&#29616;&#20102;&#19968;&#20010;&#39640;&#24230;&#21487;&#23450;&#21046;&#30340;&#35780;&#20998;&#30028;&#38754;&#65292;&#39118;&#26684;&#19978;&#19982; App Store &#30340;&#35780;&#20998;&#19982;&#35780;&#35770;&#39029;&#30456;&#36817;&#65292;&#20801;&#35768;&#24320;&#21457;&#32773;&#36890;&#36807; <code>AppRatingProviding</code> &#21327;&#35758;&#28789;&#27963;&#25509;&#20837;&#20219;&#24847;&#25968;&#25454;&#28304;&#65288;&#39033;&#30446;&#20013;&#25552;&#20379;&#20102; mock &#23454;&#29616;&#19982; Supabase / App Store Connect API &#31034;&#20363;&#65289;&#12290;&#23545;&#20110;&#38656;&#35201;&#24555;&#36895;&#25645;&#24314;&#8220;&#24212;&#29992;&#20869;&#35780;&#20998;&#35831;&#27714;&#8221;&#21151;&#33021;&#30340;&#24320;&#21457;&#32773;&#26469;&#35828;&#65292;&#36825;&#26159;&#19968;&#20010;&#36731;&#37327;&#12289;&#29616;&#20195;&#12289;&#19988;&#26131;&#20110;&#25193;&#23637;&#30340;&#36873;&#25321;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0114-08">Swift Hugging Face</a></strong></h3><p>Hugging Face &#26159;&#20840;&#29699;&#39046;&#20808;&#30340;&#24320;&#28304; AI &#31038;&#21306;&#19982;&#27169;&#22411;&#24179;&#21488;&#65292;&#25552;&#20379;&#28023;&#37327;&#27169;&#22411;&#12289;&#25968;&#25454;&#38598;&#12289;&#24037;&#20855;&#38142;&#21450;&#21327;&#20316;&#31354;&#38388;&#65292;&#20316;&#20026;&#20851;&#38190;&#30340; AI &#22522;&#30784;&#35774;&#26045;&#65292;&#36171;&#33021;&#30740;&#31350;&#32773;&#12289;&#24037;&#31243;&#24072;&#19982;&#20225;&#19994;&#39640;&#25928;&#26500;&#24314;&#24182;&#37096;&#32626; AI &#24212;&#29992;&#12290;</p><p>&#20316;&#20026; Hugging Face &#23448;&#26041;&#20986;&#21697;&#30340; Swift &#23458;&#25143;&#31471;&#65292;<strong>Swift Hugging Face</strong> &#25552;&#20379;&#20102;&#20004;&#22823;&#26680;&#24515;&#33021;&#21147;&#65306;&#19968;&#26041;&#38754;&#65292;&#23427;&#23436;&#25972;&#23553;&#35013;&#20102; Hugging Face Hub API&#65292;&#20351;&#24320;&#21457;&#32773;&#33021;&#22815;&#20197;&#21407;&#29983; Swift &#26041;&#24335;&#31649;&#29702;&#27169;&#22411;&#12289;&#25968;&#25454;&#38598;&#12289;Spaces &#31561;&#36164;&#28304;&#65307;&#21478;&#19968;&#26041;&#38754;&#65292;&#23427;&#26080;&#32541;&#38598;&#25104; Inference API&#65292;&#35753;&#25991;&#26412;&#29983;&#25104;&#65288;Chat Completion&#65289;&#12289;&#25991;&#26412;&#21521;&#37327;&#21270;&#12289;&#25991;&#29983;&#22270;/&#35270;&#39057;&#65288;Text-to-Image/Video&#65289;&#12289;&#35821;&#38899;&#36716;&#20889;&#31561;&#20219;&#21153;&#33021;&#22815;&#30452;&#25509;&#22312; iOS&#12289;macOS&#12289;visionOS &#20035;&#33267; Linux &#19982; Windows &#19978;&#36816;&#34892;&#12290;</p><p>&#22312;&#25991;&#31456; <a href="https://l.fatbobman.com/w0114-09">Introducing swift-huggingface: The Complete Swift Client for Hugging Face</a> &#20013;&#65292;<a href="https://x.com/mattt">Mattt</a> &#35814;&#32454;&#38416;&#36848;&#20102;&#35813;&#24211;&#30340;&#35774;&#35745;&#29702;&#24565;&#19982;&#26680;&#24515;&#20351;&#29992;&#26041;&#24335;&#65292;&#20026; Swift &#24320;&#21457;&#32773;&#25171;&#24320;&#20102;&#25509;&#20837; Hugging Face AI &#29983;&#24577;&#30340;&#23436;&#25972;&#36335;&#24452;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #113]]></title><description><![CDATA[When Android Phones &#8220;Force-Compat&#8221; with AirDrop]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-113</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-113</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 01 Dec 2025 12:03:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8VTn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8VTn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8VTn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8VTn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12456,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/180290042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8VTn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 424w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 848w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 1272w, https://substackcdn.com/image/fetch/$s_!8VTn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3916d07b-aebd-4ddf-b37c-af7d68160e00_1920x1080.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>When Android Phones &#8220;Force-Compat&#8221; with AirDrop</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-113/">Read on web &#8594;</a></p><p>AirDrop has long enabled fast, lossless, cable-free transfers across Apple devices, forming a signature and tightly guarded advantage within the Apple ecosystem. But this long-standing situation has taken an unexpected turn. A few days ago, Google announced that the Pixel 10 can now interoperate with AirDrop <em>without</em> Apple&#8217;s involvement, bringing AirDrop-compatible wireless sharing to Android through Quick Share.</p><p>Shortly after, Qualcomm stated that Snapdragon-powered Android devices will &#8220;soon&#8221; support the same capability. In other words, this is no longer a Pixel-only experiment&#8212;it may spread quickly across the broader Android landscape.</p><p>Beyond Google&#8217;s technical effort, the decisive catalyst behind this breakthrough is likely the EU&#8217;s Digital Markets Act (DMA). AirDrop is built on AWDL (Apple Wireless Direct Link), a protocol that remains entirely private. However, under DMA&#8217;s interoperability requirements, Apple added support for Wi-Fi Aware starting in iOS 26. This dramatically lowered the barrier for this &#8220;forced compatibility&#8221;: Android phones can now broadcast standard Wi-Fi Aware signals to <em>discover</em> iPhones. And because this relies on an official industry standard, discovery is fast, connections are stable, and Apple has very limited grounds&#8212;legally or technically&#8212;to block it.</p><p>Over the years, the Android ecosystem has repeatedly initiated &#8220;pro-Apple compatibility&#8221;: from cross-platform file-transfer apps, to manufacturers adding support for Apple&#8217;s Live Photo format, and now to system-level near-field sharing. On one hand, this reflects the fact that many of Apple&#8217;s user experiences are genuinely superior; on the other hand, it shows how far Android manufacturers are willing to go to attract users embedded in the Apple ecosystem&#8212;actively aligning their experience with Apple&#8217;s. DMA, often criticized as overly strict, has in this case served as a perfectly timed catalyst, nudging Apple toward greater &#8220;openness&#8221; and enabling more seamless cross-platform experiences for consumers.</p><p>For Apple, however, the real challenge goes beyond regulatory battles. To maintain its ecosystem advantage, it must continue delivering new, compelling experiences. If one day such &#8220;forced compatibility&#8221; is no longer needed&#8212;because Apple&#8217;s distinctiveness has faded&#8212;<em>that</em> would be the scenario Apple fears far more than today&#8217;s developments.</p><p><a href="https://fatbobman.com/en/weekly/issue-112/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G0_b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G0_b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 424w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 848w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 1272w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G0_b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png" width="120" height="120" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:120,&quot;width&quot;:120,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11272,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/180290042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!G0_b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 424w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 848w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 1272w, https://substackcdn.com/image/fetch/$s_!G0_b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faa733661-3eee-42d4-bb70-e39cefc2eff4_120x120.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong><a href="https://l.fatbobman.com/boltai-week-en">Native macOS AI Client: GPT, Claude, Gemini &amp; Local Models</a></strong></h3><p><strong>Stop Context Switching &#183; Truly Native &#183; Ultra-Low Memory Usage</strong></p><p>Tired of browser tabs eating up your RAM? Try <strong>BoltAI</strong>.</p><p>It seamlessly integrates GPT, Claude, Gemini, and Ollama local models directly into your development workflow. Access the latest AI capabilities in a unified, native interface.</p><p>With features like <strong>screen context awareness</strong> and <strong>instant code explanation</strong>, it&#8217;s the ultimate native AI tool built for developers.</p><blockquote><p>&#127881; <em><strong>Special Offer for Fatbobman Readers:</strong></em> <br><em>Use code</em> <em><strong>BFCM25</strong></em> <em>for</em> <em><strong>51% OFF</strong></em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://l.fatbobman.com/boltai-week-en&quot;,&quot;text&quot;:&quot;&#128640; Try BoltAI Today&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://l.fatbobman.com/boltai-week-en"><span>&#128640; Try BoltAI Today</span></a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/from-ios-to-android/?utm_source=fatbobman%20weekly%20issue%20113&amp;utm_medium=web">From iOS to Android: A Candid Look at My Real-World Journey into Dual-Platform Development</a></strong></h3><p>For many developers in the Apple ecosystem, Android feels both familiar and distant: massive user base yet fragmented ecosystem; significant revenue potential yet uncertain investment returns. This ambivalence keeps many hesitating over whether to develop an Android version. Senior iOS developer <a href="https://x.com/iVulgur">Shudao Wang</a> has pursued a &#8220;dual-platform parallel&#8221; strategy for years. In this article, he shares real-world experiences from dual-platform development: how to align features across platforms, trade-offs when facing system differences, variations in operational performance, and changes in revenue structure.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-01">Skip Framework: A Cross-Platform Journey for Native iOS Developer</a></strong></h3><p><a href="https://www.linkedin.com/in/maxim-ermolaev-128156356/">Maxim Ermolaev</a> shares his practical experience migrating a SwiftUI app to Android, revealing Skip&#8217;s real-world capabilities and boundaries. For SwiftUI features Skip already supports, the migration process is relatively smooth. For advanced features not yet covered, the author uses ComposeView to embed Jetpack Compose code directly within the same Swift file, providing customized implementations for the Android side. Maxim&#8217;s conclusion is pragmatic: Skip is sufficient for iOS-first teams to quickly obtain a &#8220;functional and consistent&#8221; Android client. However, achieving pixel-perfect visual and interaction parity across both platforms requires more platform-specific work on the Android side, or using Skip Lite to share business logic while keeping the UI fully native.</p><blockquote><p>As the Swift Android SDK matures and tools like Skip continue to improve, Swift&#8217;s possibilities in the Android world are rapidly transitioning from &#8220;experimental&#8221; to &#8220;production-ready.&#8221; These two authors present the current real-world path from different perspectives, providing valuable reference for Swift developers considering &#8220;crossing to the other side.&#8221;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-02">Building Mac Farm: Running 2000+ iOS Pipelines Daily</a></strong></h3><p>In this article, <a href="https://x.com/ysf_ozgul">Yusuf &#214;zg&#252;l</a> details how the Trendyol team built a macOS Farm consisting of 130 devices from scratch to comfortably support over 2000 iOS pipelines daily. The entire system uses a self-developed VM management system based on Apple Virtualization Framework, solves secure auto-login for batch devices through Authorization Plug-ins, identifies and fixes performance bottlenecks in VM&#8217;s P/E Core recognition, and builds a Grafana monitoring and alerting system to achieve a self-healing Runner cluster. For pipelines, performance is further enhanced through Tuist Cache (approximately 70% faster builds) and selective testing (approximately 80% faster tests).</p><blockquote><p>A rare comprehensive case study of macOS Farm implementation: from virtualization architecture to performance tuning, from logging and monitoring to pipeline design, covering nearly all key aspects needed for enterprise-level iOS CI/CD.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-03">Building iOS and Mac apps in Zed: SwiftUI Previews</a></strong></h3><p>While developers can now develop and debug iOS apps in Zed, they still cannot access Xcode&#8217;s killer feature: Preview. The typical workaround is to keep an Xcode preview window open alongside Zed, but Xcode doesn&#8217;t automatically jump to the corresponding Preview when switching between SwiftUI files. <a href="https://mastodon.social/@lxmn">Adrian Ross</a> shares a clever trick: using a script combined with Zed Task to synchronize Xcode with Zed&#8217;s editing view, automatically displaying the corresponding Preview in an external preview window, essentially replicating the &#8220;using Preview in Zed&#8221; experience.</p><blockquote><p>This approach isn&#8217;t limited to Zed&#8212;any macOS editor can use similar methods to work seamlessly with Xcode&#8217;s Preview functionality.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-04">Enabling Selection, Double-Click and Context Menus in SwiftUI List Rows on macOS</a></strong></h3><p>macOS&#8217;s SwiftUI List differs significantly from iOS in desktop-specific interactions like row selection, double-click, and context menus. Developers need to use a List initializer with a <code>selection</code> parameter to enable selection functionality, and use the <code>contextMenu(forSelectionType:menu:primaryAction:)</code> modifier to implement both double-click operations and context menus. Compared to iOS, macOS&#8217;s List is closer to AppKit&#8217;s table-style interaction model. In this article, <a href="https://x.com/gabtheodor">Gabriel Theodoropoulos</a> demonstrates with concise examples how to properly combine these APIs to implement standard desktop interactions in macOS SwiftUI lists.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-05">Using Associated Domains Alternate Mode during Development</a></strong></h3><p>When developing features involving Associated Domains (such as Universal Links, Shared Web Credentials, or App Clips), iOS by default fetches the <code>apple-app-site-association</code> (AASA) file through Apple&#8217;s CDN rather than directly from the server. While this works well in production, it causes inconvenience during development: file changes require waiting for CDN propagation, and local or staging servers may not be publicly accessible at all. <a href="https://x.com/tanaschita">Natascha Fadeeva</a> introduces Apple&#8217;s Alternate Mode: by adding suffixes like <code>?mode=developer</code> to Associated Domains entries, iOS bypasses the CDN and fetches the AASA file directly from the server. With this mechanism, developers can make configurations take effect immediately and debug in local environments without waiting for CDN cache refresh, significantly improving development efficiency.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-06">Understanding Data Races: A Visual Guide for Swift Developers</a></strong></h3><p>Data races are a core concept in concurrent programming that&#8217;s difficult to understand. <strong>Krishna</strong> uses a series of illustrations&#8212;several ToddlerBots (toddler robots) coloring the same coloring page together&#8212;to visually demonstrate how shared mutable state causes chaos in concurrent environments: from minor result inconsistencies to logic failures and even crashes caused by interleaved reads and writes.</p><blockquote><p>The article&#8217;s greatest strength is being &#8220;richly illustrated.&#8221; The ToddlerBot visual narrative successfully transforms a traditionally dry and serious technical topic into something vivid and easy to understand. Krishna indicates that future articles will continue using the ToddlerBot character to build a coherent mental model for Swift concurrency.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-09">Teaching AI to Read Xcode Builds</a></strong></h3><p>While today&#8217;s AI may not consistently outperform seasoned developers at <em>writing</em> code, it is almost always superior at <em>reading data</em> and breaking down complex problems&#8212;especially when the information it receives is rich and well-structured. With Apple open-sourcing <strong>swift-build</strong>, the Tuist team gained access to detailed build-event data directly from the build service, storing it in SQLite so AI agents can genuinely <em>understand</em> a build rather than merely scrape <code>xcodebuild</code>&#8217;s text output.</p><p>In this article, <a href="https://x.com/pepicrft">Pedro Pi&#241;era</a> walks through this approach and demonstrates, with real-world cases such as Wikipedia iOS and Tuist, how AI can leverage structured build data to provide diagnostics and optimization insights far beyond traditional log parsing. The result is a clear technical path toward real-time build observability and AI assistants that truly &#8220;understand&#8221; the build system.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0113-07">SwiftUI-Popover: A Popover Library Supporting watchOS</a></strong></h3><p>While SwiftUI provides the <code>.popover</code> modifier, its behavior varies across platforms: on iPhone it degrades to a sheet, and watchOS doesn&#8217;t support it at all. <a href="https://github.com/qusc">Quirin Schweigert</a>&#8216;s SwiftUI-Popover is a lightweight, pure SwiftUI popover library that provides consistent popover functionality across platforms, supporting all SwiftUI platforms including watchOS. The library&#8217;s distinctive feature is that arrows automatically follow the attachment point position and can be flexibly embedded into any view hierarchy.</p><pre><code>// 1. Attach popover
  Image(systemName: &#8220;globe&#8221;)
      .swiftUIPopover(
          isPresented: $showPopover,
          isDismissible: true,        // Tap background to dismiss
          isExclusive: true,           // Exclusive display
          preferredAttachmentEdge: .top // Prefer attaching at top
      ) {
          Text(&#8221;Popover content&#8221;)
      }
&#8203;
  // 2. Enable popover rendering on container view
  .presentPopovers()</code></pre><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-08">SwiftIR: Modern ML Compiler Infrastructure for Swift</a></strong></h3><p>Currently available ML paths in Swift mainly include Foundation&#8217;s <code>_Differentiation</code>, handwritten Accelerate/Metal, and the now-discontinued Swift for TensorFlow. However, they face performance bottlenecks, high development costs, or lack of maintenance respectively. SwiftIR, developed by <a href="https://www.linkedin.com/in/pedronrodriguez/">Pedro N. Rodriguez</a>, emerged as a solution to these challenges.</p><p>SwiftIR intercepts Swift&#8217;s native automatic differentiation (<code>@differentiable</code>) operations through <code>DifferentiableTracer</code>, automatically builds complete computation graphs, and compiles to the same runtime (XLA/PJRT) as JAX/TensorFlow for execution on CPU/GPU/TPU. The project&#8217;s biggest breakthrough: While loop compilation time remains constant (~43ms, compared to tens of minutes for traditional unrolling), gradient overhead is only ~1.0x (compared to 2.5-4.3x for standard Swift), with performance significantly superior to standard Swift at scale. This brings truly modern ML compiler infrastructure to Swift.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-113?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-113?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#24403; Android &#25163;&#26426;&#12302;&#24378;&#34892;&#20860;&#23481;&#12303;AirDrop</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-113/">&#32593;&#39029;&#29256;</a></strong></p><p>AirDrop &#35753;&#20351;&#29992;&#32773;&#21487;&#20197;&#22312;&#21508;&#31181;&#19981;&#21516;&#31867;&#22411;&#30340;&#33529;&#26524;&#35774;&#22791;&#19978;&#39640;&#25928;&#12289;&#26080;&#25439;&#30340;&#25968;&#25454;&#20256;&#36755;&#65292;&#23427;&#19968;&#30452;&#26159;&#33529;&#26524;&#29983;&#24577;&#30340;&#19987;&#23646;&#19988;&#26680;&#24515;&#21151;&#33021;&#12290;&#20294;&#65292;&#36825;&#31181;&#24773;&#20917;&#29616;&#22312;&#20986;&#29616;&#20102;&#8220;&#22855;&#24618;&#8221;&#30340;&#21464;&#21270;&#12290;&#20960;&#22825;&#21069;&#65292;&#35895;&#27468;&#23459;&#24067;&#22312; Pixel 10 &#20013;&#65292;&#22312;&#27809;&#26377;&#33529;&#26524;&#30340;&#21442;&#19982;&#19979;&#65292;&#20026; Quick Share &#25552;&#20379;&#20102; AirDrop &#30340;&#20860;&#23481;&#26426;&#21046;&#65292;&#23454;&#29616;&#20102;&#23433;&#21331;&#25163;&#26426;&#19982;&#33529;&#26524;&#25163;&#26426;&#22522;&#20110; AirDrop &#30340;&#26080;&#32447;&#20114;&#36890;&#12290;</p><p>&#38543;&#21518;&#65292;&#39640;&#36890;&#20063;&#23459;&#24067;&#20854;&#25645;&#36733; Snapdragon &#30340; Android &#35774;&#22791;&#8220;&#24456;&#24555;&#23601;&#20250;&#8221;&#25903;&#25345;&#36825;&#19968;&#36335;&#32447;&#65292;&#20063;&#23601;&#26159;&#35828;&#36825;&#19981;&#20877;&#26159; Pixel &#30340;&#19987;&#23646;&#21151;&#33021;&#65292;&#32780;&#26377;&#26395;&#25193;&#23637;&#21040;&#26356;&#24191;&#27867;&#30340; Android &#25163;&#26426;&#38453;&#33829;&#12290;</p><p>&#38500;&#20102;&#35895;&#27468;&#30340;&#25216;&#26415;&#33021;&#21147;&#22806;&#65292;&#26412;&#27425;&#20114;&#36890;&#30340;&#26368;&#22823;&#25512;&#25163;&#25110;&#35768;&#27491;&#26159; DMA(&#27431;&#30431;&#12298;&#25968;&#23383;&#24066;&#22330;&#27861;&#26696;&#12299;)&#12290;AirDrop &#20381;&#36182;&#30340;&#25216;&#26415;&#26159; AWDL (Apple Wireless Direct Link)&#65292;&#21363;&#20415;&#21040;&#29616;&#22312;&#20063;&#26159;&#31169;&#26377;&#30340;&#12290;&#20294;&#26159; DMA &#30340;&#35201;&#27714;&#19979;&#65292;&#33529;&#26524;&#20174; iOS 26 &#24320;&#22987;&#24341;&#20837;&#20102;&#23545; Wi-Fi Aware &#25903;&#25345;&#65292;&#36825;&#22823;&#24133;&#38477;&#20302;&#20102;&#26412;&#27425;&#8220;&#24378;&#34892;&#20860;&#23481;&#8221;&#30340;&#38590;&#24230;&#12290;&#23433;&#21331;&#25163;&#26426;&#21487;&#20197;&#30452;&#25509;&#21457;&#20986;&#26631;&#20934;&#30340; Wi-Fi Aware &#20449;&#21495;&#21435;&#23547;&#25214; iPhone&#65292;&#24182;&#19988;&#30001;&#20110;&#36208;&#30340;&#26159;&#23448;&#26041;&#26631;&#20934;&#21327;&#35758;&#65292;&#36830;&#25509;&#26497;&#20854;&#31283;&#23450;&#65292;&#21457;&#29616;&#36895;&#24230;&#26497;&#24555;&#65292;&#32780;&#19988;&#33529;&#26524;&#24456;&#38590;&#26377;&#29702;&#30001;&#21435;&#23553;&#26432;&#12290;</p><p>&#20174;&#21378;&#21830;&#25552;&#20379;&#36328;&#31471;&#24212;&#29992;&#23454;&#29616;&#26080;&#32447;&#20114;&#32852;&#65292;&#21040;&#37096;&#20998;&#21378;&#21830;&#20027;&#21160;&#36866;&#37197;&#33529;&#26524;&#30340; livePhoto&#65292;&#36825;&#20123;&#24180;&#20174;&#23433;&#21331;&#38453;&#33829;&#21457;&#36215;&#30340;&#23545;&#33529;&#26524;&#30340;&#20027;&#21160;&#20860;&#23481;&#23649;&#35265;&#19981;&#40092;&#12290;&#36825;&#19968;&#26041;&#38754;&#34920;&#29616;&#20986;&#20102;&#33529;&#26524;&#30340;&#24456;&#22810;&#23454;&#29616;&#21644;&#20307;&#39564;&#30830;&#26377;&#36807;&#20154;&#20043;&#22788;&#65292;&#21478;&#19968;&#26041;&#38754;&#20063;&#23637;&#29616;&#20986;&#23433;&#21331;&#21378;&#21830;&#26356;&#24895;&#24847;&#20026;&#20102;&#33719;&#21462;&#33529;&#26524;&#29983;&#24577;&#30340;&#29992;&#25143;&#32780;&#20027;&#21160;&#20986;&#20987;&#65292;&#22312;&#20307;&#39564;&#19978;&#23545;&#40784;&#12290;DMA &#36825;&#31181;&#22312;&#26576;&#20123;&#26041;&#38754;&#30475;&#36215;&#26469;&#36807;&#20998;&#33499;&#21051;&#30340;&#27861;&#35268;&#65292;&#21448;&#24688;&#22914;&#20854;&#20998;&#30340;&#20419;&#20351;&#20102;&#33529;&#26524;&#30340;&#8220;&#24320;&#25918;&#8221;&#65292;&#20174;&#32780;&#21019;&#36896;&#20986;&#26356;&#22810;&#30340;&#36328;&#24179;&#21488;&#26080;&#32541;&#20307;&#39564;&#65292;&#28385;&#36275;&#20102;&#30456;&#24403;&#19968;&#37096;&#20998;&#28040;&#36153;&#32773;&#30340;&#38656;&#27714;&#12290;</p><p>&#23545;&#20110;&#33529;&#26524;&#26469;&#35828;&#65292;&#22312;&#27861;&#24459;&#25915;&#38450;&#25112;&#22806;&#65292;&#21482;&#26377;&#19981;&#26029;&#22320;&#25512;&#20986;&#26356;&#20855;&#21560;&#24341;&#21147;&#30340;&#26032;&#21151;&#33021;&#25165;&#33021;&#20445;&#25345;&#33529;&#26524;&#29983;&#24577;&#30340;&#8220;&#20248;&#21183;&#8221;&#12290;&#19968;&#26086;&#26576;&#19968;&#22825;&#65292;&#36825;&#31181;&#8220;&#24378;&#34892;&#20860;&#23481;&#8221;&#19981;&#20877;&#26377;&#38656;&#27714;&#65292;&#37027;&#20040;&#23601;&#24847;&#21619;&#30528;&#33529;&#26524;&#30340;&#8220;&#29420;&#29305;&#24615;&#8221;&#34928;&#33853;&#20102;&#12290;&#30456;&#27604;&#36215;&#29616;&#22312;&#30340;&#24773;&#20917;&#26469;&#35828;&#65292;&#25105;&#24819;&#33529;&#26524;&#26356;&#19981;&#24819;&#30475;&#21040;&#36825;&#26679;&#30340;&#22330;&#26223;&#20986;&#29616;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-112/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2yy2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2yy2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 424w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 848w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 1272w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2yy2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png" width="120" height="120" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95721886-2364-4edb-a630-331241c98a16_120x120.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:120,&quot;width&quot;:120,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11272,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/180290042?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2yy2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 424w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 848w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 1272w, https://substackcdn.com/image/fetch/$s_!2yy2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95721886-2364-4edb-a630-331241c98a16_120x120.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3><strong><a href="https://l.fatbobman.com/sb-boltai">Mac &#21407;&#29983; AI &#23458;&#25143;&#31471;&#65306;&#32858;&#21512; GPT&#12289;Claude&#12289;Gemini &#21450;&#26412;&#22320;&#26368;&#26032;&#27169;&#22411;</a></strong></h3><p>&#21463;&#22815;&#20102;&#27983;&#35272;&#22120;&#21507;&#20809;&#20869;&#23384;&#65311;&#35797;&#35797; <strong>BoltAI</strong>&#12290;</p><p>&#23427;&#23558; GPT&#12289;Claude&#12289;Gemini &#20197;&#21450; Ollama &#26412;&#22320;&#27169;&#22411;&#26080;&#32541;&#38598;&#25104;&#21040;&#20320;&#30340;&#24320;&#21457;&#24037;&#20316;&#27969;&#20013;&#12290;&#26080;&#35770;&#27169;&#22411;&#22914;&#20309;&#36845;&#20195;&#65292;&#20320;&#37117;&#33021;&#31532;&#19968;&#26102;&#38388;&#22312;&#21407;&#29983;&#30028;&#38754;&#20013;&#35843;&#29992;&#26368;&#24378;&#33021;&#21147;&#12290;</p><p>&#25903;&#25345;<strong>&#23631;&#24149;&#19978;&#19979;&#25991;&#24863;&#30693;</strong>&#12289;<strong>&#20195;&#30721;&#35299;&#37322;&#19982;&#37325;&#26500;</strong>&#65292;&#26159;&#30495;&#27491;&#23646;&#20110;&#24320;&#21457;&#32773;&#30340; Mac &#21407;&#29983; AI &#31070;&#22120;&#12290;</p><blockquote><p><em>&#127881; <strong>&#21608;&#25253;&#35835;&#32773;&#38480;&#26102;&#31119;&#21033;</strong>&#65306;<br>&#20973;&#20195;&#30721; <strong>BFCM25</strong> &#21487;&#20139; <strong>51% OFF</strong></em></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://l.fatbobman.com/sb-boltai-zh&quot;,&quot;text&quot;:&quot;&#128640; &#31435;&#21363;&#35797;&#29992; BoltAI!&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://l.fatbobman.com/sb-boltai-zh"><span>&#128640; &#31435;&#21363;&#35797;&#29992; BoltAI!</span></a></p><div><hr></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/from-ios-to-android/?utm_source=fatbobman%20weekly%20issue%20113&amp;utm_medium=web">&#24403;&#25105;&#20915;&#23450;&#21516;&#26102;&#20570; iOS &#21644; Android&#65306;&#29420;&#31435;&#24320;&#21457;&#32773;&#30340;&#30495;&#23454;&#21452;&#24179;&#21488;&#20043;&#36335;</a></strong></h3><p>&#22312;&#19981;&#23569;&#33529;&#26524;&#29983;&#24577;&#24320;&#21457;&#32773;&#30524;&#20013;&#65292;Android &#26082;&#29087;&#24713;&#21448;&#36965;&#36828;&#65306;&#29992;&#25143;&#35268;&#27169;&#24040;&#22823;&#65292;&#20294;&#29983;&#24577;&#30862;&#29255;&#21270;&#65307;&#28508;&#22312;&#22238;&#25253;&#21487;&#35266;&#65292;&#20294;&#25237;&#20837;&#25104;&#26412;&#19981;&#30830;&#23450;&#12290;&#35768;&#22810;&#20154;&#22240;&#27492;&#23545;&#8220;&#35201;&#19981;&#35201;&#20570; Android &#29256;&#26412;&#8221;&#22987;&#32456;&#29369;&#35947;&#19981;&#20915;&#12290;&#36164;&#28145; iOS &#24320;&#21457;&#32773;<a href="https://x.com/iVulgur">&#36947;&#21733;</a>&#37319;&#29992;&#8220;&#21452;&#24179;&#21488;&#24182;&#36827;&#8221;&#31574;&#30053;&#22810;&#24180;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;&#20182;&#20998;&#20139;&#20102;&#21452;&#24179;&#21488;&#24320;&#21457;&#30340;&#23454;&#25112;&#32463;&#39564;&#65306;&#21452;&#31471;&#21151;&#33021;&#22914;&#20309;&#23545;&#40784;&#12289;&#36935;&#21040;&#31995;&#32479;&#24046;&#24322;&#26102;&#30340;&#26435;&#34913;&#12289;&#20004;&#36793;&#30340;&#36816;&#33829;&#34920;&#29616;&#24046;&#24322;&#12289;&#25910;&#20837;&#32467;&#26500;&#30340;&#21464;&#21270;&#31561;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-01">Skip &#26694;&#26550;&#30340;&#36328;&#24179;&#21488;&#23454;&#36341; (Skip Framework: A Cross-Platform Journey for Native iOS Developer)</a></strong></h3><p><a href="https://www.linkedin.com/in/maxim-ermolaev-128156356/">Maxim Ermolaev</a> &#20998;&#20139;&#20102;&#20182;&#23558; SwiftUI &#24212;&#29992;&#36801;&#31227;&#21040; Android &#30340;&#23454;&#36341;&#32463;&#39564;&#65292;&#21576;&#29616;&#20102; Skip &#22312;&#30495;&#23454;&#39033;&#30446;&#20013;&#30340;&#34920;&#29616;&#19982;&#36793;&#30028;&#12290;&#23545; Skip &#24050;&#25903;&#25345;&#30340; SwiftUI &#21151;&#33021;&#65292;&#36801;&#31227;&#36807;&#31243;&#30456;&#23545;&#39034;&#30021;&#65307;&#32780;&#23545;&#20110;&#23578;&#26410;&#35206;&#30422;&#30340;&#39640;&#32423;&#29305;&#24615;&#65292;&#20316;&#32773;&#21017;&#36890;&#36807; ComposeView &#22312;&#21516;&#19968; Swift &#25991;&#20214;&#20013;&#30452;&#25509;&#23884;&#20837; Jetpack Compose &#20195;&#30721;&#65292;&#20026; Android &#20391;&#25552;&#20379;&#23450;&#21046;&#23454;&#29616;&#12290;Maxim &#30340;&#32467;&#35770;&#30456;&#24403;&#21153;&#23454;&#65306;Skip &#36275;&#20197;&#35753; iOS-first &#22242;&#38431;&#24555;&#36895;&#33719;&#24471;&#19968;&#20010;&#8220;&#21487;&#29992;&#19988;&#19968;&#33268;&#8221;&#30340; Android &#23458;&#25143;&#31471;&#12290;&#20294;&#22914;&#26524;&#30446;&#26631;&#26159;&#20004;&#31471;&#36798;&#21040;&#23436;&#20840;&#19968;&#33268;&#30340;&#35270;&#35273;&#19982;&#20132;&#20114;&#20307;&#39564;&#65292;&#21017;&#20173;&#38656;&#22312; Android &#20391;&#20570;&#26356;&#22810;&#24179;&#21488;&#29305;&#21270;&#65292;&#25110;&#37319;&#29992; Skip Lite &#20849;&#20139;&#19994;&#21153;&#36923;&#36753;&#12289;&#23558; UI &#20445;&#25345;&#20026;&#21407;&#29983;&#23454;&#29616;&#12290;</p><blockquote><p>&#38543;&#30528; Swift Android SDK &#30340;&#25104;&#29087;&#19982; Skip &#31561;&#24037;&#20855;&#30340;&#19981;&#26029;&#23436;&#21892;&#65292;Swift &#22312; Android &#19990;&#30028;&#30340;&#21487;&#33021;&#24615;&#27491;&#36805;&#36895;&#20174;&#8220;&#23454;&#39564;&#24615;&#8221;&#36808;&#21521;&#8220;&#21487;&#33853;&#22320;&#8221;&#12290;&#20004;&#20301;&#20316;&#32773;&#20174;&#19981;&#21516;&#35282;&#24230;&#21576;&#29616;&#20102;&#24403;&#21069;&#30340;&#30495;&#23454;&#36335;&#24452;&#65292;&#20063;&#20026;&#27491;&#22312;&#32771;&#34385;&#8220;&#36328;&#21040;&#21478;&#19968;&#36793;&#8221;&#30340; Swift &#24320;&#21457;&#32773;&#25552;&#20379;&#20102;&#38590;&#24471;&#30340;&#21442;&#32771;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-02">&#25171;&#36896;&#27599;&#22825;&#36305; 2000+ &#26465;&#27969;&#27700;&#32447;&#30340; Mac &#26426;&#22120;&#20892;&#22330; (Building Mac Farm: Running 2000+ iOS Pipelines Daily)</a></strong></h3><p>&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/ysf_ozgul">Yusuf &#214;zg&#252;l</a> &#35814;&#36848;&#20102; Trendyol &#22242;&#38431;&#22914;&#20309;&#20174;&#38646;&#25645;&#24314;&#19968;&#22871;&#30001; 130 &#21488;&#35774;&#22791;&#32452;&#25104;&#30340; macOS Farm&#65292;&#20197;&#20174;&#23481;&#25903;&#25745;&#27599;&#22825; 2000+ &#26465; iOS &#27969;&#27700;&#32447;&#30340;&#23454;&#25112;&#32463;&#39564;&#12290;&#25972;&#22871;&#31995;&#32479;&#37319;&#29992;&#22522;&#20110; Apple Virtualization Framework &#33258;&#30740;&#30340; VM &#31649;&#29702;&#20307;&#31995;&#12289;&#36890;&#36807; Authorization Plug-ins &#35299;&#20915;&#25209;&#37327;&#35774;&#22791;&#30340;&#23433;&#20840;&#33258;&#21160;&#30331;&#24405;&#12289;&#23450;&#20301;&#24182;&#20462;&#22797; VM &#22312; P/E Core &#35782;&#21035;&#19978;&#30340;&#24615;&#33021;&#29942;&#39048;&#65292;&#24182;&#26500;&#24314; Grafana &#30417;&#25511;&#19982;&#21578;&#35686;&#31995;&#32479;&#65292;&#23454;&#29616;&#33258;&#24840;&#24335; Runner &#38598;&#32676;&#12290;&#22312;&#27969;&#27700;&#32447;&#19978;&#65292;&#36890;&#36807;&#37197;&#21512; Tuist Cache&#65288;&#26500;&#24314;&#25552;&#36895;&#32422; 70%&#65289;&#19982;&#36873;&#25321;&#24615;&#27979;&#35797;&#65288;&#27979;&#35797;&#25552;&#36895;&#32422; 80%&#65289;&#36827;&#19968;&#27493;&#25552;&#39640;&#20102;&#24615;&#33021;&#12290;</p><blockquote><p>&#23569;&#35265;&#30340; macOS Farm &#33853;&#22320;&#20840;&#26223;&#26696;&#20363;&#65306;&#20174;&#34394;&#25311;&#21270;&#26550;&#26500;&#21040;&#24615;&#33021;&#35843;&#20248;&#65292;&#20174;&#26085;&#24535;&#19982;&#30417;&#25511;&#21040;&#27969;&#27700;&#32447;&#35774;&#35745;&#65292;&#20960;&#20046;&#35206;&#30422;&#20102;&#20225;&#19994;&#32423; iOS CI/CD &#25152;&#38656;&#30340;&#20840;&#37096;&#20851;&#38190;&#29615;&#33410;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-03">&#22312; Zed &#20013;&#23454;&#29616; SwiftUI &#39044;&#35272;&#30340;&#23567;&#25216;&#24039; (Building iOS and Mac apps in Zed: SwiftUI Previews)</a></strong></h3><p>&#23613;&#31649;&#30446;&#21069;&#24320;&#21457;&#32773;&#24050;&#32463;&#21487;&#20197;&#22312; Zed &#20013;&#24320;&#21457;&#35843;&#35797; iOS &#24212;&#29992;&#20102;&#65292;&#20294;&#20173;&#26080;&#27861;&#23454;&#29616; Xcode &#20013;&#30340;&#26432;&#25163;&#32423;&#21151;&#33021;&#65306;Preview&#12290;&#36890;&#24120;&#30340;&#26367;&#20195;&#26041;&#26696;&#26159;&#22312; Zed &#26049;&#36793;&#20877;&#24320;&#19968;&#20010; Xcode &#39044;&#35272;&#31383;&#21475;&#65292;&#20294;&#20999;&#25442;&#32534;&#36753;&#30340; SwiftUI &#39029;&#38754;&#21518;&#65292;Xcode &#24182;&#19981;&#20250;&#33258;&#21160;&#36339;&#36716;&#21040;&#23545;&#24212;&#30340; Preview&#12290;<a href="https://mastodon.social/@lxmn">Adrian Ross</a> &#20998;&#20139;&#20102;&#19968;&#20010;&#23567;&#25216;&#24039;&#65306;&#36890;&#36807;&#19968;&#20010;&#33050;&#26412;&#37197;&#21512; Zed Task&#65292;&#23454;&#29616; Xcode &#19982; Zed &#30340;&#32534;&#36753;&#39029;&#38754;&#21516;&#27493;&#65292;&#20174;&#32780;&#22312;&#22806;&#37096;&#39044;&#35272;&#31383;&#21475;&#20013;&#33258;&#21160;&#21516;&#27493;&#23637;&#31034;&#23545;&#24212;&#30340; Preview&#65292;&#22522;&#26412;&#22797;&#21051;&#20102;&#8220;&#22312; Zed &#20013;&#20351;&#29992; Preview&#8221;&#30340;&#20307;&#39564;&#12290;</p><blockquote><p>&#36825;&#19968;&#24605;&#36335;&#19981;&#20165;&#36866;&#29992;&#20110; Zed&#65292;&#20219;&#20309;&#22312; macOS &#19978;&#30340;&#32534;&#36753;&#22120;&#37117;&#21487;&#20197;&#29992;&#31867;&#20284;&#26041;&#24335;&#19982; Xcode &#30340; Preview &#21151;&#33021;&#21327;&#21516;&#24037;&#20316;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-04">&#22312; macOS &#30340; SwiftUI &#21015;&#34920;&#20013;&#21551;&#29992;&#36873;&#25321;&#12289;&#21452;&#20987;&#21644;&#21491;&#38190;&#33756;&#21333; (Enabling Selection, Double-Click and Context Menus in SwiftUI List Rows on macOS)</a></strong></h3><p>macOS &#30340; SwiftUI List &#22312;&#34892;&#36873;&#25321;&#12289;&#21452;&#20987;&#21644;&#21491;&#38190;&#33756;&#21333;&#31561;&#26700;&#38754;&#31471;&#29305;&#26377;&#20132;&#20114;&#19978;&#65292;&#19982; iOS &#23384;&#22312;&#26174;&#33879;&#24046;&#24322;&#12290;&#24320;&#21457;&#32773;&#38656;&#35201;&#20351;&#29992;&#24102; <code>selection</code> &#21442;&#25968;&#30340; List &#21021;&#22987;&#21270;&#22120;&#26469;&#21551;&#29992;&#36873;&#25321;&#21151;&#33021;&#65292;&#24182;&#36890;&#36807; <code>contextMenu(forSelectionType:menu:primaryAction:)</code> &#20462;&#39280;&#22120;&#21516;&#26102;&#23454;&#29616;&#21452;&#20987;&#25805;&#20316;&#21644;&#21491;&#38190;&#33756;&#21333;&#12290;&#30456;&#27604; iOS&#65292;macOS &#29256;&#30340; List &#26356;&#25509;&#36817; AppKit &#30340;&#34920;&#26684;&#24335;&#20132;&#20114;&#27169;&#22411;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/gabtheodor">Gabriel Theodoropoulos</a> &#20197;&#19968;&#22871;&#31616;&#27905;&#30340;&#31034;&#20363;&#23637;&#31034;&#20102;&#22914;&#20309;&#22312; macOS &#30340; SwiftUI &#21015;&#34920;&#20013;&#27491;&#30830;&#32452;&#21512;&#36825;&#20123; API &#20197;&#23454;&#29616;&#26700;&#38754;&#31471;&#26631;&#20934;&#20132;&#20114;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-05">&#24320;&#21457;&#38454;&#27573;&#20351;&#29992; Associated Domains &#30340;&#26367;&#20195;&#27169;&#24335; (Using Associated Domains Alternate Mode during Development)</a></strong></h3><p>&#22312;&#24320;&#21457;&#28041;&#21450; Associated Domains &#30340;&#21151;&#33021;&#65288;&#22914; Universal Links&#12289;Shared Web Credentials &#25110; App Clips&#65289;&#26102;&#65292;iOS &#40664;&#35748;&#36890;&#36807; Apple CDN &#33719;&#21462; <code>apple-app-site-association</code> (AASA) &#25991;&#20214;&#65292;&#32780;&#38750;&#30452;&#25509;&#20174;&#26381;&#21153;&#22120;&#33719;&#21462;&#12290;&#36825;&#22312;&#29983;&#20135;&#29615;&#22659;&#20013;&#36816;&#34892;&#33391;&#22909;&#65292;&#20294;&#22312;&#24320;&#21457;&#38454;&#27573;&#20250;&#24102;&#26469;&#19981;&#20415;&#65306;&#25991;&#20214;&#26356;&#25913;&#38656;&#35201;&#31561;&#24453; CDN &#20256;&#25773;&#65292;&#26412;&#22320;&#25110;&#27979;&#35797;&#26381;&#21153;&#22120;&#21487;&#33021;&#26681;&#26412;&#26080;&#27861;&#20844;&#24320;&#35775;&#38382;&#12290;<a href="https://x.com/tanaschita">Natascha Fadeeva</a> &#20171;&#32461;&#20102;&#33529;&#26524;&#25552;&#20379;&#30340; Alternate Mode&#65288;&#26367;&#20195;&#27169;&#24335;&#65289;&#65306;&#36890;&#36807;&#22312; Associated Domains &#26465;&#30446;&#20013;&#28155;&#21152; <code>?mode=developer</code> &#31561;&#21518;&#32512;&#65292;&#35753; iOS &#32469;&#36807; CDN&#65292;&#30452;&#25509;&#20174;&#26381;&#21153;&#22120;&#25289;&#21462;&#23545;&#24212;&#30340; AASA &#25991;&#20214;&#12290;&#20511;&#21161;&#27492;&#26426;&#21046;&#65292;&#24320;&#21457;&#32773;&#21487;&#20197;&#35753;&#37197;&#32622;&#21363;&#26102;&#29983;&#25928;&#12289;&#22312;&#26412;&#22320;&#29615;&#22659;&#35843;&#35797;&#65292;&#32780;&#19981;&#24517;&#31561;&#24453; CDN &#32531;&#23384;&#21047;&#26032;&#65292;&#22823;&#24133;&#25552;&#21319;&#24320;&#21457;&#25928;&#29575;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-06">&#29992;&#21487;&#35270;&#21270;&#26041;&#24335;&#29702;&#35299; Swift &#20013;&#30340;&#25968;&#25454;&#31454;&#20105; (Understanding Data Races: A Visual Guide for Swift Developers)</a></strong></h3><p>&#25968;&#25454;&#31454;&#20105;&#26159;&#24182;&#21457;&#32534;&#31243;&#20013;&#38590;&#20197;&#29702;&#35299;&#30340;&#26680;&#24515;&#27010;&#24565;&#12290;<strong>Krishna</strong> &#36890;&#36807;&#19968;&#31995;&#21015;&#22270;&#29255;&#65306;&#20960;&#20010; ToddlerBot&#65288;&#24188;&#20799;&#26426;&#22120;&#20154;&#65289;&#19968;&#36215;&#32473;&#21516;&#19968;&#24352;&#28034;&#33394;&#39029;&#19978;&#33394;&#65292;&#20197;&#30452;&#35266;&#26041;&#24335;&#23637;&#31034;&#20102;&#20849;&#20139;&#21487;&#21464;&#29366;&#24577;&#22312;&#24182;&#21457;&#29615;&#22659;&#20013;&#22914;&#20309;&#24341;&#21457;&#28151;&#20081;&#65306;&#20174;&#36731;&#24494;&#30340;&#32467;&#26524;&#38169;&#20081;&#65292;&#21040;&#35835;&#20889;&#20132;&#38169;&#23548;&#33268;&#30340;&#36923;&#36753;&#22833;&#25928;&#29978;&#33267;&#23849;&#28291;&#12290;</p><blockquote><p>&#26412;&#25991;&#26368;&#22823;&#30340;&#29305;&#33394;&#22312;&#20110;&#8220;&#22270;&#25991;&#24182;&#33538;&#8221;&#12290;ToddlerBot &#30340;&#35270;&#35273;&#21270;&#21465;&#20107;&#25104;&#21151;&#25226;&#20256;&#32479;&#19978;&#26543;&#29157;&#20005;&#32899;&#30340;&#25216;&#26415;&#20027;&#39064;&#21464;&#24471;&#29983;&#21160;&#26131;&#25026;&#12290;Krishna &#34920;&#31034;&#21518;&#32493;&#25991;&#31456;&#23558;&#32487;&#32493;&#27839;&#29992; ToddlerBot &#36825;&#19968;&#35282;&#33394;&#65292;&#26500;&#24314;&#19968;&#22871;&#36830;&#36143;&#30340; Swift &#24182;&#21457;&#24515;&#26234;&#27169;&#22411;&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-09">&#25945; AI &#35835;&#25026; Xcode &#26500;&#24314; (Teaching AI to Read Xcode Builds)</a></strong></h3><p>&#22914;&#26524;&#35828;&#24403;&#19979; AI &#22312;&#8220;&#20889;&#20195;&#30721;&#8221;&#36825;&#20214;&#20107;&#19978;&#26410;&#24517;&#20248;&#20110;&#32463;&#39564;&#20016;&#23500;&#30340;&#24320;&#21457;&#32773;&#65292;&#37027;&#20040;&#22312;&#8220;&#30475;&#25968;&#25454;&#12289;&#25286;&#38382;&#39064;&#8221;&#19978;&#65292;&#23427;&#20960;&#20046;&#19968;&#23450;&#24378;&#36807;&#22823;&#22810;&#25968;&#20154;&#31867;&#65292;&#32780;&#19988;&#36755;&#20837;&#30340;&#20449;&#24687;&#36234;&#22810;&#12289;&#36234;&#32467;&#26500;&#21270;&#65292;&#20248;&#21183;&#36234;&#26126;&#26174;&#12290;&#33529;&#26524;&#24320;&#28304; swift-build &#20043;&#21518;&#65292;Tuist &#22242;&#38431;&#24471;&#20197;&#30452;&#25509;&#20174;&#26500;&#24314;&#26381;&#21153;&#20013;&#33719;&#21462;&#35814;&#23613;&#30340;&#26500;&#24314;&#20107;&#20214;&#25968;&#25454;&#65292;&#24182;&#23558;&#20854;&#20197;&#32467;&#26500;&#21270;&#30340;&#26041;&#24335;&#20889;&#20837; SQLite&#65292;&#35753; AI &#20195;&#29702;&#33021;&#22815;&#30495;&#27491;&#8220;&#29702;&#35299;&#8221;&#19968;&#27425;&#26500;&#24314;&#65292;&#32780;&#19981;&#21482;&#26159;&#34987;&#21160;&#35299;&#26512; <code>xcodebuild</code> &#30340;&#25991;&#26412;&#36755;&#20986;&#12290;&#22312;&#26412;&#25991;&#20013;&#65292;<a href="https://x.com/pepicrft">Pedro Pi&#241;era</a> &#35814;&#32454;&#20171;&#32461;&#20102;&#36825;&#19968;&#23581;&#35797;&#30340;&#23454;&#29616;&#36335;&#24452;&#65292;&#24182;&#36890;&#36807;&#22312; Wikipedia iOS&#12289;Tuist &#31561;&#30495;&#23454;&#39033;&#30446;&#19978;&#30340;&#23454;&#27979;&#65292;&#23637;&#31034;&#20102; AI &#22914;&#20309;&#22522;&#20110;&#36825;&#20123;&#32467;&#26500;&#21270;&#25968;&#25454;&#20570;&#20986;&#36828;&#36229;&#8220;&#35835;&#26085;&#24535;&#8221;&#30340;&#35786;&#26029;&#21644;&#20248;&#21270;&#24314;&#35758;&#65292;&#20026;&#26410;&#26469;&#30340;&#23454;&#26102;&#26500;&#24314;&#21487;&#35266;&#27979;&#24615;&#20197;&#21450;&#30495;&#27491;&#8220;&#25026;&#26500;&#24314;&#8221;&#30340; AI &#21161;&#25163;&#25551;&#32472;&#20986;&#19968;&#26465;&#30456;&#24403;&#28165;&#26224;&#30340;&#25216;&#26415;&#36335;&#32447;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0113-07">SwiftUI-Popover: &#25903;&#25345; watchOS &#30340;&#27668;&#27873;&#25552;&#31034;&#24211;</a></strong></h3><p>&#23613;&#31649; SwiftUI &#25552;&#20379;&#20102; <code>.popover</code> &#20462;&#39280;&#22120;&#65292;&#20294;&#23427;&#22312;&#19981;&#21516;&#24179;&#21488;&#19978;&#30340;&#34920;&#29616;&#24182;&#19981;&#19968;&#33268;&#65306;iPhone &#19978;&#20250;&#38477;&#32423;&#20026; sheet&#65292;watchOS &#21017;&#23436;&#20840;&#19981;&#25903;&#25345;&#12290;<a href="https://github.com/qusc">Quirin Schweigert</a> &#24320;&#21457;&#30340; SwiftUI-Popover &#26159;&#19968;&#20010;&#36731;&#37327;&#32423;&#12289;&#32431; SwiftUI &#23454;&#29616;&#30340; Popover &#24211;&#65292;&#25552;&#20379;&#36328;&#24179;&#21488;&#19968;&#33268;&#30340;&#27668;&#27873;&#25552;&#31034;&#21151;&#33021;&#65292;&#25903;&#25345;&#21253;&#25324; watchOS &#22312;&#20869;&#30340;&#25152;&#26377; SwiftUI &#24179;&#21488;&#12290;&#35813;&#24211;&#30340;&#29305;&#33394;&#22312;&#20110;&#31661;&#22836;&#20250;&#33258;&#21160;&#36319;&#38543;&#38468;&#30528;&#28857;&#20301;&#32622;&#65292;&#19988;&#21487;&#20197;&#28789;&#27963;&#23884;&#20837;&#21040;&#20219;&#20309;&#35270;&#22270;&#23618;&#32423;&#20013;&#12290;</p><pre><code>// 1. &#38468;&#21152; popover
  Image(systemName: &#8220;globe&#8221;)
      .swiftUIPopover(
          isPresented: $showPopover,
          isDismissible: true,        // &#21487;&#28857;&#20987;&#32972;&#26223;&#20851;&#38381;
          isExclusive: true,           // &#29420;&#21344;&#26174;&#31034;
          preferredAttachmentEdge: .top // &#20248;&#20808;&#38468;&#30528;&#22312;&#39030;&#37096;
      ) {
          Text(&#8221;&#27668;&#27873;&#20869;&#23481;&#8221;)
      }
&#8203;
  // 2. &#22312;&#23481;&#22120;&#35270;&#22270;&#19978;&#21551;&#29992; popover &#28210;&#26579;
  .presentPopovers()</code></pre><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0113-08">SwiftIR: Swift &#30340;&#29616;&#20195; ML &#32534;&#35793;&#22522;&#30784;&#35774;&#26045;</a></strong></h3><p>&#30446;&#21069; Swift &#20013;&#21487;&#29992;&#30340; ML &#36335;&#24452;&#20027;&#35201;&#21253;&#25324; Foundation &#30340; <code>_Differentiation</code>&#12289;&#25163;&#20889; Accelerate/Metal&#65292;&#20197;&#21450;&#24050;&#32463;&#20572;&#26356;&#30340; Swift for TensorFlow&#12290;&#20294;&#23427;&#20204;&#20998;&#21035;&#38754;&#20020;&#24615;&#33021;&#29942;&#39048;&#12289;&#24320;&#21457;&#25104;&#26412;&#39640;&#25110;&#32570;&#20047;&#32500;&#25252;&#31561;&#38382;&#39064;&#12290;&#30001; <a href="https://www.linkedin.com/in/pedronrodriguez/">Pedro N. Rodriguez</a> &#24320;&#21457;&#30340; SwiftIR&#65292;&#27491;&#26159;&#22312;&#36825;&#31181;&#32972;&#26223;&#19979;&#20986;&#29616;&#30340;&#35299;&#20915;&#26041;&#26696;&#12290;</p><p>SwiftIR &#36890;&#36807; <code>DifferentiableTracer</code> &#25318;&#25130; Swift &#21407;&#29983;&#33258;&#21160;&#24494;&#20998;&#65288;<code>@differentiable</code>&#65289;&#30340;&#36816;&#31639;&#36807;&#31243;&#65292;&#33258;&#21160;&#26500;&#24314;&#23436;&#25972;&#35745;&#31639;&#22270;&#65292;&#24182;&#32534;&#35793;&#21040;&#19982; JAX/TensorFlow &#30456;&#21516;&#30340;&#36816;&#34892;&#26102;&#65288;XLA/PJRT&#65289;&#65292;&#26368;&#32456;&#22312; CPU/GPU/TPU &#19978;&#25191;&#34892;&#12290;&#39033;&#30446;&#26368;&#22823;&#30340;&#31361;&#30772;&#22312;&#20110;&#65306;While &#24490;&#29615;&#32534;&#35793;&#26102;&#38388;&#20445;&#25345;&#24120;&#25968;&#65288;~43ms&#65292;&#20256;&#32479;&#23637;&#24320;&#38656;&#35201;&#25968;&#21313;&#20998;&#38047;&#65289;&#65292;&#26799;&#24230;&#24320;&#38144;&#20165; ~1.0x&#65288;&#26631;&#20934; Swift &#20026; 2.5-4.3x&#65289;&#65292;&#22312;&#22823;&#35268;&#27169;&#35745;&#31639;&#26102;&#24615;&#33021;&#26174;&#33879;&#20248;&#20110;&#26631;&#20934; Swift&#12290;&#20026; Swift &#24102;&#26469;&#20102;&#30495;&#27491;&#29616;&#20195;&#21270;&#30340; ML &#32534;&#35793;&#22522;&#30784;&#35774;&#26045;&#12290;</p>]]></content:encoded></item><item><title><![CDATA[Fatbobman's Swift Weekly #112]]></title><description><![CDATA[When AI Makes "Seeing Is Believing" Impossible]]></description><link>https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-112</link><guid isPermaLink="false">https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-112</guid><dc:creator><![CDATA[Fatbobman(东坡肘子)]]></dc:creator><pubDate>Mon, 24 Nov 2025 12:01:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hJIz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hJIz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hJIz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 424w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 848w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 1272w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hJIz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp" width="1456" height="904" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:904,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29002,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://weekly.fatbobman.com/i/179625750?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hJIz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 424w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 848w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 1272w, https://substackcdn.com/image/fetch/$s_!hJIz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb137b28c-d19d-4914-8e61-f1fcb587a359_1460x906.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>When AI Makes &#8220;Seeing Is Believing&#8221; Impossible</strong></h2><p><a href="https://fatbobman.com/en/weekly/issue-112/">Read on web &#8594;</a></p><p>Nearly thirty years have passed since I graduated from college. Most of my classmates are now fully absorbed in their careers and families, so our alumni chat stays quiet for long stretches of time. But last Thursday night, an unexpected burst of activity suddenly broke the silence.</p><p>A classmate who hadn&#8217;t appeared in over a decade rejoined the conversation, saying his family was going through a difficult situation and asking if anyone could help. Almost immediately, doubts were raised&#8212;<em>was it really him?</em> Many of my former classmates work in legal professions, and their instincts tend to be finely tuned to anything that feels off.</p><p>We went through the usual steps: voice calls, video chats, back-and-forth questions. Still, some remained unconvinced. &#8220;AI makes impersonation way too easy now. Video and voice aren&#8217;t enough anymore.&#8221;<br>It wasn&#8217;t until more personal details surfaced&#8212;shared memories, old nicknames, inside jokes known only to our class&#8212;that everyone finally felt reassured. Once his identity was confirmed, help arrived quickly, and the immediate crisis was resolved.</p><p>Strictly speaking, it&#8217;s hard to blame anyone for being suspicious. When a single smartphone can &#8220;swap faces&#8221; or &#8220;alter voices,&#8221; <em>seeing is believing</em> no longer holds up. Social media is flooded with AI-generated oddities, and our tolerance for the absurd has quietly risen. Whose pet <em>doesn&#8217;t</em> talk or cook online these days? And if a UFO actually landed one afternoon, people might not be surprised at all&#8212;our threshold for the unknown has been reshaped.</p><p>This shift has brought a new kind of anxiety:</p><p>We once worried about not getting information fast enough or broadly enough; now we worry about whether the information is even real. &#8220;Trusted sources&#8221; have become a scarce commodity.</p><p>And no, AI shouldn&#8217;t shoulder the blame alone. It remains a tool. The ones exploiting it for deception are still people&#8212;the tactics have simply evolved, and the cost of lying has dropped dramatically.</p><p>Against this backdrop, rebuilding truth and trust becomes increasingly difficult.<br>Perhaps we&#8217;ll need to &#8220;fight fire with fire&#8221;: digital signatures, trusted timestamps, blockchain-based verification. None of these are perfect solutions, but they may be meaningful paths forward.</p><p>My mother used to tell me when I was young: <em>&#8220;Doing good is like climbing uphill; doing harm is like falling off a cliff.&#8221;</em></p><p>The same is true of trust&#8212;infinitely harder to rebuild than to destroy, which is precisely what makes it precious.</p><p><a href="https://fatbobman.com/en/weekly/issue-111/">Previous Issue</a>&#65372;<a href="https://fatbobman.com/en/weekly/">Newsletter Archive</a></p><div><hr></div><h2><strong>This Week&#8217;s Sponsor</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-proxyman">Need to debug HTTPS on your iPhone?</a></strong></h3><p>Try Proxyman! The best-in-class macOS that helps you capture/debug HTTP(s) with a few clicks. Support iOS devices and Simulator.</p><p><strong>&#127881; Black Friday Offer &#8211; 30% OFF this week only! </strong><a href="https://l.fatbobman.com/sb-proxyman"> Get Started Now &#8594;</a></p><div><hr></div><h2><strong>Recent Recommendations</strong></h2><h3><strong><a href="https://fatbobman.com/en/posts/deep-dive-into-imessage/?utm_source=fatbobman%20weekly%20issue%20112&amp;utm_medium=web">Deep Dive into iMessage: Behind the Making of an Agent</a></strong></h3><p>As Apple ecosystem developers, we often face a subtle paradox: the system possesses powerful capabilities, but these aren&#8217;t necessarily exposed to developers through public APIs. iMessage is a prime example&#8212;deeply integrated into iOS and macOS as a core communication tool for users, yet it has never provided automation interfaces for developers. <a href="https://el5.net/@lingjue">LingJueYa</a>, the author of <a href="https://github.com/photon-hq/imessage-kit?utm_source=fatbobman%20weekly%20issue%20112&amp;utm_medium=web">imessage-kit</a>, shares his exploration journey in building this tool. The core challenges almost all stem from the Apple platform itself: parsing timestamps with a 2001 epoch, recovering NSAttributedString content from binary plists, safely accessing resources within macOS&#8217;s sandbox system, and working with AppleScript&#8212;a venerable automation mechanism.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-01">2025: The Year SwiftUI Died</a></strong></h3><p><a href="https://x.com/jacobtechtavern">Jacob Bartlett</a>&#8216;s provocatively titled article presents a discussion-worthy perspective: 2025 might mark a turning point for SwiftUI, rather than its peak. His core argument centers on Apple introducing the <code>@Observable</code> macro and <code>updateProperties()</code> method to UIKit, giving it modern state management capabilities, while the maturation of AI-assisted programming tools has dramatically reduced the cost of writing UIKit code (whereas AI&#8217;s understanding of SwiftUI&#8217;s declarative paradigm remains insufficient).</p><blockquote><p>Apple&#8217;s long-term commitment to SwiftUI isn&#8217;t going anywhere &#8212; especially given its natural advantages in multi-platform adaptation. Meanwhile, the rise of AI has made it easier for many developers who started with SwiftUI to lean on UIKit when they need to fill performance or capability gaps. In practice, the choice for most adults isn&#8217;t either-or, but using both together in the most effective way.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-02">Automatic Property Observation in UIKit with @Observable</a></strong></h3><p>UIKit officially introduced native support for Swift Observation in iOS 26. When you read properties of an <code>@Observable</code> object in <code>updateProperties()</code>, UIKit automatically tracks these dependencies and refreshes the corresponding views on-demand when data changes. <a href="https://x.com/natpanferova">Natalia Panferova</a> demonstrates the convenience of this feature for cross-framework data sharing through a practical case mixing UIKit and SwiftUI. The article also introduces the iOS 18 backward compatibility solution: add the <code>UIObservationTrackingEnabled</code> key to <code>Info.plist</code> and place the update logic in <code>viewWillLayoutSubviews()</code> to achieve the same effect.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-03">How SwiftData Represents AttributedString in Core Data Storage</a></strong></h3><p>Although AttributedString itself conforms to Codable, developers previously couldn&#8217;t use it directly as a property in SwiftData models. This restriction was finally lifted in iOS 26&#8212;Apple clearly opened a &#8220;special channel&#8221; for it, and now it can be stored directly like basic types such as Int and String. <a href="https://www.linkedin.com/in/oleksii-oliinyk-83482995/">Oleksii Oliinyk</a>, author of <a href="https://apps.apple.com/us/app/id6737813684">DataScout for SwiftData</a> (a SwiftData database analysis app), encountered related crashes while maintaining the tool and took the opportunity to deeply analyze the implementation mechanism behind it.</p><blockquote><p>SwiftData&#8217;s ability to allow developers to use Codable-conforming types as model properties is itself a powerful feature. However, its underlying handling may differ from what many people expect. In &#8220;<a href="https://fatbobman.com/en/posts/considerations-for-using-codable-and-enums-in-swiftdata-models/">Considerations for Using Codable and Enums in SwiftData Models</a>,&#8221; I provide a more systematic introduction to SwiftData&#8217;s Codable conversion logic and potential pitfalls. Additionally, if you need to save AttributedString before iOS 26, you can refer to this <a href="https://developer.apple.com/forums/thread/762438">thread</a> on Apple&#8217;s developer forums.</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-04">Introducing AnyLanguageModel: One API for Local and Remote LLMs on Apple Platforms</a></strong></h3><p>AnyLanguageModel is a unified Swift LLM interface library developed by <a href="https://x.com/mattt">Mattt</a>. We introduced its core concept in <a href="https://fatbobman.com/en/weekly/issue-109/#anylanguagemodel---unified-swift-llm-development-paradigm">Issue 109</a>. Building on Foundation Models&#8217; API design, the library maintains a familiar developer experience while uniformly supporting multiple model providers, including local models (Core ML, MLX, llama.cpp, Ollama) and cloud models (OpenAI, Anthropic, Google Gemini, etc.), significantly reducing the integration burden across different APIs and execution methods, and making it easier to explore open-source models.</p><p>In this article, Mattt further introduces AnyLanguageModel&#8217;s design philosophy, cross-backend capability abstraction, and how Swift 6.1 package traits help control dependency size. Notably, while Apple currently doesn&#8217;t provide image input capability in Foundation Models, AnyLanguageModel has already added this functionality for models like Claude, enabling vision-language scenarios to work smoothly on Apple platforms.</p><div><hr></div><h3><strong>Approachable Concurrency and MainActor by Default</strong></h3><p>Regardless of how things ultimately unfold, <em>Approachable Concurrency</em> introduced in Swift 6.2 is destined to leave a significant mark in Swift&#8217;s history. It significantly reduces the mental burden of concurrent programming in certain scenarios, but has also left many developers feeling &#8220;more confused the more it&#8217;s explained.&#8221;</p><ul><li><p>In <a href="https://l.fatbobman.com/w0112-05">Approachable Concurrency in Swift 6.2: A Clear Guide</a>, <a href="https://x.com/twannl">Antoine van der Lee</a> provides a systematic overview of the relevant proposals and new behaviors.</p></li><li><p>After conducting extensive research and sharing about these features, <a href="https://mastodon.social/@mattiem">Matt Massicotte</a> emphasizes in his latest article <a href="https://l.fatbobman.com/w0112-06">MainActor by Default</a>: at least for now, he won&#8217;t enable Default actor isolation = MainActor in his projects, because &#8220;understanding why MainActor is needed is far simpler than understanding why or how to remove it.&#8221;</p></li><li><p>However, one thing is crystal clear: MainActor by Default aligns perfectly with embedded platforms. In <a href="https://l.fatbobman.com/w0112-07">Embedded Swift Improvements Coming in Swift 6.3</a>, <a href="https://sfba.social/@dgregor79">Doug Gregor</a> and <a href="https://hachyderm.io/@rauhul">Rauhul Varma</a> further demonstrate the improvement direction and motivation for Swift 6.3 on embedded platforms.</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-08">How to Build Scalable White-Label iOS Apps: From Multi-Target to Modular Architecture</a></strong></h3><p>A White-Label product refers to a flexible, reusable app framework that can be deployed across different clients, with customizable branding and feature configurations (such as a universal restaurant ordering app template). <a href="https://x.com/PawelKozielecki">Pawel Kozielecki</a> systematically outlines the evolution of iOS White-Label applications in this comprehensive article, dividing it into three stages: basic branding customization, custom UI/UX, and full modularization. Building on this foundation, he compares three common implementation strategies&#8212;multi-target, resource replication, and modular architecture&#8212;and points out that as the number of clients and differentiation requirements grow, only modular architecture can truly scale long-term and avoid maintenance chaos. The article also discusses key challenges in scaling white-label projects, including App Store review, code signing, resource and configuration layering, testing, and CI, all with abundant practical details.</p><h2><strong>Tools</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0112-09">QuickLayout: Declarative UIKit Layout Library</a></strong></h3><p>Since UIKit can now seamlessly integrate Observation, it&#8217;s no surprise that writing layout code in SwiftUI style is also possible. QuickLayout, developed by <a href="https://www.linkedin.com/in/constantine-fry/">Constantine Fry</a>, provides exactly this capability and has been used by Meta in Instagram&#8217;s core features. You can lay out views directly like this:</p><pre><code>import QuickLayout
&#8203;
@QuickLayout
class MyCellView: UIView {
&#8203;
  let titleLabel = UILabel()
  let subtitleLabel = UILabel()
&#8203;
  var body: Layout {
    HStack {
      VStack(alignment: .leading) {
        titleLabel
        Spacer(4)
        subtitleLabel
      }
      Spacer()
    }
    .padding(.horizontal, 16)
    .padding(.vertical, 8)
  }
}</code></pre><p>UIKit and SwiftUI were never opposites, but rather two UI thinking models that can learn from each other. Currently, SwiftUI&#8217;s advantages lie in abstraction and consistency, while high performance, fine-grained control, and toolchain support remain UIKit&#8217;s strengths.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-10">SettingsKit</a></strong></h3><p>Nearly all apps need a settings interface. While not difficult to write, maintenance costs rise as options multiply. SettingsKit, developed by <a href="https://x.com/AetherAurelia">Aether</a>, was created to address this. It enables SwiftUI developers to quickly build scalable, consistently styled settings interfaces with built-in search capabilities, featuring multiple styles including grouped, card, and sidebar layouts&#8212;ideal for medium to large settings modules.</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-11">KurrentDB-Swift</a></strong></h3><p>Kurrent (formerly EventStoreDB) is a database specifically designed for event storage. It not only saves the current state of a system but also maintains a complete record of every change in its history, making it ideal for scenarios requiring strong traceability such as finance, logistics, retail, e-commerce, and SaaS. As a Swift client library for KurrentDB, KurrentDB-Swift developed by <a href="https://x.com/gradyzhuo">Grady Zhuo</a> supports Swift 6, async/await streaming subscriptions, and event reading, filling a long-standing gap in the Swift ecosystem for mature Event Sourcing tools.</p><div><hr></div><p>Thanks for reading Fatbobman&#8217;s Swift Weekly! This post is public so feel free to share it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-112?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://weekly.fatbobman.com/p/fatbobmans-swift-weekly-112?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2><strong>&#27605;&#19994; 30 &#24180;&#21516;&#23398;&#32676;&#65306;&#19968;&#22330; AI &#24341;&#21457;&#30340;&#8220;&#30495;&#20551;&#38590;&#36776;&#8221;&#21361;&#26426;</strong></h2><p><strong><a href="https://fatbobman.com/zh/weekly/issue-112/">&#32593;&#39029;&#29256;</a></strong></p><p>&#22823;&#23398;&#27605;&#19994;&#24555;&#19977;&#21313;&#24180;&#20102;&#65292;&#21516;&#23398;&#20204;&#22823;&#22810;&#24537;&#20110;&#20107;&#19994;&#19982;&#29983;&#27963;&#65292;&#32676;&#37324;&#24120;&#24180;&#20919;&#28165;&#12290;&#20294;&#19978;&#21608;&#22235;&#26202;&#19978;&#65292;&#19968;&#38453;&#20037;&#36829;&#30340;&#28909;&#38393;&#31361;&#28982;&#25171;&#30772;&#20102;&#27785;&#23490;&#12290;</p><p>&#19968;&#20301;&#21313;&#20960;&#24180;&#26410;&#38706;&#38754;&#30340;&#21516;&#23398;&#37325;&#26032;&#21152;&#20837;&#32676;&#32842;&#65292;&#35828;&#23478;&#37324;&#36973;&#36935;&#20102;&#21464;&#25925;&#65292;&#21521;&#22823;&#23478;&#27714;&#21161;&#12290;&#24456;&#24555;&#23601;&#26377;&#20154;&#25552;&#20986;&#36136;&#30097;&#8212;&#8212;&#36825;&#30495;&#30340;&#26159;&#26412;&#20154;&#21527;&#65311;&#27605;&#31455;&#32676;&#37324;&#22810;&#25968;&#20154;&#20174;&#20107;&#27861;&#24459;&#30456;&#20851;&#24037;&#20316;&#65292;&#32844;&#19994;&#25935;&#24863;&#24230;&#35753;&#20182;&#20204;&#23545;&#20219;&#20309;&#24322;&#24120;&#26684;&#22806;&#35686;&#35273;&#12290;</p><p>&#35821;&#38899;&#36890;&#35805;&#12289;&#35270;&#39057;&#32842;&#22825;&#65292;&#19968;&#36718;&#36718;&#39564;&#35777;&#19979;&#26469;&#65292;&#20173;&#26377;&#20154;&#19981;&#25918;&#24515;&#65306;&#8220;&#29616;&#22312; AI &#36896;&#20551;&#22826;&#23481;&#26131;&#20102;&#65292;&#20809;&#20973;&#36825;&#20123;&#21487;&#19981;&#22815;&#12290;&#8221;&#30452;&#21040;&#26356;&#22810;&#32454;&#33410;&#34987;&#25670;&#19978;&#26700;&#38754;&#8212;&#8212;&#20849;&#21516;&#32463;&#21382;&#12289;&#20869;&#37096;&#26165;&#31216;&#12289;&#21482;&#26377;&#25105;&#20204;&#30693;&#36947;&#30340;&#26087;&#26775;&#8212;&#8212;&#22823;&#23478;&#25165;&#26368;&#32456;&#30830;&#35748;&#36523;&#20221;&#65292;&#38543;&#21363;&#20280;&#20986;&#25588;&#25163;&#65292;&#24110;&#21161;&#20182;&#24230;&#36807;&#26242;&#26102;&#30340;&#38590;&#20851;&#12290;</p><p>&#20005;&#26684;&#26469;&#35828;&#65292;&#24182;&#19981;&#33021;&#24618;&#22823;&#23478;&#21464;&#24471;&#22810;&#30097;&#12290;&#22312;&#22914;&#20170;&#19968;&#37096;&#25163;&#26426;&#23601;&#33021;&#8220;&#25442;&#22836;&#8221;&#8220;&#21464;&#22768;&#8221;&#30340;&#26102;&#20195;&#65292;&#8220;&#30524;&#35265;&#20026;&#23454;&#8221;&#26089;&#24050;&#19981;&#20877;&#25104;&#31435;&#12290;&#31038;&#20132;&#23186;&#20307;&#19978;&#24067;&#28385;&#20102;&#30001; AI &#29983;&#25104;&#30340;&#21508;&#31181;&#31163;&#22855;&#24773;&#26223;&#65292;&#20154;&#20204;&#23545;&#8220;&#31163;&#35889;&#35270;&#39057;&#8221;&#30340;&#32784;&#21463;&#24230;&#19981;&#26029;&#34987;&#25289;&#39640;&#65306;&#35841;&#23478;&#30340;&#23456;&#29289;&#19981;&#20250;&#35828;&#35805;&#12289;&#20570;&#39277;&#21602;&#65311;&#20063;&#35768;&#21738;&#22825;&#30495;&#30475;&#21040; UFO &#38477;&#33853;&#65292;&#37117;&#19981;&#20250;&#20877;&#20196;&#20154;&#24778;&#35766;&#8212;&#8212;&#25105;&#20204;&#23545;&#26410;&#30693;&#30340;&#24656;&#24807;&#38408;&#20540;&#65292;&#27491;&#22312;&#34987;&#24708;&#24708;&#37325;&#22609;&#12290;</p><p>&#38543;&#20043;&#32780;&#26469;&#30340;&#65292;&#26159;&#19968;&#31181;&#26032;&#30340;&#20449;&#24687;&#28966;&#34385;&#65306;&#36807;&#21435;&#25285;&#24515;&#30340;&#26159;&#33719;&#21462;&#19981;&#21450;&#26102;&#12289;&#19981;&#20840;&#38754;&#65307;&#22914;&#20170;&#25285;&#24515;&#30340;&#26159;&#33719;&#21462;&#30340;&#20869;&#23481;&#26159;&#21542;&#30495;&#23454;&#12290;&#8220;&#21487;&#20449;&#26469;&#28304;&#8221;&#65292;&#27491;&#22312;&#21464;&#25104;&#19968;&#20214;&#31232;&#32570;&#21697;&#12290;</p><p>&#24403;&#28982;&#65292;&#36825;&#19968;&#20999;&#19981;&#33021;&#31639;&#22312; AI &#22836;&#19978;&#12290;AI &#26412;&#36136;&#19978;&#21482;&#26159;&#24037;&#20855;&#65292;&#30495;&#27491;&#21033;&#29992;&#23427;&#36896;&#20551;&#12289;&#34892;&#39575;&#30340;&#20173;&#28982;&#26159;&#20154;&#65292;&#21482;&#26159;&#27450;&#39575;&#30340;&#26041;&#24335;&#21464;&#20102;&#12289;&#25104;&#26412;&#26356;&#20302;&#20102;&#12290;</p><p>&#22312;&#36825;&#31181;&#32972;&#26223;&#19979;&#65292;&#37325;&#25342;&#30495;&#23454;&#19982;&#20449;&#20219;&#65292;&#21482;&#20250;&#21464;&#24471;&#24840;&#21457;&#22256;&#38590;&#12290;<br>&#25110;&#35768;&#65292;&#26368;&#32456;&#20173;&#38656;&#8220;&#39764;&#27861;&#25171;&#36133;&#39764;&#27861;&#8221;&#65306;&#25968;&#23383;&#31614;&#21517;&#12289;&#21487;&#20449;&#26102;&#38388;&#25139;&#12289;&#21306;&#22359;&#38142;&#39564;&#35777;&#8230;&#8230;&#23427;&#20204;&#26410;&#24517;&#26159;&#23436;&#32654;&#35299;&#27861;&#65292;&#20294;&#33267;&#23569;&#26159;&#20540;&#24471;&#25506;&#32034;&#30340;&#26041;&#21521;&#12290;</p><p>&#20174;&#23567;&#25105;&#27597;&#20146;&#23601;&#24120;&#35828;&#65306;&#8220;&#20174;&#21892;&#22914;&#30331;&#65292;&#20174;&#24694;&#22914;&#23849;&#8221;&#12290;</p><p>&#20449;&#20219;&#20134;&#22914;&#27492;&#8212;&#8212;&#37325;&#24314;&#36828;&#27604;&#25703;&#27585;&#33392;&#38590;&#65292;&#21364;&#20063;&#27491;&#22240;&#22914;&#27492;&#25165;&#26174;&#24471;&#26684;&#22806;&#29645;&#36149;&#12290;</p><p><a href="https://fatbobman.com/zh/weekly/issue-111/">&#21069;&#19968;&#26399;&#20869;&#23481;</a>&#65372;<a href="https://fatbobman.com/zh/weekly/">&#20840;&#37096;&#21608;&#25253;&#21015;&#34920;</a></p><div class="pullquote"><p>&#22914;&#26524;&#24744;&#21457;&#29616;&#36825;&#20221;&#21608;&#25253;&#25110;&#25105;&#30340;&#21338;&#23458;&#23545;&#24744;&#26377;&#25152;&#24110;&#21161;&#65292;&#21487;&#20197;&#32771;&#34385;&#36890;&#36807; <strong><a href="https://afdian.com/a/fatbobman">&#29233;&#21457;&#30005;</a>&#65292;<a href="https://www.buymeacoffee.com/fatbobman">Buy Me a Coffee</a></strong> &#25903;&#25345;&#25105;&#30340;&#21019;&#20316;&#12290;</p></div><h2><strong>&#26412;&#26399;&#36190;&#21161;</strong></h2><h3><strong><a href="https://l.fatbobman.com/sb-proxyman">&#38656;&#35201;&#22312; iPhone &#19978;&#35843;&#35797; HTTPS&#65311;</a></strong></h3><p>&#35797;&#35797; <strong>Proxyman</strong>&#65281;&#36825;&#26159;&#19968;&#27454;&#39030;&#32423;&#30340; macOS &#24212;&#29992;&#65292;&#21482;&#38656;&#28857;&#20987;&#20960;&#19979;&#65292;&#21363;&#21487;&#36731;&#26494;&#25429;&#33719;&#21644;&#35843;&#35797; HTTP(s) &#27969;&#37327;&#12290;&#25903;&#25345; iOS&#35774;&#22791;&#21644;&#27169;&#25311;&#22120;&#12290;</p><p><strong>&#127881; &#40657;&#20116;&#29305;&#24800; &#8212; &#26412;&#21608;&#38480;&#26102; 7 &#25240;&#65281; </strong><a href="https://l.fatbobman.com/sb-proxyman">&#31435;&#21363;&#35797;&#29992; &#8594;</a></p><div><hr></div><h2><strong>&#36817;&#26399;&#25512;&#33616;</strong></h2><h3><strong><a href="https://fatbobman.com/zh/posts/deep-dive-into-imessage/?utm_source=fatbobman%20weekly%20issue%20112&amp;utm_medium=web">&#28145;&#20837; iMessage &#24213;&#23618;&#65306;&#19968;&#20010; Agent &#26159;&#22914;&#20309;&#35806;&#29983;&#30340;</a></strong></h3><p>&#20316;&#20026; Apple &#29983;&#24577;&#30340;&#24320;&#21457;&#32773;&#65292;&#25105;&#20204;&#24120;&#24120;&#20250;&#38754;&#23545;&#19968;&#20010;&#24494;&#22937;&#30340;&#24726;&#35770;&#65306;&#31995;&#32479;&#26412;&#36523;&#20855;&#22791;&#24378;&#22823;&#30340;&#33021;&#21147;&#65292;&#20294;&#36825;&#20123;&#33021;&#21147;&#24182;&#19981;&#19968;&#23450;&#20197;&#20844;&#24320; API &#30340;&#24418;&#24335;&#21521;&#24320;&#21457;&#32773;&#24320;&#25918;&#12290;iMessage &#27491;&#26159;&#20854;&#20013;&#30340;&#20856;&#22411; &#8212;&#8212; &#23427;&#28145;&#24230;&#34701;&#20837; iOS &#19982; macOS&#65292;&#26159;&#29992;&#25143;&#26085;&#24120;&#27807;&#36890;&#30340;&#26680;&#24515;&#36733;&#20307;&#65292;&#21364;&#22987;&#32456;&#27809;&#26377;&#25552;&#20379;&#21487;&#20379;&#24320;&#21457;&#32773;&#20351;&#29992;&#30340;&#33258;&#21160;&#21270;&#25509;&#21475;&#12290;<a href="https://github.com/photon-hq/imessage-kit?utm_source=fatbobman%20weekly%20issue%20112&amp;utm_medium=web">imessage-kit</a> &#30340;&#20316;&#32773; <a href="https://el5.net/@lingjue">LingJueYa</a>&#65292;&#20998;&#20139;&#20182;&#22312;&#26500;&#24314;&#36825;&#19968;&#24037;&#20855;&#26102;&#30340;&#25506;&#32034;&#36335;&#24452;&#12290;&#20294;&#20854;&#26680;&#24515;&#25361;&#25112;&#20960;&#20046;&#37117;&#26469;&#33258; Apple &#24179;&#21488;&#26412;&#36523;&#65306;&#35299;&#26512;&#20197; 2001 &#20026;&#32426;&#20803;&#30340;&#26102;&#38388;&#25139;&#12289;&#20174;&#20108;&#36827;&#21046; plist &#20013;&#24674;&#22797; NSAttributedString &#20869;&#23481;&#12289;&#22312; macOS &#30340;&#27801;&#30418;&#20307;&#31995;&#19979;&#23433;&#20840;&#22320;&#35835;&#21462;&#36164;&#28304;&#12289;&#20197;&#21450;&#19982; AppleScript &#36825;&#31181;&#21382;&#21490;&#24736;&#20037;&#30340;&#33258;&#21160;&#21270;&#26426;&#21046;&#25171;&#20132;&#36947;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-01">SwiftUI &#24050;&#27515;? UIKit &#30340;&#22238;&#24402;&#20043;&#36335; (2025: The Year SwiftUI Died)</a></strong></h3><p><a href="https://x.com/jacobtechtavern">Jacob Bartlett</a> &#30340;&#36825;&#31687;&#25991;&#31456;&#26631;&#39064;&#39047;&#20855;&#25361;&#34885;&#24847;&#21619;&#65292;&#20182;&#25552;&#20986;&#20102;&#19968;&#20010;&#20540;&#24471;&#35752;&#35770;&#30340;&#35266;&#28857;&#65306;2025 &#24180;&#20063;&#35768;&#26159; SwiftUI &#30340;&#25296;&#28857;&#65292;&#32780;&#19981;&#26159;&#23427;&#30340;&#24005;&#23792;&#12290;&#26680;&#24515;&#35770;&#28857;&#22312;&#20110;&#65292;&#33529;&#26524;&#23558; <code>@Observable</code> &#23439;&#21644; <code>updateProperties()</code> &#26041;&#27861;&#24341;&#20837; UIKit&#65292;&#20351;&#20854;&#20855;&#22791;&#20102;&#29616;&#20195;&#21270;&#30340;&#29366;&#24577;&#31649;&#29702;&#33021;&#21147;&#65307;&#21516;&#26102;&#65292;AI &#36741;&#21161;&#32534;&#31243;&#24037;&#20855;&#30340;&#25104;&#29087;&#26497;&#22823;&#38477;&#20302;&#20102;&#32534;&#20889; UIKit &#20195;&#30721;&#30340;&#25104;&#26412;&#65288;&#32780; AI &#23545; SwiftUI &#36825;&#31181;&#22768;&#26126;&#24335;&#33539;&#24335;&#30340;&#29702;&#35299;&#20173;&#26174;&#19981;&#36275;&#65289;&#12290;</p><blockquote><p>&#33529;&#26524;&#23545; SwiftUI &#30340;&#38271;&#26399;&#25237;&#20837;&#19981;&#20250;&#21160;&#25671;&#65292;&#23588;&#20854;&#32771;&#34385;&#21040;&#23427;&#22312;&#22810;&#31471;&#36866;&#37197;&#19978;&#30340;&#22825;&#28982;&#20248;&#21183;&#12290;&#19982;&#27492;&#21516;&#26102;&#65292;AI &#30340;&#26222;&#21450;&#20063;&#35753;&#35768;&#22810;&#20197; SwiftUI &#20837;&#38376;&#30340;&#24320;&#21457;&#32773;&#26356;&#23481;&#26131;&#20351;&#29992; UIKit &#26469;&#34917;&#40784;&#24615;&#33021;&#25110;&#33021;&#21147;&#19978;&#30340;&#19981;&#36275;&#12290;&#36873;&#25321;&#19981;&#19968;&#23450;&#35201;&#38750;&#27492;&#21363;&#24444;&#65292;&#21487;&#20197;&#23558;&#20004;&#32773;&#32467;&#21512;&#36215;&#26469;&#29992;&#24471;&#26356;&#22909;&#12290; &#36825;&#26679;&#26356;&#22909;&#21543;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-02">UIKit &#20013;&#30340;&#35270;&#22270;&#33258;&#21160;&#21047;&#26032; (Automatic property observation in UIKit with @Observable)</a></strong></h3><p>UIKit &#22312; iOS 26 &#20013;&#27491;&#24335;&#24341;&#20837;&#20102;&#23545; Swift Observation &#30340;&#21407;&#29983;&#25903;&#25345;&#12290;&#24403;&#20320;&#22312; <code>updateProperties()</code>&#20013;&#35835;&#21462; <code>@Observable</code> &#23545;&#35937;&#30340;&#23646;&#24615;&#26102;&#65292;UIKit &#20250;&#33258;&#21160;&#36861;&#36394;&#36825;&#20123;&#20381;&#36182;&#20851;&#31995;&#65292;&#24182;&#22312;&#25968;&#25454;&#21464;&#21270;&#26102;&#25353;&#38656;&#21047;&#26032;&#23545;&#24212;&#35270;&#22270;&#12290;<a href="https://x.com/natpanferova">Natalia Panferova</a> &#36890;&#36807;&#19968;&#20010;&#28151;&#21512; UIKit + SwiftUI &#30340;&#23454;&#38469;&#26696;&#20363;&#23637;&#31034;&#20102;&#36825;&#19968;&#29305;&#24615;&#22312;&#36328;&#26694;&#26550;&#25968;&#25454;&#20849;&#20139;&#26102;&#30340;&#20415;&#21033;&#24615;&#12290;&#25991;&#31456;&#36824;&#20171;&#32461;&#20102; iOS 18 &#30340;&#21521;&#19979;&#20860;&#23481;&#26041;&#26696;&#65306;&#22312; <code>Info.plist</code> &#20013;&#28155;&#21152; <code>UIObservationTrackingEnabled</code> &#38190;&#65292;&#24182;&#23558;&#26356;&#26032;&#36923;&#36753;&#25918;&#22312; <code>viewWillLayoutSubviews()</code> &#20013;&#21363;&#21487;&#23454;&#29616;&#30456;&#21516;&#25928;&#26524;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-03">SwiftData &#23545; AttributedString &#30340;&#21407;&#29983;&#25903;&#25345; (How SwiftData Represents AttributedString in Core Data Storage)</a></strong></h3><p>&#23613;&#31649; AttributedString &#26412;&#36523;&#31526;&#21512; Codable&#65292;&#20294;&#36807;&#21435;&#24320;&#21457;&#32773;&#24182;&#19981;&#33021;&#30452;&#25509;&#22312; SwiftData &#27169;&#22411;&#20013;&#23558;&#20854;&#20316;&#20026;&#23646;&#24615;&#20351;&#29992;&#12290;&#36825;&#19968;&#38480;&#21046;&#32456;&#20110;&#22312; iOS 26 &#20013;&#34987;&#35299;&#38500; &#8212;&#8212; &#33529;&#26524;&#26174;&#28982;&#20026;&#23427;&#24320;&#20102;&#19968;&#26465;&#8220;&#29305;&#21035;&#36890;&#36947;&#8221;&#65292;&#22914;&#20170;&#23427;&#24050;&#32463;&#21487;&#20197;&#20687; Int&#12289;String &#36825;&#26679;&#30340;&#22522;&#30784;&#31867;&#22411;&#19968;&#26679;&#30452;&#25509;&#23384;&#20648;&#20102;&#12290;<a href="https://apps.apple.com/us/app/id6737813684">DataScout for SwiftData</a>&#65288;SwiftData &#25968;&#25454;&#24211;&#20998;&#26512;&#24212;&#29992;&#65289;&#30340;&#20316;&#32773; <a href="https://www.linkedin.com/in/oleksii-oliinyk-83482995/">Oleksii Oliinyk</a> &#22312;&#32500;&#25252;&#24037;&#20855;&#26102;&#36973;&#36935;&#20102;&#30456;&#20851;&#30340;&#23849;&#28291;&#38382;&#39064;&#65292;&#24182;&#39034;&#21183;&#28145;&#20837;&#20998;&#26512;&#20102;&#20854;&#32972;&#21518;&#30340;&#23454;&#29616;&#26426;&#21046;&#12290;</p><blockquote><p>SwiftData &#20801;&#35768;&#24320;&#21457;&#32773;&#23558;&#31526;&#21512; Codable &#21327;&#35758;&#30340;&#31867;&#22411;&#20316;&#20026;&#27169;&#22411;&#23646;&#24615;&#65292;&#36825;&#26412;&#36523;&#26159;&#19968;&#39033;&#21313;&#20998;&#24378;&#22823;&#30340;&#33021;&#21147;&#12290;&#20294;&#23427;&#30340;&#24213;&#23618;&#22788;&#29702;&#26041;&#24335;&#21487;&#33021;&#19982;&#35768;&#22810;&#20154;&#39044;&#24819;&#30340;&#24182;&#19981;&#30456;&#21516;&#12290;&#25105;&#22312;&#12298;<a href="https://fatbobman.com/zh/posts/considerations-for-using-codable-and-enums-in-swiftdata-models/">&#22312; SwiftData &#27169;&#22411;&#20013;&#20351;&#29992; Codable &#21644;&#26522;&#20030;&#30340;&#27880;&#24847;&#20107;&#39033;</a>&#12299;&#20013;&#23545; SwiftData &#30340; Codable &#36716;&#25442;&#36923;&#36753;&#19982;&#28508;&#22312;&#38519;&#38449;&#20570;&#20102;&#26356;&#31995;&#32479;&#30340;&#20171;&#32461;&#12290;&#27492;&#22806;&#65292;&#22914;&#26524;&#20320;&#38656;&#35201;&#22312; iOS 26 &#20043;&#21069;&#20445;&#23384; AttributedString&#65292;&#21487;&#20197;&#21442;&#32771;&#33529;&#26524;&#24320;&#21457;&#32773;&#35770;&#22363;&#19978;&#30340;&#36825;&#20010;<a href="https://developer.apple.com/forums/thread/762438">&#24086;&#23376;</a>&#12290;</p></blockquote><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-04">AnyLanguageModel:&#32479;&#19968; Apple &#24179;&#21488;&#30340; LLM &#25509;&#21475; (Introducing AnyLanguageModel: One API for Local and Remote LLMs on Apple Platforms)</a></strong></h3><p>AnyLanguageModel &#26159;&#30001; <a href="https://x.com/mattt">Mattt</a> &#24320;&#21457;&#30340;&#32479;&#19968; Swift &#22823;&#27169;&#22411;&#25509;&#21475;&#24211;&#65292;&#25105;&#20204;&#24050;&#22312;<a href="https://fatbobman.com/zh/weekly/issue-109/#anylanguagemodel---%E7%BB%9F%E4%B8%80-swift-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BC%80%E5%8F%91%E8%8C%83%E5%BC%8F">&#31532; 109 &#26399;&#21608;&#25253;</a>&#20013;&#20171;&#32461;&#36807;&#20854;&#26680;&#24515;&#29702;&#24565;&#12290;&#35813;&#24211;&#20197; Foundation Models &#30340; API &#35774;&#35745;&#20026;&#22522;&#30784;&#65292;&#22312;&#20445;&#25345;&#24320;&#21457;&#32773;&#29087;&#24713;&#30340;&#20351;&#29992;&#26041;&#24335;&#30340;&#21516;&#26102;&#65292;&#32479;&#19968;&#25903;&#25345;&#22810;&#31181;&#27169;&#22411;&#25552;&#20379;&#26041;&#65292;&#21253;&#25324;&#26412;&#22320;&#27169;&#22411;&#65288;Core ML&#12289;MLX&#12289;llama.cpp&#12289;Ollama&#65289;&#20197;&#21450;&#20113;&#31471;&#27169;&#22411;&#65288;OpenAI&#12289;Anthropic&#12289;Google Gemini &#31561;&#65289;&#65292;&#22823;&#24133;&#38477;&#20302;&#20102;&#36328; API&#12289;&#36328;&#36816;&#34892;&#26041;&#24335;&#25152;&#24102;&#26469;&#30340;&#38598;&#25104;&#36127;&#25285;&#65292;&#20063;&#35753;&#25506;&#32034;&#24320;&#28304;&#27169;&#22411;&#21464;&#24471;&#26356;&#23481;&#26131;&#12290;</p><p>&#22312;&#36825;&#31687;&#25991;&#31456;&#20013;&#65292;Mattt &#36827;&#19968;&#27493;&#20171;&#32461;&#20102; AnyLanguageModel &#30340;&#35774;&#35745;&#24605;&#36335;&#12289;&#36328;&#21518;&#31471;&#30340;&#33021;&#21147;&#25277;&#35937;&#21450; Swift 6.1 package traits &#22312;&#25511;&#21046;&#20381;&#36182;&#20307;&#31215;&#20013;&#30340;&#20316;&#29992;&#12290;&#20540;&#24471;&#19968;&#25552;&#30340;&#26159;&#65292;&#23613;&#31649;&#33529;&#26524;&#24403;&#21069;&#23578;&#26410;&#22312; Foundation Models &#20013;&#25552;&#20379;&#22270;&#20687;&#36755;&#20837;&#33021;&#21147;&#65292;AnyLanguageModel &#24050;&#20026; Claude &#31561;&#27169;&#22411;&#34917;&#19978;&#36825;&#19968;&#21151;&#33021;&#65292;&#20351;&#35270;&#35273;-&#35821;&#35328;&#22330;&#26223;&#20063;&#33021;&#22312; Apple &#24179;&#21488;&#19978;&#39034;&#21033;&#33853;&#22320;&#12290;</p><div><hr></div><h3><strong>Approachable Concurrency &#19982; MainActor by Default</strong></h3><p>&#26080;&#35770;&#26368;&#32456;&#36208;&#21521;&#22914;&#20309;&#65292;Swift 6.2 &#20013;&#24341;&#20837;&#30340; <em>Approachable Concurrency</em> &#27880;&#23450;&#20250;&#22312; Swift &#21457;&#23637;&#21490;&#19978;&#30041;&#19979;&#27987;&#37325;&#30340;&#19968;&#31508;&#12290;&#23427;&#22312;&#26576;&#20123;&#22330;&#26223;&#19979;&#26174;&#33879;&#38477;&#20302;&#20102;&#24182;&#21457;&#32534;&#31243;&#30340;&#24515;&#26234;&#36127;&#25285;&#65292;&#20294;&#20063;&#35753;&#19981;&#23569;&#24320;&#21457;&#32773;&#24863;&#21040;&#8220;&#36234;&#35299;&#37322;&#36234;&#22256;&#24785;&#8221;&#12290;</p><ul><li><p>&#22312; <a href="https://l.fatbobman.com/w0112-05">Approachable Concurrency in Swift 6.2: A Clear Guide</a> &#19968;&#25991;&#20013;&#65292;<a href="https://x.com/twannl">Antoine van der Lee</a> &#20013;&#23545;&#30456;&#20851;&#25552;&#26696;&#21644;&#26032;&#34892;&#20026;&#36827;&#34892;&#20102;&#31995;&#32479;&#26803;&#29702;&#12290;</p></li><li><p><a href="https://mastodon.social/@mattiem">Matt Massicotte</a> &#22312;&#23545;&#36825;&#20123;&#21151;&#33021;&#36827;&#34892;&#20102;&#35814;&#23613;&#30740;&#31350;&#21644;&#20998;&#20139;&#21518;&#65292;&#20182;&#22312;&#26368;&#26032;&#25991;&#31456; <a href="https://l.fatbobman.com/w0112-06">MainActor by Default</a> &#20013;&#24378;&#35843;&#65306;&#33267;&#23569;&#22312;&#29616;&#38454;&#27573;&#65292;&#20182;&#19981;&#20250;&#22312;&#39033;&#30446;&#20013;&#21551;&#29992; Default actor isolation = MainActor&#65292;&#22240;&#20026;&#8220;&#29702;&#35299;&#20026;&#20309;&#38656;&#35201; MainActor&#65292;&#35201;&#27604;&#29702;&#35299;&#20026;&#20309;&#21024;&#38500;&#23427;&#26356;&#23481;&#26131;&#8221;&#12290;</p></li><li><p>&#19981;&#36807;&#26377;&#19968;&#28857;&#24050;&#32463;&#21313;&#20998;&#26126;&#30830;&#65306;MainActor by Default &#19982;&#23884;&#20837;&#24335;&#24179;&#21488;&#38750;&#24120;&#22865;&#21512;&#12290;&#22312; <a href="https://l.fatbobman.com/w0112-07">Embedded Swift Improvements Coming in Swift 6.3</a> &#19968;&#25991;&#20013;&#65292;<a href="https://sfba.social/@dgregor79">Doug Gregor</a> &#21644; <a href="https://hachyderm.io/@rauhul">Rauhul Varma</a> &#21017;&#36827;&#19968;&#27493;&#23637;&#31034;&#20102; Swift 6.3 &#22312;&#23884;&#20837;&#24335;&#24179;&#21488;&#19978;&#30340;&#25913;&#36827;&#26041;&#21521;&#19982;&#21160;&#26426;&#12290;</p></li></ul><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-08">&#26500;&#24314;&#21487;&#25193;&#23637;&#30340;&#30333;&#26631; iOS &#24212;&#29992; (How to Build Scalable White-Label iOS Apps: From Multi-Target to Modular Architecture)</a></strong></h3><p>&#30333;&#26631;&#20135;&#21697;&#65288;White-Label&#65289;&#25351;&#30340;&#26159;&#19968;&#20010;&#26550;&#26500;&#28789;&#27963;&#12289;&#21487;&#22312;&#19981;&#21516;&#23458;&#25143;&#20043;&#38388;&#22797;&#29992;&#30340;&#36890;&#29992; App &#26694;&#26550;&#65292;&#33021;&#22815;&#25353;&#38656;&#26356;&#25442;&#21697;&#29260;&#30382;&#32932;&#19982;&#21151;&#33021;&#37197;&#32622;&#65288;&#20363;&#22914;&#36890;&#29992;&#30340;&#35746;&#39184; App &#27169;&#26495;&#65289;&#12290;<a href="https://x.com/PawelKozielecki">Pawel Kozielecki</a> &#22312;&#36825;&#31687;&#38271;&#25991;&#20013;&#31995;&#32479;&#26803;&#29702;&#20102; iOS White-Label &#24212;&#29992;&#30340;&#28436;&#36827;&#36335;&#32447;&#65292;&#23558;&#20854;&#21010;&#20998;&#20026;&#19977;&#20010;&#38454;&#27573;&#65306;&#22522;&#30784;&#21697;&#29260;&#23450;&#21046;&#12289;&#33258;&#23450;&#20041; UI/UX&#65292;&#20197;&#21450;&#23436;&#20840;&#27169;&#22359;&#21270;&#12290;&#22312;&#27492;&#22522;&#30784;&#19978;&#65292;&#20182;&#23545;&#27604;&#20102;&#19977;&#31181;&#24120;&#35265;&#23454;&#29616;&#31574;&#30053;&#8212;&#8212;&#22810; Target&#12289;&#36164;&#28304;&#22797;&#21046;&#12289;&#27169;&#22359;&#21270;&#26550;&#26500;&#65292;&#24182;&#25351;&#20986;&#38543;&#30528;&#23458;&#25143;&#25968;&#37327;&#19982;&#24046;&#24322;&#21270;&#38656;&#27714;&#22686;&#38271;&#65292;&#30495;&#27491;&#33021;&#22815;&#38271;&#26399;&#25193;&#23637;&#12289;&#36991;&#20813;&#32500;&#25252;&#22833;&#25511;&#30340;&#26041;&#26696;&#21482;&#26377;&#27169;&#22359;&#21270;&#65288;Modular Architecture&#65289;&#12290;&#25991;&#31456;&#36824;&#32467;&#21512;&#22823;&#37327;&#23454;&#25112;&#32454;&#33410;&#65292;&#35752;&#35770;&#20102;&#23457;&#26680;&#12289;&#31614;&#21517;&#12289;&#36164;&#28304;&#19982;&#37197;&#32622;&#20998;&#23618;&#12289;&#27979;&#35797;&#19982; CI &#31561;&#30333;&#26631;&#39033;&#30446;&#22312;&#35268;&#27169;&#21270;&#36807;&#31243;&#20013;&#30340;&#20851;&#38190;&#25361;&#25112;&#12290;</p><h2><strong>&#24037;&#20855;</strong></h2><h3><strong><a href="https://l.fatbobman.com/w0112-09">QuickLayout: &#22768;&#26126;&#24335; UIKit &#24067;&#23616;&#24211;</a></strong></h3><p>&#26082;&#28982; UIKit &#24050;&#32463;&#21487;&#20197;&#26080;&#32541;&#38598;&#25104; Observation &#20102;&#65292;&#37027;&#20040;&#20197; SwiftUI &#39118;&#26684;&#32534;&#20889;&#24067;&#23616;&#20195;&#30721;&#20063;&#23601;&#19981;&#36275;&#20026;&#22855;&#20102;&#12290;&#30001; <a href="https://www.linkedin.com/in/constantine-fry/">Constantine Fry</a> &#24320;&#21457;&#30340; QuickLayout &#20415;&#25552;&#20379;&#20102;&#36825;&#26679;&#30340;&#33021;&#21147;&#65292;&#20854;&#24050;&#34987; Meta &#22312; Instagram &#30340;&#26680;&#24515;&#21151;&#33021;&#20013;&#20351;&#29992;&#12290;&#20320;&#21487;&#20197;&#30452;&#25509;&#20197;&#22914;&#19979;&#30340;&#26041;&#24335;&#36827;&#34892;&#24067;&#23616;:</p><pre><code>import QuickLayout
&#8203;
@QuickLayout
class MyCellView: UIView {
&#8203;
  let titleLabel = UILabel()
  let subtitleLabel = UILabel()
&#8203;
  var body: Layout {
    HStack {
      VStack(alignment: .leading) {
        titleLabel
        Spacer(4)
        subtitleLabel
      }
      Spacer()
    }
    .padding(.horizontal, 16)
    .padding(.vertical, 8)
  }
}</code></pre><p>UIKit &#21644; SwiftUI &#20174;&#26469;&#19981;&#26159;&#23545;&#31435;&#38754;&#65292;&#32780;&#26159;&#20004;&#22871;&#21487;&#20114;&#30456;&#20511;&#37492;&#30340; UI &#24605;&#32500;&#27169;&#22411;&#12290;&#29616;&#38454;&#27573; SwiftUI &#30340;&#20248;&#21183;&#22312;&#20110;&#25277;&#35937;&#19982;&#19968;&#33268;&#24615;&#65292;&#32780;&#39640;&#24615;&#33021;&#12289;&#31934;&#32454;&#25511;&#21046;&#12289;&#24037;&#20855;&#38142;&#25903;&#25345;&#31561;&#20173;&#26159; UIKit &#30340;&#29305;&#38271;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-10">SettingsKit</a></strong></h3><p>&#20960;&#20046;&#25152;&#26377;&#24212;&#29992;&#37117;&#38656;&#35201;&#35774;&#32622;&#30028;&#38754;&#65292;&#34429;&#28982;&#32534;&#20889;&#38590;&#24230;&#19981;&#39640;&#65292;&#20294;&#24403;&#36873;&#39033;&#19981;&#26029;&#22686;&#21152;&#26102;&#65292;&#32500;&#25252;&#25104;&#26412;&#20063;&#20250;&#38543;&#20043;&#19978;&#21319;&#12290;<a href="https://x.com/AetherAurelia">Aether</a> &#24320;&#21457;&#30340; SettingsKit &#27491;&#26159;&#20026;&#27492;&#32780;&#29983;&#12290;&#23427;&#35753; SwiftUI &#24320;&#21457;&#32773;&#21487;&#20197;&#24555;&#36895;&#26500;&#24314;&#19968;&#20010;&#21487;&#25193;&#23637;&#12289;&#26679;&#24335;&#32479;&#19968;&#12289;&#24182;&#24102;&#26377;&#25628;&#32034;&#33021;&#21147;&#30340;&#35774;&#32622;&#30028;&#38754;&#65292;&#24182;&#20869;&#32622;&#20998;&#32452;&#12289;&#21345;&#29255;&#12289;&#20391;&#26639;&#31561;&#22810;&#31181;&#39118;&#26684;&#65292;&#36866;&#29992;&#20110;&#20013;&#22823;&#22411;&#35774;&#32622;&#27169;&#22359;&#30340;&#25645;&#24314;&#12290;</p><div><hr></div><h3><strong><a href="https://l.fatbobman.com/w0112-11">KurrentDB-Swift</a></strong></h3><p>Kurrent&#65288;&#21407; EventStoreDB&#65289;&#26159;&#19968;&#27454;&#19987;&#38376;&#29992;&#20110;&#20107;&#20214;&#23384;&#20648;&#30340;&#25968;&#25454;&#24211;&#65292;&#23427;&#19981;&#20165;&#20445;&#23384;&#31995;&#32479;&#30340;&#26368;&#26032;&#29366;&#24577;&#65292;&#36824;&#33021;&#23436;&#25972;&#35760;&#24405;&#27599;&#19968;&#27425;&#21464;&#21270;&#30340;&#21382;&#21490;&#65292;&#38750;&#24120;&#36866;&#29992;&#20110;&#37329;&#34701;&#12289;&#29289;&#27969;&#12289;&#38646;&#21806;&#12289;&#30005;&#21830;&#12289;SaaS &#31561;&#38656;&#35201;&#24378;&#21487;&#36861;&#28335;&#24615;&#30340;&#22330;&#26223;&#12290;&#20316;&#20026; KurrentDB &#30340; Swift &#23458;&#25143;&#31471;&#24211;&#65292;&#30001; <a href="https://x.com/gradyzhuo">Grady Zhuo</a> &#24320;&#21457;&#30340; KurrentDB-Swift &#25903;&#25345; Swift 6&#12289;async/await &#27969;&#24335;&#35746;&#38405;&#19982;&#20107;&#20214;&#35835;&#21462;&#65292;&#34917;&#19978;&#20102; Swift &#29983;&#24577;&#22312; Event Sourcing &#39046;&#22495;&#38271;&#26399;&#32570;&#20047;&#25104;&#29087;&#24037;&#20855;&#30340;&#31354;&#30333;&#12290;</p>]]></content:encoded></item></channel></rss>