feat: add EntryEditView for add/edit entries

Also fixes real bugs found while making Phase 4 build clean on both
platforms:
- FileBookmarkService used .withSecurityScope unconditionally, but
  that bookmark option is macOS-only -- iOS grants scoped access
  automatically once the user picks a file. Now conditional per platform.
- EntryEditViewModel's groupId was non-optional with no default, but
  EntryDetailView's edit-sheet call site (Task 14) has no group
  reference to pass -- only the "add new entry" path actually needs
  it, so groupId is now optional and validated at save time instead.
- Missing `import Combine` in EntryDetailView (Timer.publish/autoconnect)
  and UnlockViewModel/VaultViewModel/EntryEditViewModel (@Published).
- GroupBrowserView's `group: Group` property collided with SwiftUI's
  own Group view type -- qualified as MyPassCore.Group.
- EntryEditView's .keyboardType(.URL) and .navigationBarTitleDisplayMode
  are iOS-only APIs, guarded with #if os(iOS) for the macOS build.

Verified clean (aside from the known, expected ContentView.swift/Item
breakage) on both iOS Simulator and macOS destinations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
This commit is contained in:
2026-09-19 16:00:37 +02:00
co-authored by Claude Sonnet 5
parent 347f9a99c4
commit a48e8baf7a
5 changed files with 181 additions and 4 deletions
+21 -3
View File
@@ -14,9 +14,27 @@ public final class FileBookmarkService {
defaults = UserDefaults(suiteName: appGroup) ?? .standard
}
// `.withSecurityScope` is a macOS-only bookmark-creation option; iOS grants scoped
// access automatically once the user picks a file, without that flag.
private static var creationOptions: URL.BookmarkCreationOptions {
#if os(macOS)
return .withSecurityScope
#else
return []
#endif
}
private static var resolutionOptions: URL.BookmarkResolutionOptions {
#if os(macOS)
return .withSecurityScope
#else
return []
#endif
}
public func save(url: URL) throws {
let data = try url.bookmarkData(
options: .withSecurityScope,
options: Self.creationOptions,
includingResourceValuesForKeys: nil,
relativeTo: nil
)
@@ -29,12 +47,12 @@ public final class FileBookmarkService {
var isStale = false
let url = try URL(
resolvingBookmarkData: data,
options: .withSecurityScope,
options: Self.resolutionOptions,
relativeTo: nil,
bookmarkDataIsStale: &isStale
)
if isStale {
let fresh = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
let fresh = try url.bookmarkData(options: Self.creationOptions, includingResourceValuesForKeys: nil, relativeTo: nil)
defaults.set(fresh, forKey: Self.key)
}
guard url.startAccessingSecurityScopedResource() else { throw BookmarkError.accessDenied }