Skip to content

refactor: improve Swift 6 concurrency safety, API parsing o11y#78

Merged
sozercan merged 3 commits intomainfrom
bugbash2
Jan 18, 2026
Merged

refactor: improve Swift 6 concurrency safety, API parsing o11y#78
sozercan merged 3 commits intomainfrom
bugbash2

Conversation

@sozercan
Copy link
Owner

Description

Summary

This PR addresses multiple issues identified in a comprehensive API and codebase audit, focusing on:

  1. Swift 6 Concurrency Safety - Fixed nonisolated(unsafe) patterns for task cancellation in deinit
  2. API Parsing Observability - Added logging to parsers that previously failed silently
  3. Documentation Accuracy - Updated api-discovery.md to reflect actually implemented endpoints
  4. Foundation Models API Updates - Fixed LanguageModelSession API changes (prewarm, error handling)
  5. Security Hardening - Fixed NSKeyedArchiver to use secure coding for cookie archival

Changes

Swift Concurrency (ViewModels & Services)

  • Added deinit with task cancellation to 6 ViewModels: ChartsViewModel, ExploreViewModel, HomeViewModel, MoodsAndGenresViewModel, NewReleasesViewModel, PodcastsViewModel, SearchViewModel
  • Marked background tasks as nonisolated(unsafe) for proper deinit access
  • Fixed NetworkMonitor to use simpler immutable pattern for NWPathMonitor

API Parsers

  • Added DiagnosticsLogger to: LyricsParser, RadioQueueParser, SearchResponseParser, SearchSuggestionsParser, SongMetadataParser
  • Added debug logging on parse failures to improve observability

Foundation Models (macOS 26+)

  • Updated AIErrorHandler to handle new LanguageModelSession.GenerationError cases
  • Fixed FoundationModelsService.prewarmSession() to match new async API (no longer throws)

Documentation

  • Updated api-discovery.md: Moved 4 endpoints from "Not Implemented" to "Implemented" (FEmusic_charts, FEmusic_moods_and_genres, FEmusic_new_releases, FEmusic_library_landing)
  • Added Parsers Reference and Error Handling sections
  • Fixed search filter param documentation

UI & Player

  • Added playback error state display with retry button in PlayerBar
  • Fixed FavoritesSection drop handler return value

API Explorer Tool

  • Added diagnostic output for cookie loading failures
  • Removed music/get_queue from auth-required list (works without auth)
  • Added explanatory comments for NSKeyedArchiver coding

Security

  • Fixed WebKitManager to use requiringSecureCoding: true for outer cookie array archival
  • Added comments explaining secure coding rationale

Testing

  • Added new NetworkMonitorTests.swift with basic test coverage

AI Prompt (Optional)

🤖 AI Prompt Used
<!-- Paste your prompt here, or write "N/A - Manual implementation" -->

AI Tool:

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📚 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Refactoring (no functional changes)
  • 🧪 Test update
  • 🔧 Build/CI configuration

Related Issues

Changes Made

Testing

  • Unit tests pass (xcodebuild test -only-testing:KasetTests)
  • Manual testing performed
  • UI tested on macOS 26+

Checklist

  • My code follows the project's style guidelines
  • I have run swiftlint --strict && swiftformat .
  • I have added tests that prove my fix/feature works
  • New and existing unit tests pass locally
  • I have updated documentation if needed
  • I have checked for any performance implications
  • My changes generate no new warnings

Screenshots

Additional Notes

…ty, and documentation accuracy

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Copilot AI review requested due to automatic review settings January 17, 2026 23:56
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Swift 6 concurrency safety, adds API parsing observability, updates documentation, and implements several bug fixes and security enhancements.

Changes:

  • Added proper task cancellation in deinit for 7 ViewModels and NotificationService using nonisolated(unsafe) pattern
  • Added debug logging to 4 API parsers that previously failed silently (LyricsParser, RadioQueueParser, SearchResponseParser, SearchSuggestionsParser)
  • Updated Foundation Models API to handle new LanguageModelSession.GenerationError cases and async prewarm API
  • Enhanced documentation with Parsers Reference and Error Handling sections, moved 4 endpoints to "Implemented" status
  • Fixed NSKeyedArchiver security with requiringSecureCoding: true for outer cookie array
  • Added error state display with retry button in PlayerBar

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Core/ViewModels/ChartsViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/ExploreViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/HomeViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/MoodsAndGenresViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/NewReleasesViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/PodcastsViewModel.swift Added deinit with task cancellation, marked task as nonisolated(unsafe)
Core/ViewModels/SearchViewModel.swift Added deinit with task cancellation for two tasks, marked as nonisolated(unsafe)
Core/Services/Notification/NotificationService.swift Updated comment for task cancellation pattern
Core/Services/NetworkMonitor.swift Removed nonisolated(unsafe) from immutable NWPathMonitor property
Core/Services/API/Parsers/LyricsParser.swift Added DiagnosticsLogger and debug logging for parse failures
Core/Services/API/Parsers/RadioQueueParser.swift Added DiagnosticsLogger and debug logging for parse failures
Core/Services/API/Parsers/SearchResponseParser.swift Added DiagnosticsLogger and debug logging for parse failures
Core/Services/API/Parsers/SearchSuggestionsParser.swift Added DiagnosticsLogger and debug logging for parse failures
Core/Services/API/Parsers/SongMetadataParser.swift Added DiagnosticsLogger declaration for consistency
Core/Services/AI/FoundationModelsService.swift Updated prewarm to use new async API without try-catch
Core/Services/AI/AIErrorHandler.swift Added handling for 7 new GenerationError cases, fixed property access
Core/Services/WebKit/WebKitManager.swift Fixed NSKeyedArchiver to use secure coding for outer cookie array
Core/Utilities/ImageCache.swift Marked evictDiskCacheIfNeeded as async with explanatory comment
Views/macOS/PlayerBar.swift Added error state display with retry button
Views/macOS/SharedViews/FavoritesSection.swift Added explicit return statement in dropDestination closure
Tools/api-explorer.swift Added diagnostic output for cookie loading failures, removed music/get_queue from auth-required list
docs/api-discovery.md Moved 4 endpoints to Implemented section, added Parsers Reference and Error Handling sections, fixed search filter documentation
Tests/KasetTests/NetworkMonitorTests.swift Added new test file with basic NetworkMonitor tests

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let watchNextTabbedResults = tabbedRenderer["watchNextTabbedResultsRenderer"] as? [String: Any],
let tabs = watchNextTabbedResults["tabs"] as? [[String: Any]]
else {
self.logger.debug("LyricsParser: Failed to extract lyrics browse ID structure")
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parse failure logging uses self.logger.debug but should be Self.logger.debug for consistency with static context (enum with static methods). The capital 'S' in 'Self' is the convention for static contexts.

Copilot uses AI. Check for mistakes.
try await client.fetchData()
}
```
```
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an extra closing triple backtick (```) on this line, which will break the markdown rendering. The code block on line 959 already has its closing triple backtick on line 969, so this line should be removed.

Suggested change
```

Copilot uses AI. Check for mistakes.
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
sozercan

This comment was marked as resolved.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
@sozercan sozercan merged commit 543edd5 into main Jan 18, 2026
6 checks passed
@sozercan sozercan deleted the bugbash2 branch January 18, 2026 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants