I had the same issue and solved it by calling startAccessingSecurityScopedResource on the initially resolved URL before getting a fresh bookmark for it (and calling stopAccessingSecurityScopedResource after).
I previously thought you only need to call these methods if you're about to access the file's contents, but it seems that creating a new bookmark from a previously resolved one also counts as "using" the security-scoped resource. The hint to the solution came from the code snippet at https://developer.apple.com/documentation/professional_video_applications/fcpxml_reference/asset/media-rep/bookmark/creating_bookmark_data?language=objc
Post
Replies
Boosts
Views
Activity
I had the same problem and it seemed due to not having accepted all the latest developer agreements. xcrun notarytool reported:
Error: HTTP status code: 403. A required agreement is missing or has expired. This request requires an in-effect agreement that has not been signed or has expired. Ensure your team has signed the necessary legal agreements and that they are not expired.
There was an updated agreement on https://developer.apple.com/account. Accepting this didn't seem to solve the problem, at least not after a waiting for a few minutes, so I kept looking and found the "Paid Apps" agreement on https://appstoreconnect.apple.com/agreements. I wasn't sure if it's relevant to me (I don't currently have any paid apps), but after accepting this one, notarising from Xcode worked again. However, it could be that there was just a propagation delay and that accepting the first agreement would have proved to be enough eventually.
If you're just renaming a property, you shouldn't need an explicit migration plan and could instead rely on automatic migration, using the originalName parameter of the @Attribute macro:
@Attribute(originalName: "name") let title: String
In terms of how the willMigrate and didMigrate closures work when you do write a custom migration stage, the SwiftData documentation currently isn't helpful, but the equivalent Core Data documentation offers some insight:
The handlers provide an opportunity to prepare the persistent store’s data for the upcoming changes before the stage runs, and perform any cleanup tasks afterward.
For example, to support a migration that changes an optional attribute to be nonoptional, you might assign a handler to the stage’s willMigrateHandler property that sets any nil instances of that attribute to a default value, thereby ensuring the migration succeeds.
The way I understand it is that at its core, a custom stage actually does the same as a lightweight stage, but the two handlers allow you to prepare the data so that the automatic part of the stage can succeed, and to do some clean-up afterwards if you need to.
I guess if you did want to rename a field using a custom stage, you'd have to:
Add an optional title attribute in the V1 model alongside the original name attribute, to allow you to copy the value over.*
In the willMigrate closure, get all the V1 objects and copy their name value into their title field.
The automatic part of the migration stage can now run safely, making title non-optional and removing the name field.
* Note that if your original model wasn't part of an explicit VersionedSchema, you can't introduce the title field in your now-explicit V1 schema because SwiftData won't recognise it as being the same as the implicit 1.0.0 schema it had created. To get around this, I had to create an intermediate schema (1.1.0) with the new field, and added a lightweight migration stage (from 1.0.0 to 1.1.0) to introduce the field before the custom stage (from 1.1.0 to 2.0.0) populated it.
I had the same problem in a NavigationSplitView and managed to solve it using simultaneous gestures as you originally tried. To make sure single-clicking fully matches native behaviour, my single-click handler sets the selection which is passed as a binding to the List, and it also sets a FocusState.
struct ContentView: View {
// Assume there's an "items" array of Item instances to display.
@State private var selectedItem: Item?
@FocusState var listFocused: Bool
var body: some View {
NavigationSplitView {
List(selection: $selectedItem) {
ForEach(items) { item in
NavigationLink(value: item) { Text(verbatim: item.name) }
.gesture(doubleClickGesture(for: item))
}
}
.focused($listFocused)
} detail: {
DetailView(item)
}
}
private func doubleClickGesture(for item: Item) -> some Gesture {
SimultaneousGesture(
TapGesture(count: 1).onEnded {
selectedItem = item
listFocused = true
},
TapGesture(count: 2).onEnded {
print(“Double-clicked”)
}
)
}
}