Repository navigation
Release 1.8.0: complete artwork, per-side VoiceOver, Swift 6, CI and snapshot tests - #6
Merged
Merged
Conversation
Every Muscle case is now drawn in at least one view. - upperTrapezius / lowerTrapezius: on the back views, the parts of the trapezius above and below the rhomboid band, clipped to the trapezius outline. On the front views the visible trapezius is the upper part, so upperTrapezius uses that shape. - rearDeltoid: the deltoid as seen from behind, on both back views. - These three were removed earlier because they were small circular placeholders; the new shapes follow the parent muscle's own outline. Like the other non-visible sub-groups they are only drawn with .showSubGroups(). - Female back ankles: the female back view had a single heel shape tagged as feet, so .ankles painted nothing there. Its upper part is now the always-visible ankles sub-group, slightly inset so the unhighlighted body looks the same as before. - The female back view still has no head path: the hair covers it completely, so there is nothing visible to draw. isDrawable reports that. Unhighlighted bodies and heatmaps on trapezius, deltoids, feet and upper back render pixel-identical to 1.7.1 on three views; on the female back the ankle edges differ by at most 2/255 per channel.
Path cache - Parse every SVG path string once at unit scale and scale it per view size with an affine transform, instead of parsing again for every size. The first draw at a new size (rotation, split view, zoom) drops from ~6.0 ms to ~2.9 ms for a front + back pair in a release build; steady-state redraws are unchanged at ~2.2 ms. - Parsed paths are kept for the life of the app (the artwork is a fixed set of strings); per-size copies are still cleared past 4096 entries. - Protect the cache with OSAllocatedUnfairLock so PathCache is checked Sendable instead of @unchecked Sendable. Preloading - Creating a BodyView now starts parsing all four bodies in the background once per app run, and BodyView.preloadArtwork() lets apps start it at launch. After SwiftUI's own first-render setup, the first body draws in ~6.7 ms instead of ~8.1 ms. Swift 6 - Add Package@swift-6.0.swift with the Swift 6 language mode, so projects on a Swift 6 toolchain build the package with full concurrency checking; Package.swift keeps Swift 5.9 for older Xcode versions. The podspec now lists both Swift versions. - AnimatedBodyCanvas.animatableData is nonisolated, which Swift 6 requires for the Animatable conformance of a main-actor view. - Test classes that create views run on the main actor. The library and tests build without warnings in Swift 6 mode, all tests pass with both manifests, and renders match 1.7.1 to within 1/255 per channel.
Paired muscles were exposed as a single accessibility element whose frame was the union of both sides, so the biceps element spanned the whole chest and the midline between the arms announced "Biceps". - Muscles drawn on both sides now get one element per side, labelled "Biceps, Left" / "Biceps, Right" and read left then right. Muscles drawn once (for example a single common path) keep one element. - The activate and long-press actions report the element's side, matching what a touch on the same spot returns, instead of always .both. - New "accessibility.muscleWithSide" string in all 11 languages, using the list separator of each script (、 in Japanese, , in Chinese, ، in Arabic) and keeping the muscle name and side as separate words so no language needs grammatical agreement. - BodyRenderer gains boundingRect(for:muscleSide:in:) for per-side frames.
- Add Tools/ScreenshotGenerator, a small macOS tool that renders the README
body screenshots with the library itself:
swift run --package-path Tools/ScreenshotGenerator ScreenshotGenerator Screenshots
Each screenshot is defined next to the code it illustrates, so they can
be refreshed whenever the artwork or rendering changes.
- Regenerate the eleven body screenshots with it and add two new ones:
back_regions (upper/lower trapezius, rhomboids, rear deltoid, rotator
cuff) and heatmap_stepped (.workoutStepped now that the scale's own
interpolation is honoured). The two app screenshots of the gradient and
stepped heatmap demo are unchanged.
- Demo app: the Sub-Groups tab gains a "Back Regions" section with both
back bodies and a legend, and shows which views the tapped muscle is
drawn on.
- Remove Examples/MuscleMapDemo, an outdated copy of the demo without an
Xcode project that was last updated for 1.4.0. Example/ is the
maintained demo.
- README: document the new back regions, BodyView.preloadArtwork(), the
per-side VoiceOver elements, Swift 6 support, and how to run the tests
and regenerate the screenshots.
- GitHub Actions runs on every push to main and every pull request: swift test on macOS, an iOS Simulator build of the library and of the demo app, and pod lib lint. - SnapshotTests render all four bodies, unhighlighted and with a heatmap, plus the back regions, and compare them with reference images in Tests/MuscleMapTests/__Snapshots__. A pixel counts as different above a per-channel tolerance and a snapshot fails above 0.2 % different pixels, so anti-aliasing differences between machines pass while artwork or layout regressions fail. Reintroducing the female back view box bug fixed in 1.6.4 makes 26 % of the pixels differ. - Record new references after an intended change with MUSCLEMAP_RECORD_SNAPSHOTS=1 swift test --filter SnapshotTests. On CI, failing renders are uploaded as a build artifact.
- Bump the podspec and the SPM / CocoaPods install snippets to 1.8.0.
The first CI run failed the heatmap and back-region snapshots by 1-5 % of pixels while the unhighlighted bodies matched exactly. The shapes were identical; the system colors were not: SwiftUI's .red, .orange and .yellow resolve to different values on macOS 15 (CI) and macOS 26 (where the references were recorded), e.g. #FF5128 vs #FF5340. Snapshots now highlight with fixed sRGB colors and a custom heatmap scale, so they test geometry and layout independently of the OS color palette. References re-recorded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every muscle is now drawn in at least one view, the package builds cleanly in the Swift 6 language mode, VoiceOver exposes paired muscles per side, and the repository gets CI with snapshot tests.
Artwork
.rearDeltoid,.upperTrapeziusand.lowerTrapeziusare drawn on both back views, and.upperTrapeziuson the front views. They follow the parent muscle's own outline, replacing the small circular placeholders that were removed earlier. Like the other non-visible sub-groups, they are drawn with.showSubGroups()..anklespainted nothing there. Its upper part is now the always-visible ankles sub-group.isDrawablereports this.VoiceOver
Performance
BodyViewstarts parsing all four bodies in the background, and the newBodyView.preloadArtwork()lets apps start this at launch.PathCacheis now protected byOSAllocatedUnfairLockand is checkedSendable; it no longer uses@unchecked Sendable.Swift 6
Package@swift-6.0.swiftuses the Swift 6 language mode.Package.swiftstays on Swift 5.9 for older Xcode versions, and the podspec lists both versions.Repository
pod lib lint.Tools/ScreenshotGeneratorrenders the README screenshots from code. All body screenshots were regenerated, and two were added: back regions and the stepped heatmap.Examples/copy was removed, and the demo app's Sub-Groups tab now shows the back regions.