<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Version 1.8.1 on RawCull</title><link>https://rawcull.netlify.app/tags/version-1.8.1/</link><description>Recent content in Version 1.8.1 on RawCull</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 17 May 2026 06:55:48 +0200</lastBuildDate><atom:link href="https://rawcull.netlify.app/tags/version-1.8.1/index.xml" rel="self" type="application/rss+xml"/><item><title>Version 1.8.1</title><link>https://rawcull.netlify.app/blog/2026/05/16/version-1.8.1/</link><pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/05/16/version-1.8.1/</guid><description>&lt;h1 id="rawcull-changelog--v180--181"&gt;RawCull Changelog — v1.8.0 → 1.8.1&lt;a class="td-heading-self-link" href="#rawcull-changelog--v180--181" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Updated on &lt;a href="https://apps.apple.com/no/app/rawcull/id6759362764?mt=12"&gt;Apple App Store&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A stability and resource-hygiene release. Focus is on eliminating main-thread hangs in the zoom preview, tightening security-scoped resource lifecycles, and fixing
actor-isolation gaps in the rsync copy path.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="-security-scoped-resource-lifecycle"&gt;🔒 Security-Scoped Resource Lifecycle&lt;a class="td-heading-self-link" href="#-security-scoped-resource-lifecycle" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Catalog access is now scoped to the &lt;em&gt;active&lt;/em&gt; catalog&lt;/strong&gt;, not every catalog ever opened in the sidebar. Long sessions no longer accumulate stale security-scoped accesses.&lt;/li&gt;
&lt;li&gt;Added explicit &lt;code&gt;startSecurityScopedAccess(for:)&lt;/code&gt;, &lt;code&gt;stopSecurityScopedAccess(for:)&lt;/code&gt;, and &lt;code&gt;stopActiveSecurityScopedAccess()&lt;/code&gt; on &lt;code&gt;RawCullViewModel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Catalog cancellation and app shutdown both route through the same cleanup path; &lt;code&gt;deinit&lt;/code&gt; is now a last-resort fallback rather than the primary stop point.&lt;/li&gt;
&lt;li&gt;Picker flow simplified — view no longer manually pairs start/stop calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-zoom-preview--no-more-main-thread-hangs"&gt;⚡ Zoom Preview — No More Main-Thread Hangs&lt;a class="td-heading-self-link" href="#-zoom-preview--no-more-main-thread-hangs" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ZoomPreviewHandler&lt;/code&gt; sidecar JPG decode moved &lt;strong&gt;off the MainActor&lt;/strong&gt; into a &lt;code&gt;Task.detached(priority: .userInitiated)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Opening the zoom overlay on a large Sony JPEG no longer blocks the UI while ImageIO opens and decodes the file.&lt;/li&gt;
&lt;li&gt;Cancellation is now checked between every async step, so dismissing the overlay early stops in-flight work cleanly.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loadCGImage(from:)&lt;/code&gt; and the disk-cache accessor are marked &lt;code&gt;nonisolated&lt;/code&gt; to make the off-main path explicit.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-rsync-copy-path-executecopyfiles"&gt;🛠️ Rsync Copy Path (&lt;code&gt;ExecuteCopyFiles&lt;/code&gt;)&lt;a class="td-heading-self-link" href="#-rsync-copy-path-executecopyfiles" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Security-scoped URLs for source and destination are now paired with a single, idempotent &lt;code&gt;cleanup()&lt;/code&gt; call covering: rsync success, launch failure, user close/cancel, sheet dismissal, and &lt;code&gt;deinit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Progress streaming callback hops to &lt;code&gt;@MainActor&lt;/code&gt; before touching &lt;code&gt;progressContinuation&lt;/code&gt;, removing a latent actor-isolation race that strict concurrency would flag.&lt;/li&gt;
&lt;li&gt;Progress continuations and streaming handler state are finished/cleared exactly once.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-catalog-loading--cancellation"&gt;🧵 Catalog Loading &amp;amp; Cancellation&lt;a class="td-heading-self-link" href="#-catalog-loading--cancellation" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;startCatalogLoad(for:)&lt;/code&gt; short-circuits cleanly when the active catalog already has live security-scoped access — no redundant cancel/restart cycles.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cancelCatalogLoad()&lt;/code&gt; now also clears &lt;code&gt;currentselectedSource&lt;/code&gt; and stops active security-scoped access, preventing a new load from racing previous cleanup.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-tests"&gt;🧪 Tests&lt;a class="td-heading-self-link" href="#-tests" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;New &lt;code&gt;RawCullViewModelSecurityScopeTests&lt;/code&gt; covering start/stop pairing, re-selection no-op behavior, and cancellation cleanup.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ThumbnailProvider*&lt;/code&gt; tests updated for the refreshed memory and cancellation surface.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="-cleanup"&gt;🧹 Cleanup&lt;a class="td-heading-self-link" href="#-cleanup" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Removed legacy &lt;code&gt;documents/ver176.md&lt;/code&gt;; added &lt;code&gt;documents/ver181.md&lt;/code&gt; capturing the v1.8.0 review findings actually shipped in this release.&lt;/li&gt;
&lt;li&gt;Minor follow-ups in &lt;code&gt;RawCullViewModel+Catalog&lt;/code&gt;, &lt;code&gt;SharpnessScoringModel&lt;/code&gt;, and project settings.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>