<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://luxmentis.org/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://luxmentis.org"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-25T00:00:00+00:00</updated>
    <id>https://luxmentis.org/atom.xml</id>
    <entry xml:lang="en">
        <title>Developing Xcode apps in Zed: Make your life easier with xcede&#x27;s profile switcher</title>
        <published>2026-05-25T00:00:00+00:00</published>
        <updated>2026-05-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luxmentis.org/blog/xcede-profile-switcher/"/>
        <id>https://luxmentis.org/blog/xcede-profile-switcher/</id>
        
        <content type="html" xml:base="https://luxmentis.org/blog/xcede-profile-switcher/">&lt;p&gt;Following on from &lt;a href=&quot;&#x2F;blog&#x2F;ios-and-mac-apps-in-zed&#x2F;&quot;&gt;Build, run and debug iOS and Mac apps in Zed instead of
Xcode&lt;&#x2F;a&gt;, here&#x27;s something
to make your workflow easier – or &lt;em&gt;even easier than ever&lt;&#x2F;em&gt;, as a certain fruit
company might put it.&lt;&#x2F;p&gt;
&lt;p&gt;Build settings like target device live in your project&#x27;s xcede config file,
but it&#x27;s a bit inconvenient to have to edit the file every time you want to
build and run on a different device.&lt;&#x2F;p&gt;
&lt;p&gt;With xcede&#x27;s profiles and the new profile switcher, you can switch target
devices in a couple of keystrokes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;profiles&quot;&gt;Profiles&lt;&#x2F;h2&gt;
&lt;p&gt;Profiles are named groups of settings – you&#x27;re probably familiar with the
concept. They&#x27;re handy in &lt;code&gt;xcede&lt;&#x2F;code&gt; because to switch from say a real device to
a simulator, you have to change multiple settings: &lt;code&gt;platform&lt;&#x2F;code&gt; and &lt;code&gt;device&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Profiles are best explained with an example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;ctiveProfile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Phone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;rofiles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;    M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;ac&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;latform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;ac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;    i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;Phone&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;latform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Tarquin&amp;#39;s iPhone 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;    P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;roMax Sim&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;latform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;im&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Phone 17 Pro Max&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;    i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;OS 18 Sim&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;latform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;im&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;        d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Phone 17 iOS 18.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And you may have other uses for groups of settings.&lt;&#x2F;p&gt;
&lt;p&gt;💡 Profiles like this might of course be useful across multiple projects.
Remember you can put global settings in &lt;code&gt;$HOME&#x2F;.xcede.yml&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So now you can target a different device by changing just one line in a file, but
we can do &lt;em&gt;even better&lt;&#x2F;em&gt; with some UI. Zed extensions aren&#x27;t able to have UI, so instead
we have:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-profile-switcher&quot;&gt;The Profile Switcher&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;xcede switcher&lt;&#x2F;code&gt; is a little interactive terminal menu for selecting a profile.
It looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Mac   🟢 iPhone      ProMax Sim      iOS 18 Sim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt; &lt;&#x2F;p&gt;
&lt;p&gt;🔧 You need to tell it which profiles to display:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;witcherprofiles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;ac&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Phone&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;roMax Sim&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;OS 18 Sim&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are other options, including vertical display. See &lt;code&gt;xcede help&lt;&#x2F;code&gt; for details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;next-define-a-zed-task-for-it&quot;&gt;Next, define a Zed task for it:&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Switch profile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede switcher&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;reveal&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;always&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;hide&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;on_success&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; I like this because otherwise the bottom panel is left open,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; but do whatever suits you:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;reveal_target&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;center&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;and-assign-a-key-binding&quot;&gt;And assign a key binding:&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;cmd-alt-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;task::Spawn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;task_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Switch profile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And there you have it – a hotkey that lets you switch devices in a flash. It&#x27;s
also handy if you, like me, keep forgetting which device is currently selected. Or,
with the &lt;code&gt;--keeprunning&lt;&#x2F;code&gt; option, you could even turn it into a permanent UI
element.&lt;&#x2F;p&gt;
&lt;p&gt;The profile switcher is a new feature, so don&#x27;t forget to &lt;code&gt;brew upgrade xcede&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Enjoy!&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&quot;&gt;The xcede Codeberg repo&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;@lxmn@mastodon.social&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Apple Dev Search: A search engine for Apple developer blogs</title>
        <published>2026-03-24T00:00:00+00:00</published>
        <updated>2026-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luxmentis.org/blog/appledevsearch/"/>
        <id>https://luxmentis.org/blog/appledevsearch/</id>
        
        <content type="html" xml:base="https://luxmentis.org/blog/appledevsearch/">&lt;p&gt;This isn&#x27;t new, but I&#x27;m convinced it&#x27;s useful and think it needs a boost. Also, it might be a slight
antidote to LLMs helping themselves to all our content.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;appledevsearch.com&quot;&gt;appledevsearch.com&lt;&#x2F;a&gt; is a search engine; it searches blog posts written
by people who develop for Apple platforms. Hopefully the uses are obvious: pick just about any
topic you can think of to do with iOS and macOS development and someone will have been writing about
it.&lt;&#x2F;p&gt;
&lt;p&gt;Sure, you&#x27;ll have regulars that you read, but you can&#x27;t follow everyone! When you land, there&#x27;s a list
of the latest articles from whoever&#x27;s been writing. But there&#x27;s also a great depth of past material
– just waiting there until you need to find out about a particular topic.&lt;&#x2F;p&gt;
&lt;p&gt;At the time of writing it&#x27;s searching 14989 articles across 674 blogs (including this one).&lt;&#x2F;p&gt;
&lt;p&gt;I built it a few years ago, so it&#x27;s been around for a while. Frankly I&#x27;m kind of surprised that more people don&#x27;t use it – I find it fairly useful myself. I hope people still read! Possibly it doesn&#x27;t help that I
changed the domain at some point (it used to be iosdevsearch.com).&lt;&#x2F;p&gt;
&lt;p&gt;Of course, you could use a generic search engine, but I bet you&#x27;d get more noise than you do with this.&lt;&#x2F;p&gt;
&lt;p&gt;The blog list comes from the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;iosdevdirectory.com&#x2F;&quot;&gt;iOS Dev Directory&lt;&#x2F;a&gt;, so if you write and you&#x27;re
not listed there, then you should go and sort that out. Dave has
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;iosdevweekly.com&#x2F;issues&#x2F;745&#x2F;&quot;&gt;some recent comments about the directory&lt;&#x2F;a&gt; too.&lt;&#x2F;p&gt;
&lt;p&gt;A note: there are a bunch of blog categories in the directory. Apple Dev Search indexes just one of
them: development blogs, which is material written by individuals. Of course there will be other
good stuff in other categories too, but I was finding with company blogs in particular that you
end up with a lot of content marketing. We don&#x27;t want that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Build, run and debug iOS and Mac apps in Zed instead of Xcode</title>
        <published>2026-03-14T00:00:00+00:00</published>
        <updated>2026-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luxmentis.org/blog/ios-and-mac-apps-in-zed/"/>
        <id>https://luxmentis.org/blog/ios-and-mac-apps-in-zed/</id>
        
        <content type="html" xml:base="https://luxmentis.org/blog/ios-and-mac-apps-in-zed/">&lt;p&gt;This article will get you building iOS and Mac apps in the Zed editor, with a proper build &#x2F; run &#x2F; debug cycle, on
devices and the iOS simulator. With the help of a new tool I&#x27;ve developed, this makes Zed genuinely usable for building
apps for Apple platforms. This is something of a first from what I can tell.&lt;&#x2F;p&gt;
&lt;p&gt;Out of the box, Zed comes with a Swift extension which handles plain Swift projects, but it doesn&#x27;t understand Xcode
projects.&lt;&#x2F;p&gt;
&lt;p&gt;But with a little setup, you can have a real development process:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Code completion and navigation that understands your project&lt;&#x2F;li&gt;
&lt;li&gt;Build Xcode projects just as fast as Xcode&lt;&#x2F;li&gt;
&lt;li&gt;Run iOS apps on the simulator and real devices&lt;&#x2F;li&gt;
&lt;li&gt;Run Mac apps&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;luxmentis.org&#x2F;blog&#x2F;ios-and-mac-apps-in-zed&#x2F;#debugging&quot;&gt;Debug your apps on the simulator, devices and the Mac&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;luxmentis.org&#x2F;blog&#x2F;ios-and-mac-apps-in-zed&#x2F;#running-tests&quot;&gt;Run tests right from your code, just like in Xcode&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;luxmentis.org&#x2F;blog&#x2F;ios-and-mac-apps-in-zed&#x2F;#ui-previews&quot;&gt;Use SwiftUI previews (after a fashion)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why Zed?&lt;&#x2F;strong&gt; I&#x27;ve been using the Zed editor for writing iOS and Mac apps for a while now. I won&#x27;t try and convince you
to use Zed; suffice to say I find pretty much any other modern editor is better than Xcode for actually writing code. So
I&#x27;ve been through AppCode (used it for years although it often didn&#x27;t work properly; now decommissioned), briefly looked
into VSCode (meh), used Fleet for a bit (it didn&#x27;t quite know what it was about, and now it&#x27;s been canned), and now Zed.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;used-in-the-real-world&quot;&gt;Used in the real world&lt;&#x2F;h2&gt;
&lt;p&gt;This isn&#x27;t just an article about what you could do &lt;em&gt;in theory&lt;&#x2F;em&gt; – I built my new app, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;delaydrop.app&quot;&gt;DelayDrop&lt;&#x2F;a&gt;,
mainly in Zed. It&#x27;s a pleasure to work in a genuinely good code editor, and switching into Xcode for things like
previews really isn&#x27;t an imposition.&lt;&#x2F;p&gt;
&lt;p&gt;DelayDrop is an iOS and Mac app for sending anything to your other Apple devices – even if they&#x27;re locked, off or
elsewhere – in two taps. It beats AirDrop because your other device can be anywhere in the world; and even if it &lt;em&gt;is&lt;&#x2F;em&gt;
nearby, you&#x27;re still winning because you don&#x27;t have to get up and unlock it.&lt;&#x2F;p&gt;
&lt;p&gt;And if that sounds like a plug for DelayDrop, that&#x27;s because it is!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Open your project&#x27;s folder in Zed.&lt;&#x2F;li&gt;
&lt;li&gt;Open a Swift file. Zed will offer to install the Swift extension. Do that.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now after a minute you should have basic syntax highlighting. Most of your imports won&#x27;t work yet though – so you&#x27;ll see
unresolved symbols, and code completion and command-clicking to navigate around will be pretty limited.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-xcode-build-server&quot;&gt;Install xcode-build-server&lt;&#x2F;h2&gt;
&lt;p&gt;This enhances the language server so it understands your project, which gives you code navigation and completion
and fixes syntax highlighting. (I didn&#x27;t write this tool.)&lt;&#x2F;p&gt;
&lt;p&gt;🔧 &lt;code&gt;brew install xcode-build-server&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Run &lt;code&gt;xcode-build-server config -scheme MyScheme&lt;&#x2F;code&gt; in your project directory (there are also arguments for workspace
and project if you have multiple candidates)&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Do a build in Xcode&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Restart Zed&lt;&#x2F;p&gt;
&lt;p&gt;You should now be able to command-click symbols to navigate around, and code completion should work. (This can be a
little slow at first.)&lt;&#x2F;p&gt;
&lt;p&gt;(This created a &lt;code&gt;buildServer.json&lt;&#x2F;code&gt; file in your project directory. You probably won&#x27;t look at it again, but it&#x27;s good to
know it&#x27;s there. See &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;SolaWing&#x2F;xcode-build-server&quot;&gt;xcode-build-server&#x27;s repo&lt;&#x2F;a&gt; if you want to know
more.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-xcede&quot;&gt;Install xcede&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&quot;&gt;xcede&lt;&#x2F;a&gt; to help build, run and
debug Apple platform apps from the command line. We&#x27;ll use it for our Zed tasks.
(It&#x27;s also a debug adapter; we&#x27;ll get into that soon.)&lt;&#x2F;p&gt;
&lt;p&gt;🔧 &lt;code&gt;brew tap luxmentis&#x2F;tap https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;homebrew-tap&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;🔧 &lt;code&gt;brew install xcede&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;🔧 &lt;code&gt;brew install xcbeautify&lt;&#x2F;code&gt; This is optional, but your build logs will be &lt;em&gt;much&lt;&#x2F;em&gt; easier to read.&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Now in your project&#x27;s root folder add a config file &lt;code&gt;xcede.yml&lt;&#x2F;code&gt;
(&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&#x2F;src&#x2F;branch&#x2F;main&#x2F;HELP.md&quot;&gt;you have options&lt;&#x2F;a&gt;: &lt;code&gt;[.]xcede.yml|yaml|toml|json&lt;&#x2F;code&gt;).
Something  like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;cheme&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;yApp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; device, sim or mac:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;latform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; not required for Mac apps:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;evice&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Tarquin&amp;#39;s iPhone 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; Faster builds: xcede uses Xcode to build your project via Applescript.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; If you don&amp;#39;t like this idea you can leave it out and xcede will &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; use  xcodebuild instead. That&amp;#39;s quite a lot slower, but it works just &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; as well.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;uildwithxcode&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #F5A97F);&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; There are many more options, including profiles (groups of settings) -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; which make it much easier to switch between different devices and &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; simulators for example. Also options for file naming, location and &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; format (toml, json). See `xcede help`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; Note that these options are available on the command line too, like&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; `xcede --scheme MyApp`, but a config file works better for our &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; purposes.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now try out &lt;code&gt;xcede&lt;&#x2F;code&gt; from the command line:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xcede build&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;xcede run&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;or both at once:
&lt;code&gt;xcede buildrun&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;create-zed-tasks&quot;&gt;Create Zed tasks&lt;&#x2F;h2&gt;
&lt;p&gt;You probably know by now that building and running aren&#x27;t really concepts in Zed: they&#x27;re just examples of &lt;strong&gt;&lt;em&gt;tasks&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;. Zed&#x27;s idea of a task is very generic: it&#x27;s just a way to run a command in a shell. You define tasks yourself (although some are created automagically by language plugins).&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Add this to your global tasks file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftBuild&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede build&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;allow_concurrent_runs&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #F5A97F);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;reveal&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;no_focus&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;hide&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;never&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftRun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede buildrun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;allow_concurrent_runs&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#FE640B, #F5A97F);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;reveal&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;no_focus&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;hide&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;never&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now run each of your tasks. You should get nicely formatted build output, and Zed should launch your app and show its
console output.&lt;&#x2F;p&gt;
&lt;p&gt;💡 You can command-click the file location on errors and warnings in the build log to jump to their location in code.&lt;&#x2F;p&gt;
&lt;p&gt;💡 Do you log with Apple&#x27;s unified logging system (oslog)? You need some extra settings to show that; see &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&#x2F;src&#x2F;branch&#x2F;main&#x2F;HELP.md&quot;&gt;xcede help&lt;&#x2F;a&gt;
for details.&lt;&#x2F;p&gt;
&lt;p&gt;💡 Running Mac apps? Make sure you read that section of the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&#x2F;src&#x2F;branch&#x2F;main&#x2F;HELP.md&quot;&gt;xcede help&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;add-keyboard-shortcuts-for-your-tasks&quot;&gt;Add keyboard shortcuts for your tasks&lt;&#x2F;h2&gt;
&lt;p&gt;(You&#x27;ll want to choose your own key bindings of course.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;cmd-b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;task::Spawn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;task_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftBuild&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;cmd-r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;task::Spawn&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;task_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftRun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note this is only one way of organising things.&lt;&#x2F;strong&gt; I use global tasks, defined once, and an &lt;code&gt;xcede.yml&lt;&#x2F;code&gt; for
each project. You might prefer something different, say project tasks instead with all settings as command line
arguments. Or some other variation. It&#x27;s up to you.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;bonus-basic-swift-package-support&quot;&gt;Bonus: Basic Swift package support&lt;&#x2F;h2&gt;
&lt;p&gt;If you open a Swift package rather than an Xcode project, your global build and run tasks will still work. You don&#x27;t
need &lt;code&gt;xcede.yml&lt;&#x2F;code&gt; for this.&lt;&#x2F;p&gt;
&lt;p&gt;xcede just runs plain &lt;code&gt;swift build&lt;&#x2F;code&gt; and &lt;code&gt;swift run&lt;&#x2F;code&gt;, so if you need anything more elaborate, define a project task.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;debugging&quot;&gt;Debugging&lt;&#x2F;h2&gt;
&lt;p&gt;🔧 First you need to configure zed to use xcede&#x27;s DAP wrapper. Add this your zed settings file (Settings →
Open Settings File):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;dap&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;Swift&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;binary&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&#x2F;path&#x2F;to&#x2F;xcede&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;🔧 Now define a debug task. Like our build and run tasks, this works globally and isn&#x27;t project-specific – the project
settings come from the config file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftDebug&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;adapter&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Swift&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;launch&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; This says we want xcede to manage the process.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; You could pass the path to an executable here, and that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; would just launch lldb on that executable, as if you&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; weren&amp;#39;t using xcede.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;program&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;    &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; This will build your app first, and is optional.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;build&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;SwiftBuild&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now start the debugger (Run → Start Debugger) and choose your task. Set some breakpoints and make sure it works!
You should be able to step through your code, see variables&#x27; values and the call stack, and do all the usual things.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aside: what&#x27;s going on here?&lt;&#x2F;strong&gt;
If you&#x27;re interested: the DAP (debugger adapter protocol) layer sits between the IDE and lldb. It provides a standard way for the IDE to talk about debugging: without this, IDEs would have to implement a different protocol for every debugger they talked to. Communication looks like this: IDE (Zed) → lldb-dap → lldb.&lt;&#x2F;p&gt;
&lt;p&gt;When launched without arguments, xcede runs as a DAP server. This adds &lt;em&gt;another&lt;&#x2F;em&gt; layer, so then communication looks like this: IDE (Zed) → xcede → lldb-dap → lldb. Mostly xcede passes commands straight through to lldb-dap, but it adds some useful functionality:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;With &lt;code&gt;lldb-dap&lt;&#x2F;code&gt; there&#x27;s no obvious way to attach to a process on a device without hackery with python scripts. xcede takes care of that for you.&lt;&#x2F;li&gt;
&lt;li&gt;Even so, &lt;em&gt;attaching&lt;&#x2F;em&gt; kind of sucks because you&#x27;d have two separate manual steps to do: first launch the app, then attach with the debugger. Also, its console output would be in a separate zed terminal panel. What I wanted was &lt;em&gt;launch&lt;&#x2F;em&gt;-like behaviour (like you get in Xcode). lldb can do that with a macOS executable, but not on devices&#x2F;simulators. xcede takes care of the launching, and merges the app&#x27;s console output into debugger output as you&#x27;d expect. Plus it uses &lt;code&gt;xcede.yml&lt;&#x2F;code&gt;, which is convenient.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;running-tests&quot;&gt;Running tests&lt;&#x2F;h2&gt;
&lt;p&gt;Open some test code and you should see runnable triangles in the gutter next to your tests. Out of the box these work
for Swift packages but not Xcode projects, so let&#x27;s take care of that.&lt;&#x2F;p&gt;
&lt;p&gt;🔧 Add this to your global tasks file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_CLASS test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_CLASS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;swift-xctest-class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;swift-testing-suite&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_CLASS.$ZED_CUSTOM_SWIFT_TEST_FUNC test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_CLASS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_FUNC&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    ]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;swift-xctest-func&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;swift-testing-member-func&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_FUNC test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcede&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_CUSTOM_SWIFT_TEST_FUNC&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;all&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;swift-testing-bare-func&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;🔧 Add a setting or two to &lt;code&gt;xcede.yml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;esttarget&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; M&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;yAppTests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; Depending on how you&amp;#39;ve arranged things, you might have a separate &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; scheme for your tests, in which case define this:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);font-style: italic;&quot;&gt; testscheme: MyAppTestScheme&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. Click those triangles and run some tests!&lt;&#x2F;p&gt;
&lt;p&gt;💡 If you&#x27;re using Swift Testing, annotate your test structs&#x2F;classes with @Suite, otherwise Zed won&#x27;t see them as
runnable.&lt;&#x2F;p&gt;
&lt;p&gt;💡 You can run all tests in your target with &lt;code&gt;xcede test&lt;&#x2F;code&gt;. You could create a task for that. (If your scheme contains
tests for multiple targets, you can override the &lt;code&gt;xcede.yml&lt;&#x2F;code&gt; setting like this: &lt;code&gt;xcede test --testtarget &#x27;&#x27;&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How this works:&lt;&#x2F;strong&gt; The runnables you see in Zed are created by the Swift plugin. Each one has an associated tag, and
also sets variables $ZED_CUSTOM_* for things we need to know – test class and test function. The plugin also defined
tasks to execute these runnables using &lt;code&gt;swift test&lt;&#x2F;code&gt;; here, we&#x27;re replacing the plugin&#x27;s tasks with versions that use
xcede instead.&lt;&#x2F;p&gt;
&lt;p&gt;Note that you haven&#x27;t lost the ability to run Swift package tests – if you&#x27;ve opened a package rather than an Xcode
project, xcede will see that and run the appropriate &lt;code&gt;swift test&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;ui-previews&quot;&gt;UI Previews&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s a brief video with no sound:&lt;&#x2F;p&gt;
&lt;video controls&gt;
  &lt;source src=&quot;&#x2F;zed-swiftui-previews.mp4&quot; type=&quot;video&#x2F;mp4&quot;&gt;
&lt;&#x2F;video&gt;
&lt;h4 id=&quot;wait-that-s-just-an-xcode-window-behind-a-zed-window&quot;&gt;Wait, that&#x27;s just an Xcode window behind a Zed window!&lt;&#x2F;h4&gt;
&lt;p&gt;Yes indeed. Xcode helpfully updates the preview whenever you save a file. Changes are a bit slower to
appear, but it&#x27;s actually quite usable and it&#x27;s nice staying in Zed when the situation allows.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;bonus-points-preview-a-different-file-without-leaving-zed&quot;&gt;Bonus points: preview a different file without leaving Zed&lt;&#x2F;h4&gt;
&lt;p&gt;If you were watching carefully, you&#x27;ll have noticed that I switched to working on an entirely different
app screen part way through the video.&lt;&#x2F;p&gt;
&lt;p&gt;I did that with a small shell script that I&#x27;ve named &lt;code&gt;xcode-open-file&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#EA76CB, #F5BDE6);font-style: italic;&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#EA76CB, #F5BDE6);font-style: italic;&quot;&gt;&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);font-style: italic;&quot;&gt;osascript&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#179299, #8BD5CA);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;END&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;tell application &amp;quot;Xcode&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;	open POSIX file &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E64553, #EE99A0);font-style: italic;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E64553, #EE99A0);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;end tell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;END&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and a Zed task:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#4C4F69, #CAD3F5); background-color: light-dark(#EFF1F5, #24273A);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;label&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;Open current file in Xcode&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;command&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;xcode-open-file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;$ZED_FILE&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;save&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;current&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;hide&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;always&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#1E66F5, #8AADF4);&quot;&gt;reveal&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;never&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#40A02B, #A6DA95);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#7C7F93, #939AB7);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which of course I created a key binding for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-almost-it&quot;&gt;That&#x27;s (almost) it&lt;&#x2F;h2&gt;
&lt;p&gt;Maybe it looks like a whole bunch of moving parts, but don&#x27;t be put off – most of it is one-off setup.
After that, each new project you work just needs an &lt;code&gt;xcede.yml&lt;&#x2F;code&gt; config file.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;actually-there-s-more&quot;&gt;Actually, there&#x27;s more:&lt;&#x2F;h3&gt;
&lt;p&gt;Next, check out &lt;a href=&quot;&#x2F;blog&#x2F;xcede-profile-switcher&#x2F;&quot;&gt;Make your life easier with xcede&#x27;s profile switcher&lt;&#x2F;a&gt; so you don&#x27;t have to edit the config file every time
you switch target devices. (Who says you can&#x27;t add UI to Zed!)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Here is &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&#x2F;src&#x2F;branch&#x2F;main&#x2F;HELP.md&quot;&gt;xcede&#x27;s documentation page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For bug reports or to discuss possible enhancements, you can engage with the project at &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;luxmentis&#x2F;xcede&quot;&gt;the xcede Codeberg
repo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;@lxmn@mastodon.social&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>On iOS scenes, and why your UIApplicationDelegate method isn&#x27;t being called</title>
        <published>2020-11-20T00:00:00+00:00</published>
        <updated>2020-11-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://luxmentis.org/blog/ios-scenes-uiapplicationdelegate/"/>
        <id>https://luxmentis.org/blog/ios-scenes-uiapplicationdelegate/</id>
        
        <content type="html" xml:base="https://luxmentis.org/blog/ios-scenes-uiapplicationdelegate/">&lt;p&gt;So, you&#x27;re being a good modern iOS developer and adopting scene support in your UIKit app. You&#x27;ve implemented &lt;code&gt;application(_:configurationForConnecting:options:)&lt;&#x2F;code&gt;, but it&#x27;s not being called consistently. What&#x27;s going on? Is it a bug in iOS?&lt;&#x2F;p&gt;
&lt;p&gt;In fact, things are probably behaving as they should, but this isn&#x27;t well documented and can be super confusing. Even once I started to realise what was going on, it took quite some time to get to the bottom of it all.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s all to do with &lt;em&gt;scene restoration&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-happens-when-your-app-starts&quot;&gt;What happens when your app starts&lt;&#x2F;h2&gt;
&lt;p&gt;When your app starts up after a previous launch, iOS wants to restore its windows so the user feels like they&#x27;re picking up where they left off. To do this, iOS saved the configuration details of each of your app&#x27;s scenes last time the app was run. When the app is launched again, it reads the saved scene config and recreates those scenes.&lt;&#x2F;p&gt;
&lt;p&gt;This happens even on the iPhone, where you only have one window.&lt;&#x2F;p&gt;
&lt;p&gt;Here are the various permutations at launch time, assuming you&#x27;ve implemented &lt;code&gt;application(_:configurationForConnecting:options:)&lt;&#x2F;code&gt; for some custom behaviour:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;case-1-app-launched-for-the-first-time-ever&quot;&gt;Case 1: App launched for the first time ever&lt;&#x2F;h3&gt;
&lt;p&gt;The app doesn&#x27;t know what type of scene to put in the window, and calls &lt;code&gt;application(_:configurationForConnecting:options:)&lt;&#x2F;code&gt; to find out. So far things are as we expect. (If you don&#x27;t implement this delegate method, it just falls back to the first suitable entry in your &lt;code&gt;Info.plist&#x27;s&lt;&#x2F;code&gt; scene manifest, if it has one.)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;case-2-new-window-created&quot;&gt;Case 2: New window created&lt;&#x2F;h3&gt;
&lt;p&gt;An iPad user creates a new window. The app doesn&#x27;t know what to put in this window either. This is the same as case 1.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;case-3-app-relaunched&quot;&gt;Case 3: App relaunched&lt;&#x2F;h3&gt;
&lt;p&gt;The OS wants to restore your windows. To do this, it has remembered the scene configs of the windows you had open last time. Surprise! &lt;strong&gt;&lt;em&gt;It knows what scenes to put in the windows, and doesn&#x27;t ask your app delegate.&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; It just goes ahead and creates the scenes using the remembered configs.&lt;&#x2F;p&gt;
&lt;p&gt;For the poor developer thinking in terms of a window being created when the app starts up, this is confusing. But if you think in terms of windows being &lt;em&gt;restored&lt;&#x2F;em&gt; at startup, not created – even when there is only one – it starts to make sense.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-forget-saved-windows&quot;&gt;How to forget saved windows&lt;&#x2F;h2&gt;
&lt;p&gt;During development, you might want to reset things so your windows are forgotten and your delegate method is called on next launch. To do that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;for iOS, delete the app&lt;&#x2F;li&gt;
&lt;li&gt;for Catalyst, delete the app&#x27;s container&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;restoring-content&quot;&gt;Restoring content&lt;&#x2F;h2&gt;
&lt;p&gt;This is all about restoring scene &lt;em&gt;types&lt;&#x2F;em&gt;. To be most useful to the user you might want to restore windows&#x27; &lt;em&gt;content&lt;&#x2F;em&gt; as well. Your starting point for this is &lt;code&gt;NSUserActivity&lt;&#x2F;code&gt; and the various state methods on your &lt;code&gt;UIWindowSceneDelegate&lt;&#x2F;code&gt;. Good luck.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
