<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Derived Data</title><description>A blog about Apple platforms, Swift, SwiftUI, Xcode, and related developer topics by Reda Lemeden.</description><link>https://redalemeden.com/</link><lastBuildDate>Tue, 06 Oct 2026 22:50:59 GMT</lastBuildDate><image><title>Reda Lemeden</title><url>https://redalemeden.com/icon-touch.png</url><link>https://redalemeden.com</link></image><item><title>How to Use OpenCode in Xcode 27</title><link>https://redalemeden.com/derived-data/2026/how-to-use-any-harness-with-xcode-27/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2026/how-to-use-any-harness-with-xcode-27/</guid><description>A step-by-step guide to connecting OpenCode, or any ACP-compatible coding agent, to Xcode 27&apos;s Intelligence features.</description><pubDate>Tue, 09 Jun 2026 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the most exciting announcements out of WWDC this year is support for third-party coding agents, or harnesses, in Xcode 27. Over the past couple of years, I&apos;ve used a lot of GUIs and TUIs for coding agents, but the Xcode Intelligence team has knocked it out of the park with the UI and animations, so much so that I feel, for the first time, incentivized to use it.&lt;/p&gt;
&lt;p&gt;Xcode 27 achieves this through first-class support for &lt;a href=&quot;https://agentclientprotocol.com/&quot;&gt;ACP&lt;/a&gt;-compatible coding harnesses[^1], which makes it possible to use any agent even if not officially supported by Apple. This guide uses OpenCode as an example, but the same steps apply to any ACP-compatible harness.&lt;/p&gt;
&lt;p&gt;First, we need the path to the executable. For OpenCode installed via Homebrew, that&apos;s &lt;code&gt;/opt/homebrew/bin/opencode&lt;/code&gt;. You can find it using the &lt;code&gt;which&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;which opencode
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/intelligence-settings.MnJoJbcj.png&quot; alt=&quot;Xcode Intelligence settings showing the Agents list&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In Xcode Settings, go to the &lt;em&gt;Intelligence&lt;/em&gt; tab and click &lt;em&gt;Add an Agent…&lt;/em&gt; in the &lt;em&gt;Agents&lt;/em&gt; section.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/add-agent-sheet.IYr5yyOf.png&quot; alt=&quot;Empty Add an ACP Agent sheet&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Fill in the &lt;em&gt;Name&lt;/em&gt; (anything goes) and &lt;em&gt;Executable&lt;/em&gt; fields. Leave &lt;em&gt;Interpreter&lt;/em&gt; blank unless the executable is a script.&lt;/p&gt;
&lt;p&gt;Some agents require additional arguments to enter ACP mode. For OpenCode, add &lt;code&gt;acp&lt;/code&gt; to the &lt;em&gt;Arguments&lt;/em&gt; list. See &lt;a href=&quot;#finding-the-right-arguments&quot;&gt;Finding the Right Arguments&lt;/a&gt; below if you&apos;re unsure what to put here.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/opencode-configured.CnI05SF6.png&quot; alt=&quot;Add an ACP Agent sheet filled in for OpenCode&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click &lt;em&gt;Add&lt;/em&gt;. The first time Xcode launches the agent during that session, it will ask for permission. Click &lt;em&gt;Allow&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/allow-access.yw61ZFUh.png&quot; alt=&quot;macOS permission dialog asking to allow opencode to access Xcode&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That&apos;s it. The agent is now ready to use in Xcode. In the &lt;em&gt;Intelligence&lt;/em&gt; sidebar, click &lt;em&gt;New Conversation&lt;/em&gt; and select your freshly added harness from the dropdown.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/conversation.D4JtXM8Q.png&quot; alt=&quot;Conversation sheet with OpenCode selected&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Finding the Right Arguments&lt;/h2&gt;
&lt;p&gt;Not all ACP-compatible harnesses need arguments, and many listen for ACP by default. Others, like OpenCode, require a subcommand to switch into protocol mode.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/agentclientprotocol/registry&quot;&gt;ACP registry&lt;/a&gt; lists all compliant agents. Each entry&apos;s &lt;code&gt;agent.json&lt;/code&gt; tells you exactly how to launch it. Here&apos;s OpenCode&apos;s:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;id&quot;: &quot;opencode&quot;,
  &quot;name&quot;: &quot;OpenCode&quot;,
  &quot;distribution&quot;: {
    &quot;binary&quot;: {
      &quot;darwin-aarch64&quot;: {
        &quot;cmd&quot;: &quot;./opencode&quot;,
        &quot;args&quot;: [&quot;acp&quot;]
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Find your agent&apos;s folder in the registry and open &lt;code&gt;agent.json&lt;/code&gt;. If there&apos;s an &lt;code&gt;args&lt;/code&gt; field under your platform, add those values to the &lt;em&gt;Arguments&lt;/em&gt; list in Xcode, one per line. If there&apos;s no &lt;code&gt;args&lt;/code&gt; field, leave it empty. Some agents are more finicky to set up than others, but the most popular ones are straightforward.&lt;/p&gt;
&lt;p&gt;P.S. I still haven&apos;t figured out a way to change models, but I will update this guide if I do.&lt;/p&gt;
&lt;p&gt;[^1]: A harness is a program that wraps an LLM and exposes it as a controllable coding assistant. It handles things like context, file access, shell execution, and tool calling. The combination of a harness and an LLM is what is we often call an &lt;em&gt;autonomous agent&lt;/em&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Using Xcode 27 Skills with Any Harness</title><link>https://redalemeden.com/derived-data/2026/using-xcode-27-skills-with-any-harness/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2026/using-xcode-27-skills-with-any-harness/</guid><description>Xcode 27 ships with a set of AI coding skills you can export and use with Claude Code, Codex, OpenCode, or any harness that supports the skills format.</description><pubDate>Tue, 09 Jun 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Beside &lt;a href=&quot;/derived-data/2026/what-new-in-xcode-27-mcp-bridge&quot;&gt;new MCP tools&lt;/a&gt;, the Xcode 27 beta comes with a half dozen agent skills covering topics such as SwiftUI, security, and testing. These are all available to agents used from within Xcode, but even if you use an external agent like I do, you&apos;re in for a treat as these can be exported as skill folders and used by any AI coding harness such as &lt;a href=&quot;https://claude.ai/code&quot;&gt;Claude Code&lt;/a&gt;, &lt;a href=&quot;https://opencode.ai&quot;&gt;OpenCode&lt;/a&gt;, or anything else that supports the skills format.&lt;/p&gt;
&lt;h2&gt;How to&lt;/h2&gt;
&lt;p&gt;Before exporting these skills you need to point &lt;code&gt;xcode-select&lt;/code&gt; at Xcode 27:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo xcode-select -s &amp;lt;beta-location&amp;gt;/Contents/Developer # Example: /Applications/Xcode-27.0.0-Beta.app/Contents/Developer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run from wherever you want the output to land:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xcrun agent skills export
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates an &lt;code&gt;xcode-skills/&lt;/code&gt; folder containing all the skill folders, but if you want to save these in a different folder, either global or repo-specific, use the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;xcrun agent skills export --output-dir ~/.claude/skills
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once exported, feel free to revert xcode-select to the stable version, as skills stay put regardless of which Xcode version is active afterward.&lt;/p&gt;
&lt;h2&gt;The Skills&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;swiftui-whats-new-27&lt;/code&gt;&lt;/strong&gt;: Xcode 27 SwiftUI changes such as the &lt;code&gt;@State&lt;/code&gt; macro migration, reorderable containers, and the new document model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;swiftui-specialist&lt;/code&gt;&lt;/strong&gt;: Provides broader SwiftUI guidance, including soft-deprecated patterns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;uikit-app-modernization&lt;/code&gt;&lt;/strong&gt;: Replaces &lt;code&gt;UIScreen.main&lt;/code&gt;, &lt;code&gt;interfaceOrientation&lt;/code&gt;, and other legacy shared-state APIs with multi-window-aware alternatives, in both Swift and Objective-C.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;c-bounds-safety&lt;/code&gt;&lt;/strong&gt;: Adopting C bounds-safety attributes and removing unsafe pointer usage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;test-modernizer&lt;/code&gt;&lt;/strong&gt;: Migrating test suites to current testing APIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;audit-xcode-security-settings&lt;/code&gt;&lt;/strong&gt;: Checks project security settings against current best practices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;device-interaction&lt;/code&gt;&lt;/strong&gt;: Device-specific interaction patterns.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>What&apos;s New in Xcode 27 MCP Bridge</title><link>https://redalemeden.com/derived-data/2026/what-new-in-xcode-27-mcp-bridge/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2026/what-new-in-xcode-27-mcp-bridge/</guid><description>Xcode 27 beta expands the mcpbridge catalog of tools from 21 to 48, adding deep device interaction, live debugging, crash analytics, localization support, and more.</description><pubDate>Tue, 09 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WWDC 2026 kicked off yesterday with the usual keynote, State of the Union, and beta software for those who like to live life dangerously. Xcode 27 beta is also out, and it includes a significant expansion of the &lt;code&gt;mcpbridge&lt;/code&gt; toolset. I have been using the bridge for a while in my agentic coding workflow, and this beta goes from 21 tools to 48, adding deep device interaction, live debugging, crash analytics, localization, and more. This will solve a lot of the problems I&apos;ve been patching around in my workflow, inlcuding interacting with the simulator and debugging.&lt;/p&gt;
&lt;p&gt;Here&apos;s every new tool and what it does.&lt;/p&gt;
&lt;h2&gt;Running &amp;amp; Debugging&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RunProject&lt;/strong&gt;: The biggest new addition, builds and runs the current scheme, the equivalent of pressing Cmd+R. Returns once the app has launched. Pair it with InvokeDebuggerCommand and GetConsoleOutput to drive a full debug session.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StopProject&lt;/strong&gt;: Stops the running app, the equivalent of Cmd+. Returns immediately if nothing is running.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;InvokeDebuggerCommand&lt;/strong&gt;: Sends any lldb command to Xcode&apos;s active debug session and returns the output. The process must already be running with the debugger attached. Supports the full lldb surface: &lt;code&gt;bt&lt;/code&gt;, &lt;code&gt;po&lt;/code&gt;, &lt;code&gt;breakpoint set&lt;/code&gt;, &lt;code&gt;thread step-over&lt;/code&gt;, &lt;code&gt;frame variable&lt;/code&gt;, etc. The agent and Xcode UI share the same lldb session, so state is consistent on both sides.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GetConsoleOutput&lt;/strong&gt;: Retrieves stdout, stderr, and OSLog output from a running or completed app session. Supports regex filtering, severity filtering, and context extraction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RunCodeSnippet&lt;/strong&gt; &lt;em&gt;(replaces ExecuteSnippet)&lt;/em&gt;: Builds and runs a code snippet in the context of a specific source file and waits for results. Returns the output of any &lt;code&gt;print&lt;/code&gt; statements in the snippet. Works for app, framework, library, and command-line targets.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Device Interaction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DeviceInteractionStartSession&lt;/strong&gt;: Prepares a simulator or physical device for interaction and boots it if needed. Designed to be called early so the device is ready in parallel with other work. Keeping a session open is expensive, so always close it when done.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeviceInteractionEndSession&lt;/strong&gt;: Closes an open device session. Must be called when interaction is finished.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeviceInteractionInstallAndRun&lt;/strong&gt;: Builds, installs, and launches the app on the currently targeted device. Should be called every time the project changes, the target device changes, or the previous debug session has disconnected.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeviceInteractionSynthesize&lt;/strong&gt;: Synthesizes device events: taps, swipes, text input, hardware button presses, orientation changes, etc. then captures the resulting state as a screenshot and UI hierarchy. Always base coordinates on the latest hierarchy dump, not a screenshot.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Crash Reporting &amp;amp; Field Performance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GetTopCrashIssues&lt;/strong&gt;: Pulls the top crash signatures for an app from Apple&apos;s crash reporting service, sorted by number of affected devices over the last 14 days. Supports filtering by platform, version, and release channel (App Store vs. TestFlight).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GetCrashIssueLogs&lt;/strong&gt;: Drills into a specific crash signature to retrieve raw crash logs plus expert triage analysis and actionable recommendations. Use after GetTopCrashIssues.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GetTopFieldPerformanceIssues&lt;/strong&gt;: Surfaces the top performance regressions from Apple&apos;s field report APIs. Covers four diagnostic types: &lt;code&gt;launches&lt;/code&gt;, &lt;code&gt;hangs&lt;/code&gt;, &lt;code&gt;diskwrites&lt;/code&gt;, and &lt;code&gt;energy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GetFieldPerformanceIssueLogs&lt;/strong&gt;: Retrieves detailed diagnostics for a specific performance issue: stack traces, timeline data, and expert triage guidance. Use after GetTopFieldPerformanceIssues.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Build Settings &amp;amp; Compiler Flags&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GetTargetBuildSettings&lt;/strong&gt;: Returns all build settings for a given target. The canonical way to inspect build settings instead of parsing &lt;code&gt;project.pbxproj&lt;/code&gt; directly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UpdateTargetBuildSetting&lt;/strong&gt;: Updates, appends, or deletes a named build setting for a target. Same caveat: always use this tool instead of editing &lt;code&gt;project.pbxproj&lt;/code&gt; directly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GetFileCompilerFlags&lt;/strong&gt;: Gets the per-file compiler flags for a single source file in a target: the value shown in the Compiler Flags column of Build Phases &amp;gt; Compile Sources.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UpdateFileCompilerFlags&lt;/strong&gt;: Updates, appends, or deletes per-file compiler flags for a single source file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Schemes &amp;amp; Run Destinations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XcodeListSchemes&lt;/strong&gt;: Lists all schemes in the current workspace with their sharing status and container. Active scheme is listed first. Full list is written to a file for grep-friendly access.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XcodeSwitchScheme&lt;/strong&gt;: Switches the active scheme by name or disambiguated name.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XcodeListRunDestinations&lt;/strong&gt;: Lists available run destinations for the active scheme, grouped the same way the Xcode picker does (Devices, Simulators, Build, Incompatible). Identifies the active destination. Incompatible destinations are omitted by default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XcodeSwitchRunDestination&lt;/strong&gt;: Changes the active run destination for the current scheme. Pass the destination&apos;s &lt;code&gt;displayTitle&lt;/code&gt; from XcodeListRunDestinations. Refuses destinations that aren&apos;t eligible for the active scheme.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Project Configuration&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AddEntitlement&lt;/strong&gt;: Adds a new entitlement to the project&apos;s entitlements file for a given target. Only for restricted system capabilities gated by code signing—push notifications, app groups, iCloud, hardware access, etc. Not for standard frameworks, privacy descriptions, or general feature flags. Use AddInfoPlist for privacy descriptions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AddInfoPlist&lt;/strong&gt;: Adds or updates an Info.plist key (privacy usage descriptions, URL schemes, background modes, orientation settings, app metadata, etc.) Not for entitlements.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Localization&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;StringCatalogRead&lt;/strong&gt;: Returns string keys grouped by translation state for a requested locale. Requires the &lt;code&gt;xcode-integration:translation-coordinator&lt;/code&gt; skill to be active before calling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StringCatalogContext&lt;/strong&gt;: Returns the source language value and context for a given string in the String Catalog. Requires the &lt;code&gt;xcode-integration:translation&lt;/code&gt; skill.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;StringCatalogEdit&lt;/strong&gt;: Inserts a translation for a given locale into the String Catalog. Requires the &lt;code&gt;xcode-integration:translation&lt;/code&gt; skill.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LocalizationPlanner&lt;/strong&gt;: Ensures the project is ready for translations to be added. Call this each time you&apos;re adding a new language or translating an entire project. Requires the &lt;code&gt;xcode-integration:translation-coordinator&lt;/code&gt; skill.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether the agent runs standalone or inside Xcode through &lt;a href=&quot;https://agentclientprotocol.com/get-started/introduction&quot;&gt;ACP&lt;/a&gt;, the new tools close the loop that previously required reaching out to &lt;code&gt;simctl&lt;/code&gt; and friends just to run and poke at the app to verify their work. &lt;code&gt;DeviceInteractionSynthesize&lt;/code&gt; alone eliminates a whole class of workarounds. &lt;code&gt;GetConsoleOutput&lt;/code&gt; is similarly welcome, since pulling logs directly instead of switching windows and copy-pasting saves more time than it sounds once you&apos;re doing it dozens of times a session.&lt;/p&gt;
</content:encoded></item><item><title>A Feel-Good Refactor</title><link>https://redalemeden.com/derived-data/2021/a-feel-good-refactor/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2021/a-feel-good-refactor/</guid><pubDate>Sun, 21 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are using Combine&apos;s &lt;code&gt;Just&lt;/code&gt;, &lt;code&gt;Fail&lt;/code&gt;, or &lt;code&gt;Result.publisher&lt;/code&gt; as much as I do
to mock publishers for SwiftUI&apos;s previews and tests, chances are you have grown
tired of manually setting either the output or the failure types, then erasing
to &lt;code&gt;AnyPublisher&lt;/code&gt; in every occurrence.&lt;/p&gt;
&lt;p&gt;Today I decided that it was time to honor the rule of three (or &lt;em&gt;thirty eight&lt;/em&gt;?)
and come up with something better. For one, we can heavily lean on Swift&apos;s &lt;a href=&quot;https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID322&quot;&gt;type inference&lt;/a&gt;
to improve the API at the call site. And while we&apos;re at it, we can make it
easier to remember by using a similar syntax to handle both success and failure
scenarios.&lt;/p&gt;
&lt;p&gt;Since the goal here is to create a type-erased publisher that emits either a value
or an error then completes, we can call the helper &lt;em&gt;&quot;once&quot;&lt;/em&gt;. As for the
implementation, we have a couple of options: define a static function on
&lt;code&gt;Publisher&lt;/code&gt;, or create a custom &lt;code&gt;Publisher&lt;/code&gt; type. Since the latter would still
require type-erasure at the call site, I chose to go with the former.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with the far more common value-emitting path.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public extension Publisher {
  static func once&amp;lt;T, U: Error&amp;gt;(
   _ value: T,
    failAs error: U.Type // 1
  ) -&amp;gt; AnyPublisher&amp;lt;T, U&amp;gt; {
    Just(value)
      .setFailureType(to: U.self)
      .eraseToAnyPublisher()
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This does the job, but having to specify the error type (1) every time takes
away some of the &lt;em&gt;feel-goodness&lt;/em&gt; of this solution. Luckily, Swift&apos;s type
inference comes to the rescue. Time for take 2!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static func once&amp;lt;T, U: Error&amp;gt;(
  _ value: T
) -&amp;gt; AnyPublisher&amp;lt;T, U&amp;gt; {
  Just(value)
    .setFailureType(to: U.self)
    .eraseToAnyPublisher()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The type of the return value should be enough to identify the publisher&apos;s
failure type. For cases where there isn&apos;t enough type information at the call
site, we can keep the first iteration around to avoid the need for explicit
types when assigning values—but that&apos;s purely a matter of preference.&lt;/p&gt;
&lt;p&gt;With the happy path case behind us, let&apos;s do the same for the failure-emitting
case.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static func once&amp;lt;T, U: Error&amp;gt;( // 1
  failing error: U // 2
) -&amp;gt; AnyPublisher&amp;lt;T, U&amp;gt; {
  Fail(
    outputType: T.self,
    failure: error
  )
  .eraseToAnyPublisher()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I chose to keep the same method name (1) to streamline the API at the call site.
Unfortunately this means an additional keyword is needed to help the compiler
tell them apart. I went with &lt;code&gt;failing&lt;/code&gt; (2) on the spur of the moment, but
anything would do the job. If call site uniformity is a non-goal, then using
&lt;code&gt;just&lt;/code&gt;/&lt;code&gt;fail&lt;/code&gt; to match the Combine publishers would be preferable.&lt;/p&gt;
&lt;p&gt;As a parting bonus, we can throw in an additional helper for publishers where
the output value is &lt;code&gt;Void&lt;/code&gt;; quite common for write operations and &lt;code&gt;PUT&lt;/code&gt;/&lt;code&gt;DELETE&lt;/code&gt;
endpoints.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;static func once&amp;lt;U: Error&amp;gt;() -&amp;gt; AnyPublisher&amp;lt;Void, U&amp;gt; {
  once((), failAs: U.self)
}

static func once&amp;lt;U: Error&amp;gt;(
  failing error: U
) -&amp;gt; AnyPublisher&amp;lt;Void, U&amp;gt; {
  once(Void.self, failing: error)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Armed with these new tools, mocking publishers is now as easy as calling
&lt;code&gt;once()&lt;/code&gt; and &lt;code&gt;once(failing:)&lt;/code&gt; with the value or error respectively.&lt;/p&gt;
&lt;p&gt;Here&apos;s an example from the codebase that prompted me to write this post:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let cache = Cache(
  upsert: { value in // -&amp;gt; AnyPublisher&amp;lt;Value, CachingError&amp;gt;
    Just(value)
      .setFailureType(to: CachingError.self)
      .eraseToAnyPublisher()
  },
  deleteOutdated: { // -&amp;gt; AnyPublisher&amp;lt;Int, CachingError&amp;gt;
    Just(2)
      .setFailureType(to: CachingError.self)
      .eraseToAnyPublisher()
  },
  deleteAll: { // -&amp;gt; AnyPublisher&amp;lt;Int, CachingError&amp;gt;
    Fail(
      outputType: Int.self,
      failure: CachingError.nothingToDelete
    )
  }
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is the same section after the refactor:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let cache = Cache(
  upsert: { .once($0) }, // (Item) -&amp;gt; AnyPublisher&amp;lt;Value, Error&amp;gt;
  deleteOutdated: { .once(2) }, // () -&amp;gt; AnyPublisher&amp;lt;Int, Error&amp;gt;
  deleteAll: { .once(failing: .nothingToDelete) } // () -&amp;gt; AnyPublisher&amp;lt;Int, Error&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, tell me which scores higher in the &lt;em&gt;feel-good&lt;/em&gt; department?&lt;/p&gt;
</content:encoded></item><item><title>Debugging SwiftUI: Trials and Tribulations</title><link>https://redalemeden.com/derived-data/2020/debugging-swiftui-trials-and-tribulations/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2020/debugging-swiftui-trials-and-tribulations/</guid><pubDate>Fri, 30 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have been using &lt;a href=&quot;https://developer.apple.com/xcode/swiftui/&quot;&gt;SwiftUI&lt;/a&gt; since
day one, on both client and side projects. It&apos;s an incredibly refreshing way of
coding interfaces for Apple devices, but it&apos;s far from being wrinkle-free. The
framework&apos;s bold ambitions are sometimes hampered by subpar debugging tools and
arcane, seemingly random limitations.&lt;/p&gt;
&lt;p&gt;I previously
&lt;a href=&quot;https://redalemeden.com/blog/2020/this-week-i-learned-24#programming&quot;&gt;wrote&lt;/a&gt;
about a SwiftUI bug that gave me quite a run for my money:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The stack trace isn’t of much help and no amount of view hierarchy tweaks got
rid of it entirely. Initially I was under the impression that either my code
or one of my external dependencies were doing something horribly wrong, but
&lt;a href=&quot;https://steipete.com/posts/state-of-swiftui/&quot;&gt;this post&lt;/a&gt; from Peter
Steinberger made me realize that it is a rather widespread issue.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since I didn’t manage to reproduce it on a particular test device at the time, I
assumed it’s yet another simulator quirk. But a little over a month later, the
same bug reared its ugly head on a test device. Fun times!&lt;/p&gt;
&lt;p&gt;The app in question uses tab navigation where the first tab is always
accessible, while the second tab shows different content depending on whether
the user is signed in to their account or not. The view code looked roughly like
this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TabView {
  Home()
    .tabItem { /* ... */ }
    .tag { /* ... */ }

  if isSignedIn {
    Profile()
      .tabItem { /* ... */ }
      .tag { /* ... */ }
  } else {
    SignIn()
      .tabItem { /* ... */ }
      .tag { /* ... */ }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To avoid the &lt;code&gt;isSignedIn&lt;/code&gt; boolean check in multiple modifiers, I opted for an
&lt;code&gt;if-else&lt;/code&gt; block with separate views and &lt;code&gt;tabItem&lt;/code&gt; modifiers.[^1] Except that
didn’t seem to sit right with SwiftUI for some reason. The app launches and
displays the content of the first tab exactly as intended. But when I switch
tabs—or god forbid, sign in or out—the app crashes with this cryptic error
message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[error] precondition failure: invalid size for indirect attribute: &amp;lt;number&amp;gt; vs &amp;lt;number&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The call stack points exclusively to SwiftUI internals, with the last call
referring to a certain
&lt;code&gt;AG::Graph&lt;/code&gt;—&lt;a href=&quot;https://steipete.com/posts/state-of-swiftui/#swiftui-attributegraph-crashes&quot;&gt;responsible&lt;/a&gt;
for holding the view tree and diffing it. As far as debugging goes, this is
very, &lt;em&gt;very&lt;/em&gt; little to work with.&lt;/p&gt;
&lt;p&gt;With my hands tied, I briefly considered resurrecting the &lt;code&gt;UITabBarController&lt;/code&gt;
wrapper I used prior to WWDC, especially since I didn’t manage to make a
reproducible test case or submit a feedback to Apple. At first, I spent an
inordinate amount of time tweaking the view hierarchies of the profile and
sign-in screens themselves, with varying—and rather inconsistent—levels of
success. I ran out of both time and patience, so I moved on to other things to
not stall the project any further. Weeks later, I came back to the problematic
screen—pitchfork in hand—ready to gut the entire tab navigation and replace it
with a custom-made solution. I had had enough.&lt;/p&gt;
&lt;p&gt;But then came the proverbial aha moment: what if the conditional check took
place &lt;em&gt;inside&lt;/em&gt; the second tab, instead of &lt;em&gt;around&lt;/em&gt; it?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TabView {
  Home()
    .tabItem { /* ... */ }
    .tag { /* ... */ }

  ProfileOrSignIn(isSignedIn: $isSignedIn)
    .tabItem { /* ... */ }
    .tag { /* ... */ }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And &lt;em&gt;just&lt;/em&gt; like that, the crasher was gone. Squashed into oblivion.&lt;/p&gt;
&lt;p&gt;If this sounds dumb, it’s because it is. At no point did the compiler chastise
me for doing something I wasn&apos;t supposed to do. And to make matters worse, the
documentation doesn&apos;t mention anything related to... wait, what documentation?&lt;/p&gt;
&lt;p&gt;It’s a bittersweet feeling when you fix a bug in a non-deterministic, haphazard
way. On one hand you are elated you’ve managed to fix it at all. On the other,
you feel somewhat powerless and insecure about your ability to handle similar
situations in the future. I adore SwiftUI, but moments like these give me a good
dose of anticipatory anxiety—the kind that erodes trust and dampens the thrill of
being at the bleeding edge.&lt;/p&gt;
&lt;p&gt;[^1]:
As an aside, apps that greet users with a sign up screen are generally
trash. You don&apos;t ask prospective tenants to sign the contract at the door
before they&apos;ve even seen the apartment.&lt;/p&gt;
</content:encoded></item><item><title>How I Use Document Tabs in Xcode 12</title><link>https://redalemeden.com/derived-data/2020/xcode-12-document-tabs/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2020/xcode-12-document-tabs/</guid><pubDate>Thu, 03 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The new &lt;em&gt;document tabs&lt;/em&gt; in Xcode 12 caught me off-guard more than once at first,
but as soon as I figured out how they work, I started to enjoy using them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/xcode-12.CnfhWXrm.jpg&quot; alt=&quot;The new document tabs in Xcode 12.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For instance, in server-side projects I am typically dealing with half a dozen
files related to the same area or feature; the model itself, the repository,
migrations, tests, mocks, etc. Before, I used separate window tabs for each
&quot;topic&quot;, but now I rely heavily on document tabs to fill that need. My current
setup is something roughly like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I usually keep 3 window tabs in every project: &lt;em&gt;development&lt;/em&gt;, &lt;em&gt;testing&lt;/em&gt;, and
&lt;em&gt;debugging&lt;/em&gt;. I occasionally create break-out window tabs for self-contained
tasks like refactoring, reading the source code of a dependency, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the development window tab, I use vertical area splits for the different
topics I am actively working on. Usually these correspond to a model file and
its satellite types. I start with one then add or remove splits as needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside each area, I use the new &lt;em&gt;document tabs&lt;/em&gt; to keep all the related files
open, enabling quick tab switching using the keyboard shortcut &amp;lt;kbd&amp;gt;cmd&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;shift&amp;lt;/kbd&amp;gt; + &amp;lt;kbd&amp;gt;[&amp;lt;/kbd&amp;gt; or &amp;lt;kbd&amp;gt;]&amp;lt;/kbd&amp;gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I use horizontal splits when I need to look at different files in the same
topic. An example would be the model and its migration file in server-side, or
a view and its state object in SwiftUI.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I reason better about code when I can see several related files at the same
time, and document tabs give me an even more effective way to achieve that.&lt;/p&gt;
</content:encoded></item><item><title>Mattt on WWDC 2020</title><link>https://redalemeden.com/derived-data/2020/mattt-wwdc-2020/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2020/mattt-wwdc-2020/</guid><pubDate>Sun, 28 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s refreshing to see &lt;a href=&quot;https://nshipster.com/wwdc-2020/&quot;&gt;Mattt&apos;s reasoned take&lt;/a&gt;
amidst all the attention-seeking headlines this week:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As it turns out, going fully remote wasn’t merely good enough — it was, in
many ways, superior to the original thing. [...] Sessions are tight and
well-paced. Rather than stretching or cramming content into a fixed time slot,
they’re as long as they need to be.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This definitely echoes my impressions. As someone who mostly followed along from
home in the past, not only did I not miss much this year, but I got treated to a
much improved remote experience.&lt;/p&gt;
&lt;p&gt;Mattt also brings up the topic of Excitement—or &lt;em&gt;hype&lt;/em&gt;, as I often call it—and
productivity:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here’s the thing about excitement: It’s kryptonite to developers. Excitement
messes with our ability to focus on one thing, which is already a big struggle
for a lot of us (myself included). When you’re excited, it’s almost impossible
to get anything done.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is true for any endeavor, but especially so for software development.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are plenty of voices in the community who are echoing this excitement. I
can’t add anything to that discussion. And besides, that’s not really where my
head’s at right now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The official Apple content generates enough sense of &amp;lt;abbr title=&quot;Fear of
Missing Out&quot;&amp;gt;FOMO&amp;lt;/abbr&amp;gt; as it is. Combining that with a firehose of &lt;em&gt;What&apos;s new
in X&lt;/em&gt; blog posts, podcasts, YouTube videos, and tweets doesn&apos;t help much as far
as I am concerned.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s been an exciting week, so take a moment to collect yourself. Go on a
walk. Take a hike. (Be safe about it.) Do whatever you need to break free of
the “reality distortion field”. Once you do, you’ll have the necessary
distance to determine what new technologies you should pay attention to and
what you can ignore for now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Solid advice, WWDC or otherwise.&lt;/p&gt;
</content:encoded></item><item><title>Early Lessons in Adopting SwiftUI</title><link>https://redalemeden.com/derived-data/2019/swift-ui-early-lessons/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2019/swift-ui-early-lessons/</guid><pubDate>Fri, 02 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We&apos;ve been using SwiftUI day in and day out since the first beta to build a
non-trivial app at work---a bold move, but one that makes me like my job. Here
are some lessons I&apos;ve learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stick to standard navigation. As unstable as the APIs are for the time being,
this will spare you the layout and accessibility headaches that come with
custom transitions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Always investigate whether your UI can be implemented as a list view. It
handles dynamic type, dark mode, and other accessibility features out of the
box, and will likely look more polished as a result.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make good use of section headers and footers in &lt;code&gt;List&lt;/code&gt;. Unlike &lt;code&gt;UITableView&lt;/code&gt;,
these are much easier to set up in SwiftUI&apos;s declarative syntax. They can be
used for empty states, search fields, sorting controls, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Embrace the current limitations of the framework. If you have to fight it at
every turn to get the result you want, consider taking a different route where
you don&apos;t have to do that. You can revisit the same challenge later as the
framework matures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t use hard coded colors, i.e. the RGB initializer. Use system tint colors
or asset catalogs instead, and stay clear of white and black as they don&apos;t
adapt to appearance modes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pay attention to the methods used to pass data down to and up from subviews.
It’s easy to use the wrong method and the error won’t be very helpful. Spend
some time to understand the difference between &lt;code&gt;@State&lt;/code&gt;, &lt;code&gt;@Binding&lt;/code&gt;,
&lt;code&gt;@ObservedObject&lt;/code&gt;, and &lt;code&gt;@EnvironmentObject&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of compiler errors, split your view hierarchy using variables,
methods, and separate view structs to make the wide of the mark error messages
slightly more relevant and helpful.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extract reoccurring view modifier chains into custom modifiers to DRY up the
code. It&apos;s a bit more work that I anticipated, but it&apos;s worth it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UIKit appearance helpers still work in SwiftUI. Call them from within the
&lt;code&gt;init()&lt;/code&gt; method of the view when needed. For instance, this is the only method
to remove the opaque background from a &lt;code&gt;List&lt;/code&gt; as of now.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SwiftUI is still very rough around the edges, so keep your cool and stay
hydrated.🥤&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Swift&apos;s Killer Feature</title><link>https://redalemeden.com/derived-data/2019/swift-killer-feature/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2019/swift-killer-feature/</guid><pubDate>Tue, 18 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since its release 5 years ago, Swift has matured a great deal as a programming
language, both in terms of stability and expressive power. Its concise syntax
and type safety have been largely celebrated within the Apple developer
community, and increasingly noticed outside of it. But, as it is the case with
similar transitions, not everything is hunky-dory.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://redalemeden.com/_astro/header-image.BQS9n3vV.jpg&quot; alt=&quot;SwiftUI&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In addition to the source breaking changes that soured the language earlier on,
Swift is often criticized for lacking an indisputable selling point compared to
what was there before it (Cocoa and Objective-C), and what came after it
(JavaScript cross-platform frameworks).&lt;/p&gt;
&lt;p&gt;Unfair as it may sound, programming languages are often evaluated based on their
ecosystem, not on their intrinsic merits. In the eyes of many, Swift is
indissociable from Apple and their platform UI frameworks, for better or for
worse. The mismatch between Cocoa APIs and Swift language features has been
brought up again and again in discussions about its appeal as a replacement for
Objective-C.&lt;/p&gt;
&lt;p&gt;Expressiveness and type safety can certainly keep a handful of enthusiastic
developers engaged, but it won’t be enough to sustain Swift’s momentum on the
long run. As much as some of us hate to admit, the competition is colossal on
the server and scripting side of things, and it’s getting uncomfortably stronger
on the native platform front.&lt;/p&gt;
&lt;p&gt;On top of that, the &lt;em&gt;write-preview-debug&lt;/em&gt; development cycle that we’ve been
dealt since the dawn of Cocoa is considered sluggish and tedious by today’s
standards. A liability that’s long overdue for reconsideration. To make matters
worse, Apple&apos;s UI frameworks haven’t converged fast enough to alleviate some of
these issues---we are still required to implement half a dozen methods for each
platform to display a plain table view.&lt;/p&gt;
&lt;p&gt;This state of affairs has pushed many to adventure outside first-party fences in
search of more exotic alternatives, while the holdouts stuck to their &lt;s&gt;guns&lt;/s&gt;
bows and arrows in the absence of a clear-cut perk of leaving their
tried-and-true programming language behind[^1].&lt;/p&gt;
&lt;p&gt;But all of this is bound to change.&lt;/p&gt;
&lt;p&gt;During this past WWDC, Apple introduced
&lt;em&gt;&lt;a href=&quot;https://developer.apple.com/xcode/swiftui/&quot;&gt;SwiftUI&lt;/a&gt;&lt;/em&gt;---a modern, universal
framework for building user interfaces across their platforms. And it’s &lt;em&gt;packing
quite a punch.&lt;/em&gt; SwiftUI is declarative, reactive, and ready to take us places;
the killer feature that Swift &lt;em&gt;deserved&lt;/em&gt; all along. Not only is it tightly
integrated with the language, but it’s also pushing it forward by providing a
use case for new additions such as &lt;a href=&quot;https://github.com/apple/swift-evolution/blob/9992cf3c11c2d5e0ea20bee98657d93902d5b174/proposals/XXXX-function-builders.md&quot;&gt;function builders&lt;/a&gt;
and &lt;a href=&quot;https://github.com/DougGregor/swift-evolution/blob/property-wrappers/proposals/0258-property-wrappers.md&quot;&gt;property wrappers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even though we have barely scratched the surface of SwiftUI since its
announcement, it’s already winning the hearts of large swaths of developers,
myself included. I don&apos;t have a shred of doubt that this is the future of UI
programming on Apple platforms, and I am thrilled to witness, and be part of,
this transition.&lt;/p&gt;
&lt;p&gt;[^1]:
Part of me appreciates the prudent approach with regard to adopting new
technology that’s yet to prove itself. Another part of me fails to see the
point of swimming against the current in a predominantly closed platform
where a single company gets to call the shots.&lt;/p&gt;
</content:encoded></item><item><title>Units in Foundation</title><link>https://redalemeden.com/derived-data/2016/units-in-foundation/</link><guid isPermaLink="true">https://redalemeden.com/derived-data/2016/units-in-foundation/</guid><pubDate>Sun, 04 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Starting iOS 10 and macOS 10.12, &lt;em&gt;Foundation&lt;/em&gt; supports units and measurements
out of the box, in the form of
&lt;a href=&quot;https://developer.apple.com/reference/foundation/unit&quot;&gt;(NS)Unit&lt;/a&gt; and
&lt;a href=&quot;https://developer.apple.com/reference/foundation/nsmeasurement&quot;&gt;(NS)Measurement&lt;/a&gt;
respectively. Let&apos;s take a look at how they work.&lt;/p&gt;
&lt;p&gt;Note: All code snippets below are written in &lt;strong&gt;Swift 3.0&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To get started, let&apos;s define a measurement. To do that, you have to pass a
&lt;em&gt;value&lt;/em&gt; and a &lt;em&gt;unit&lt;/em&gt; to the initializer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Foundation

let snorlaxWeight = Measurement(value: 460, unit: UnitMass.kilograms)
// -&amp;gt; 460.0 kg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can then effortlessly convert the measurement to another unit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let snorlaxWightInImperial = snorlaxWeight.converted(to: .pounds)
// -&amp;gt; 1014.12723328454 lb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also define your own unit by extending one of the default
&lt;a href=&quot;https://developer.apple.com/reference/foundation/dimension&quot;&gt;&lt;em&gt;dimensions&lt;/em&gt;&lt;/a&gt;
available:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;extension UnitMass {
  static let snorlax = UnitMass(symbol: &quot;snorlax&quot;, converter: UnitConverterLinear(coefficient: 460))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The converter is used to transform the measurement from any given unit to the
base unit of the dimension; Kilograms in the case of &lt;code&gt;UnitMass&lt;/code&gt;. You can inspect
the base unit of any dimension by calling &lt;code&gt;baseUnit()&lt;/code&gt; on it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UnitMass.baseUnit()
// -&amp;gt; kg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once defined, your custom unit can be used alongside the pre-defined ones:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let statueOfLibertyMass = Measurement(value: 225_000, unit: UnitMass.kilograms)
let statueOfLibertyMassInSnorlax = statueOfLibertyMass.converted(to: .snorlax)
// -&amp;gt; 489.130434782609 snorlax
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also define a custom dimension of units by subclassing &lt;code&gt;Dimension&lt;/code&gt; if
necessary. Here is an example that defines a new &lt;code&gt;UnitDataRate&lt;/code&gt; class for
measuring data transfer rates, often used in Internet speed tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class UnitDataRate: Dimension {
  static let kilobitPerSecond = UnitDataRate(symbol: &quot;kbps&quot;, converter: UnitConverterLinear(coefficient: 1))
  static let megabitPerSecond = UnitDataRate(symbol: &quot;Mbps&quot;, converter: UnitConverterLinear(coefficient: 1_000))
  static let gigabitPerSecond = UnitDataRate(symbol: &quot;Gbps&quot;, converter: UnitConverterLinear(coefficient: 1_000_000))

  override class func baseUnit() -&amp;gt; UnitDataRate {
    return .megabitPerSecond
  }
}

let speed = Measurement(value: 100, unit: UnitDataRate.megabitPerSecond)
let speedInKpbs = speed.converted(to: .kilobitPerSecond)

// -&amp;gt; 100000 kbps
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Learn More&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/videos/play/wwdc2016/238/&quot;&gt;WWDC session 238&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oleb.net/blog/2016/07/measurements-and-units/&quot;&gt;Measurements and Units in Foundation&lt;/a&gt; by Ole
Begemann.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://videos.raywenderlich.com/screencasts/ios-10-measurements-units&quot;&gt;iOS 10: Measurements &amp;amp; Units Screencast&lt;/a&gt;
by Sam Davies.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item></channel></rss>