4

I have posted this question on Apple's Developer forum and received no reply after a week, so I am hoping I will have better luck here.

I have created a standard document-based application (using NSDocument, saving simple XML files) that I now need to extend to also save document-scoped bookmarks to external files that the user has selected.

Everything is working, aside from the fact that the document-scoped bookmarks are failing to resolve after I read them back from the file, which it turns out is due to NSDocument writing the file atomically.

Background

Because I have found it extremely difficult to find information on the reported error via Apple's developer forums or web searches, I will quickly document what I have found in case it assists anyone else in the same boat.

The error returned by the failed attempt is:

Error Domain=NSCocoaErrorDomain Code=256 "The file “somefile.xml” couldn’t be opened."

where, confusingly, somefile.xml is (the filename component of) the absolute URL passed as "relativeToURL:" in the code-block below.

There are reports such as App Sandbox: document-scoped bookmark not resolving; not returning any error that have suggested a problem with sandbox/bookmarks when atomic file saving is enabled.

The previous reports of this problem do not give the same error (they usually refer to a failure with no error message), but I created a separate test application (not using NSDocument) to test this, and found that I was able to reproduce the same error message as above using the following code when writing the file:

// HACK: Save a temporary value to the file so that the file exists when creating the bookmark
NSString *temp = @"Temp";
[temp writeToURL:saveURL atomically:NO encoding:NSUTF8StringEncoding error:&error];
// Create bookmark to imageURL relative to the save location
NSData *bookmarkData = [imageURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:[saveURL absoluteURL] error:&error];
if(bookmarkData == nil) return;
// Convert NSData to a string format.
NSString *bookmarkString = [bookmarkData base64EncodedString];
// Write the file.
[bookmarkString writeToURL:saveURL atomically:YES encoding:NSUTF8StringEncoding error:&error];

When changing the final line to "atomically:NO", the bookmarks resolve correctly and everything works as expected.

NSDocument and atomic writing

Since the default and recommended setup for NSDocument uses atomic writes, and this will not work with one of the Sandbox's core features, I am looking for a way to make document-scoped bookmarks and NSDocument work together, which I assume means finding a way to make NSDocument write the file directly rather than atomically.

I am yet to find any working solution (on these forums or in a wider search) that gets around Apple's framework failures.

I could override one of

  • writeSafelyToURL:ofType:forSaveOperation:error:
  • writeToURL:ofType:forSaveOperation:error:
  • saveToURL:ofType:forSaveOperation:completionHandler:

but in each case the documentation says "if you override this method, be sure to invoke the superclass implementation", which would presumably continue to save the file atomically.

My aim would be to do it in a way where I can continue to support the other user experience expectations that Apple pushes onto developers (for better or worse) - eg. autosavesInPlace, versions, etc. But I am willing to sacrifice those niceties in order to have a working sandboxed application that can be released into the AppStore.

Community
  • 1
  • 1
  • this all might be a bug in sandbox implementation which was awful back in Mar '13 – mahal tertin May 04 '15 at 18:04
  • 1
    @user2206907 Did you find a solution to this problem in the end? I'm experiencing about the same problems and no matter what solution I try I constantly run into bugs in the bookmarks implementation. – Remco Poelstra Feb 29 '16 at 13:22

0 Answers0