<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hsin-Chieh Cheng</title>
    <description>The latest articles on DEV Community by Hsin-Chieh Cheng (@hsinchieh_cheng_21828cea).</description>
    <link>https://dev.to/hsinchieh_cheng_21828cea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3965669%2F942993eb-c0f2-42f5-9a3f-52466f011dce.jpg</url>
      <title>DEV Community: Hsin-Chieh Cheng</title>
      <link>https://dev.to/hsinchieh_cheng_21828cea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hsinchieh_cheng_21828cea"/>
    <language>en</language>
    <item>
      <title>程式碼定位、追蹤與修改操作筆記</title>
      <dc:creator>Hsin-Chieh Cheng</dc:creator>
      <pubDate>Wed, 03 Jun 2026 04:25:07 +0000</pubDate>
      <link>https://dev.to/hsinchieh_cheng_21828cea/cheng-shi-ma-ding-wei-zhui-zong-yu-xiu-gai-cao-zuo-bi-ji-23he</link>
      <guid>https://dev.to/hsinchieh_cheng_21828cea/cheng-shi-ma-ding-wei-zhui-zong-yu-xiu-gai-cao-zuo-bi-ji-23he</guid>
      <description>&lt;h1&gt;
  
  
  程式碼定位、追蹤與修改操作筆記
&lt;/h1&gt;

&lt;p&gt;這份筆記整理一套不用 AI 時也能照著做的工作流程：如何定位函式定義、找引用、追資料流、確認行為，並安全修改檔案。&lt;/p&gt;

&lt;h2&gt;
  
  
  核心原則
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;先用最快的工具縮小範圍，再用更精準的工具確認語意。&lt;/li&gt;
&lt;li&gt;先找「定義」與「引用」，再讀上下文，不要只看單行。&lt;/li&gt;
&lt;li&gt;修改前先確認資料流與呼叫順序，修改後用 &lt;code&gt;git diff&lt;/code&gt;、build、test 驗證。&lt;/li&gt;
&lt;li&gt;對 Xcode project 管理的 Swift 檔案，新增、刪除、搬移時要注意 &lt;code&gt;.xcodeproj&lt;/code&gt; reference。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  工具選擇
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;需求&lt;/th&gt;
&lt;th&gt;優先工具&lt;/th&gt;
&lt;th&gt;何時使用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;快速找文字、函式、變數&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;第一輪定位，速度最快&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;看檔案行號與上下文&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;nl -ba&lt;/code&gt; + &lt;code&gt;sed&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;找到結果後閱讀附近程式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;找 Swift 定義、引用、型別&lt;/td&gt;
&lt;td&gt;Xcode index / SourceKit-LSP&lt;/td&gt;
&lt;td&gt;同名函式、overload、protocol extension 較多時&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swift 語法結構分析或安全改寫&lt;/td&gt;
&lt;td&gt;SwiftSyntax&lt;/td&gt;
&lt;td&gt;需要 AST/CST 等級分析或批次 rewrite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;通用語法樹查詢&lt;/td&gt;
&lt;td&gt;tree-sitter&lt;/td&gt;
&lt;td&gt;想找特定語法形狀，但不需要完整型別解析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C/C++/Obj-C symbol index&lt;/td&gt;
&lt;td&gt;ctags / cscope&lt;/td&gt;
&lt;td&gt;老專案或 C-family code 較多時&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;修改既有檔案內容&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apply_patch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;小到中型人工修改&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;新增 Xcode project 內 Swift 檔&lt;/td&gt;
&lt;td&gt;Xcode MCP &lt;code&gt;XcodeWrite&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;需要加入 project structure / compile sources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;刪除 Xcode project 檔案&lt;/td&gt;
&lt;td&gt;Xcode MCP &lt;code&gt;XcodeRM&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;避免只刪檔案但 project reference 還留著&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;搬移或 rename Xcode 檔案&lt;/td&gt;
&lt;td&gt;Xcode MCP &lt;code&gt;XcodeMV&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;避免 Xcode project reference 壞掉&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  定位函式定義
&lt;/h2&gt;

&lt;p&gt;假設要找 &lt;code&gt;presentWebView&lt;/code&gt; 的定義：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'func\s+presentWebView\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;說明：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;func&lt;/code&gt;：找 Swift function declaration。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\s+&lt;/code&gt;：一個或多個空白，允許 &lt;code&gt;func    presentWebView&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\b&lt;/code&gt;：單字邊界，避免誤中 &lt;code&gt;presentWebViewController&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt;：顯示行號。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-g '*.swift'&lt;/code&gt;：只查 Swift 檔。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果函式可能是 property、closure、protocol requirement，也可以放寬：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'\bpresentWebView\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  找函式引用
&lt;/h2&gt;

&lt;p&gt;找呼叫點：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'\bpresentWebView\s*\('&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;說明：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;\bpresentWebView&lt;/code&gt;：要求是完整名稱。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\s*&lt;/code&gt;：允許函式名和 &lt;code&gt;(&lt;/code&gt; 中間有空白。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\(&lt;/code&gt;：找真正的左括號。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果有 trailing closure 或不同語法，也可先放寬：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'\bpresentWebView\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;再人工排除不是呼叫的結果。&lt;/p&gt;

&lt;h2&gt;
  
  
  閱讀上下文
&lt;/h2&gt;

&lt;p&gt;找到檔案與行號後，用 &lt;code&gt;nl -ba&lt;/code&gt; 顯示行號，再用 &lt;code&gt;sed&lt;/code&gt; 切範圍：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nl&lt;/span&gt; &lt;span class="nt"&gt;-ba&lt;/span&gt; AppPOS/Common/WebView/WebViewCoordinator.swift | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'30,75p'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;常見用法：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nl&lt;/span&gt; &lt;span class="nt"&gt;-ba&lt;/span&gt; path/to/File.swift | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'起始行,結束行p'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;例：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nl&lt;/span&gt; &lt;span class="nt"&gt;-ba&lt;/span&gt; AppPOS/Payment/Payment/QRScan/QRScanViewController.swift | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'24,45p;190,225p;250,265p'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;這可以一次看：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;property 宣告&lt;/li&gt;
&lt;li&gt;delegate callback&lt;/li&gt;
&lt;li&gt;setup camera&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  追資料流的方法
&lt;/h2&gt;

&lt;p&gt;以 QR/barcode 掃描為例，確認是否支援 Code 128 時，追三段：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;支援格式宣告
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'AVMetadataObject.ObjectType|vaildObjectTypes|code128'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;看到：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;vaildObjectTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;AVMetadataObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;ObjectType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;qr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code128&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;是否真的套用到相機 output
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'metadataObjectTypes\s*='&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;看到：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadataObjectTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vaildObjectTypes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;delegate 收到後是否放行
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'metadataOutput|contains\(data.type\)|scanCodeSubject.send'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;看到：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vaildObjectTypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;scanCodeSubject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;symbolData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;這三段都成立時，才能說「相機掃描層支援 Code 128」。&lt;/p&gt;

&lt;p&gt;接著要追後續業務是否接受：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'scanCodeSubject|scanCode|paymentRequest|voucherScan|voucherInquiry|isFormatValid'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;例：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scanCode&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;useCase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paymentRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;oneTimeKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;或：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;VoucherCodeChecker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFormatValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;這代表掃描層支援不等於業務層一定接受。&lt;/p&gt;

&lt;h2&gt;
  
  
  Regex 常用片段
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Regex&lt;/th&gt;
&lt;th&gt;意思&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;空白字元，包含 space、tab、換行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\s+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;一個或多個空白&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\s*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;零個或多個空白&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;單字邊界&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\(&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;左括號 &lt;code&gt;(&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;任意字元&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;任意字元重複零次以上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;`foo&lt;/td&gt;
&lt;td&gt;bar`&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;建議 shell 裡用單引號包 regex：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'func\s+presentWebView\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;比雙引號少處理一層 escape。&lt;/p&gt;

&lt;h2&gt;
  
  
  AST、LSP、rg 的差別
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;解決問題&lt;/th&gt;
&lt;th&gt;適合情境&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;找文字 pattern&lt;/td&gt;
&lt;td&gt;快速定位、第一輪搜尋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AST/CST&lt;/td&gt;
&lt;td&gt;理解語法形狀&lt;/td&gt;
&lt;td&gt;找所有 function declaration、assignment、call expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LSP&lt;/td&gt;
&lt;td&gt;理解 symbol 語意&lt;/td&gt;
&lt;td&gt;go to definition、find references、hover type、diagnostics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;簡單判斷：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;想找「文字在哪裡」：用 &lt;code&gt;rg&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;想找「這段 code 是什麼語法結構」：用 AST/CST。&lt;/li&gt;
&lt;li&gt;想找「這個名字實際指的是哪個 symbol」：用 LSP / Xcode index。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Swift 專案裡：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AST/CST：SwiftSyntax、&lt;code&gt;swiftc -dump-ast&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;LSP：SourceKit-LSP、Xcode index。&lt;/li&gt;
&lt;li&gt;通用 CST：tree-sitter。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SourceKit-LSP 怎麼用
&lt;/h2&gt;

&lt;p&gt;確認路徑：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcrun &lt;span class="nt"&gt;--find&lt;/span&gt; sourcekit-lsp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;通常會得到類似：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;實務上通常不手動呼叫 raw LSP JSON，而是透過 editor：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Xcode：Jump to Definition、Find Call Hierarchy、Find References。&lt;/li&gt;
&lt;li&gt;VS Code / Neovim：設定 LSP server 為 &lt;code&gt;xcrun sourcekit-lsp&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;對 Xcode app 專案，先 build 過會讓 index 比較完整：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcodebuild build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-project&lt;/span&gt; AppPOS.xcodeproj &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-scheme&lt;/span&gt; &lt;span class="s2"&gt;"AppPOS Dev"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-destination&lt;/span&gt; &lt;span class="s1"&gt;'platform=iOS Simulator,name=iPhone 17,OS=26.5'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Xcode MCP 常用操作
&lt;/h2&gt;

&lt;p&gt;如果在有 Xcode MCP 的環境，可以用：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指令&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeGrep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在 Xcode project structure 裡搜尋&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeRead&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;讀 Xcode project 裡的檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeGlob&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用 wildcard 找 project 檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeGetCurrentFile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;讀目前 editor 開啟檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BuildProject&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;build 目前 active scheme&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetBuildLog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;讀 build log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeRefreshCodeIssuesInFile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;查單檔 compiler diagnostics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GetTestList&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;列出 tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RunSomeTests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跑指定 tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeWrite&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;新增/覆寫檔案並加入 project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeUpdate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用 old/new string 修改檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeRM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;刪除 project 檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XcodeMV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;move / rename project 檔案&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;注意：Xcode MCP 看的是 Xcode project organization，不完全等同 filesystem。&lt;/p&gt;

&lt;h2&gt;
  
  
  修改檔案：apply_patch
&lt;/h2&gt;

&lt;p&gt;修改既有檔案：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;*** Begin Patch
*** Update File: AppPOS/Foo.swift
@@
&lt;span class="gd"&gt;-    let title = "Old"
&lt;/span&gt;&lt;span class="gi"&gt;+    let title = "New"
&lt;/span&gt;*** End Patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;新增檔案：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;*** Begin Patch
*** Add File: docs/example.md
&lt;span class="gi"&gt;+# Example
+
+This is a new file.
&lt;/span&gt;*** End Patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;刪除檔案：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;*** Begin Patch
*** Delete File: docs/old.md
*** End Patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;使用原則：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;小到中型人工修改：用 &lt;code&gt;apply_patch&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;新增 Swift 檔且要進 Xcode target：優先 &lt;code&gt;XcodeWrite&lt;/code&gt;，或同步改 &lt;code&gt;.xcodeproj&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;刪除/搬移 Xcode project 檔：優先 &lt;code&gt;XcodeRM&lt;/code&gt; / &lt;code&gt;XcodeMV&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;修改完一定看 &lt;code&gt;git diff&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  修改後驗證
&lt;/h2&gt;

&lt;p&gt;基本檢查：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff &lt;span class="nt"&gt;--stat&lt;/span&gt;
git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;找是否有漏改：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'OldName|NewName'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;跑測試或 build：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcodebuild &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-project&lt;/span&gt; AppPOS.xcodeproj &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-scheme&lt;/span&gt; &lt;span class="s2"&gt;"AppPOS Dev"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-destination&lt;/span&gt; &lt;span class="s1"&gt;'platform=iOS Simulator,name=iPhone 17,OS=26.5'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-only-testing&lt;/span&gt;:AppPOSTests/SomeTests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;如果只是確認 project schemes：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcodebuild &lt;span class="nt"&gt;-list&lt;/span&gt; &lt;span class="nt"&gt;-project&lt;/span&gt; AppPOS.xcodeproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  實戰流程模板
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;先找入口：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'目標關鍵字|目標函式|目標型別'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;找定義：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'func\s+函式名\b|class\s+型別名\b|struct\s+型別名\b|enum\s+型別名\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;找引用：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'\b函式名\s*\(|\b變數名\b|\b型別名\b'&lt;/span&gt; AppPOS &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'*.swift'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;讀上下文：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nl&lt;/span&gt; &lt;span class="nt"&gt;-ba&lt;/span&gt; path/to/File.swift | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'start,endp'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;追資料流：&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;UI event / delegate callback&lt;/li&gt;
&lt;li&gt;Subject / publisher send&lt;/li&gt;
&lt;li&gt;ViewModel input&lt;/li&gt;
&lt;li&gt;UseCase&lt;/li&gt;
&lt;li&gt;API request&lt;/li&gt;
&lt;li&gt;Model / validation&lt;/li&gt;
&lt;li&gt;Output / navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;修改：&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;既有內容：&lt;code&gt;apply_patch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Xcode 新增檔：&lt;code&gt;XcodeWrite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Xcode 刪除檔：&lt;code&gt;XcodeRM&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Xcode 搬移檔：&lt;code&gt;XcodeMV&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;驗證：
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff
xcodebuild build/test ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  常見陷阱
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;只看到 &lt;code&gt;.code128&lt;/code&gt; 宣告，不代表有套用到 &lt;code&gt;metadataObjectTypes&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;掃描層支援格式，不代表業務層接受內容。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rg&lt;/code&gt; 找到同名函式，不代表是同一個 overload。&lt;/li&gt;
&lt;li&gt;protocol extension / dynamic dispatch 需要 LSP 或人工確認型別。&lt;/li&gt;
&lt;li&gt;新增 Swift 檔只放到 filesystem，不代表 Xcode target 會編譯。&lt;/li&gt;
&lt;li&gt;刪檔只用 &lt;code&gt;rm&lt;/code&gt;，可能留下 &lt;code&gt;.xcodeproj&lt;/code&gt; broken reference。&lt;/li&gt;
&lt;li&gt;build/test 失敗要分清楚是本次修改造成，還是既有環境問題。&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>swift</category>
      <category>ios</category>
      <category>xcode</category>
      <category>workflow</category>
    </item>
  </channel>
</rss>
