Microsoft's official documentation says:
to try to access persistent outside of SandBox, but it doesn't work.
First, I use NSSavePanel.SavePanel
according to the SandBox security policy and bookmark the URL that I can access.
using (var dlg = NSSavePanel.SavePanel)
{
dlg.AllowedFileTypes = new[] { "zip" };
dlg.Prompt = "Authenticate";
if (dlg.RunModal() > 0)
{
NSError error;
NSData url = dlg.Url.CreateBookmarkData(NSUrlBookmarkCreationOptions.WithSecurityScope, null, null, out error);
}
}
And then I retrieve the access-authenticated bookmarks and make them accessible.
NSData data = new NSData();
NSUrl url = NSUrl.FromBookmarkData(data, NSUrlBookmarkResolutionOptions.WithSecurityScope, null, out bool isStale, out NSError error);
url.StartAccessingSecurityScopedResource();
//...
url.StopAccessingSecurityScopedResource();
However, the above url
will only contain null
, which will result in an error.
How can I make it work?
Do we need to put anything in the value of NSData data
in the first place?
You are confusing some things. Your code
using (var dlg = NSSavePanel.SavePanel)
{
dlg.Message = AppResources.DialogMessageSaveEncryptedFileName;
dlg.AllowedFileTypes = new[] { "zip" };
dlg.Prompt = "Authenticate";
if (dlg.RunModal() > 0)
{
NSError error;
//NSData url = dlg.Url.CreateBookmarkData(NSUrlBookmarkCreationOptions.WithSecurityScope, null, null, out error);
NSData bookmark = dlg.Url.CreateBookmarkData(NSUrlBookmarkCreationOptions.WithSecurityScope, null, null, out error);
}
}
The dlg.Url
is the url you want to access.
What you get back from dlg.Url.CreateBookmarkData()
is the encoded bookmark data. You can store this data anyway you like to persist it across app launches. For example in UserDefaults
Storing:
NSUserDefaults.StandardUserDefaults["bookmark"] = bookmark;
NSUserDefaults.StandardUserDefaults.Synchronize();
Later retrieving:
NSData bookmark = NSUserDefaults.StandardUserDefaults.DataForKey("bookmark");
This is the data you
put into NSUrl.FromBookmarkData
to get the url back.
//NSData data = new NSData();
//NSUrl url = NSUrl.FromBookmarkData(data, NSUrlBookmarkResolutionOptions.WithSecurityScope, null, out bool isStale, out NSError error);
NSUrl url = NSUrl.FromBookmarkData(bookmark, NSUrlBookmarkResolutionOptions.WithSecurityScope, null, out bool isStale, out NSError error);
url.StartAccessingSecurityScopedResource();
//...
url.StopAccessingSecurityScopedResource();
Also if you need to keep using the access pay attention to the isStale
return value from CreateBookmarkData
. If it return true you need to refresh the bookmark from the url with url.CreateBookMarkData
and replace the stored bookmark with the new one.