Skip to content

Instantly share code, notes, and snippets.

@trevordevore
Created August 28, 2012 14:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trevordevore/3498531 to your computer and use it in GitHub Desktop.
Save trevordevore/3498531 to your computer and use it in GitHub Desktop.
Security Scoped Bookmark URLs
/*
To use:
1) Get path to file/folder using file selection dialog.
2) Pass path to secscopGetBookmarkFromURL in order to get bookmark data for it.
3) Store this bookmark data somehow.
4) Tell the OS you want access to the file using secscopInitializeURLFromBookmarkData(). Store security-scoped url returned for later.
5) When you are done using the file call secscopStopUsingURL.
You will need to do steps 4 and 5 every time you want to open a file across sessions. For example, if you have a recent files menu or a folder that a user selects once and you write data to across sessions.
*/
/**
* \brief Creates bookmark data from a LiveCode path to a file.
*
* \param pFilename The full path to the file you want bookmark data for.
* \param pBookmarkDataVarName The name of the variable to store the bookmark data in.
*
* \return Security-scoped URL
*/
void secscopGetBookmarkFromURL(char *p_arguments[], int p_argument_count, char **r_result, Bool *r_pass, Bool *r_err)
{
*r_pass = False;
*r_err = False;
ExternalString theExternalString;
int r_success;
const char *t_error;
t_error = NULL;
NSString *filename = [[NSString alloc] initWithCString:p_arguments[0] encoding:NSUTF8StringEncoding];
NSURL *theURL = [[NSURL alloc] initFileURLWithPath:filename];
NSError *error = nil;
NSData *bookmarkData = [theURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:nil
error:&error];
if (bookmarkData == NULL)
{
t_error = "unable to get bookmark data from URL";
} else {
//NSLog(@"The bookmark data is: %@", bookmarkData);
theExternalString.buffer = (const char*)[bookmarkData bytes];
theExternalString.length = (int)[bookmarkData length];
SetVariableEx( p_arguments[1], "", &theExternalString, &r_success);
if (r_success == EXTERNAL_FAILURE)
{
t_error = "unable to store bookmark data in variable";
}
}
[theURL release];
[filename release];
if (t_error == NULL)
{
*r_result = strdup("");
}
else
{
*r_result = strdup(t_error);
}
}
/**
* \brief Converts bookmark data to a security-scoped URL and tells OS that you want access to it.
*
* \param pBookmarkDataVarName The name of the variable that contains the bookmark data. The bookmark data was obtained from secscopGetBookmarkFromURL.
*
* \return Security-scoped URL
*/
void secscopInitializeURLFromBookmarkData(char *p_arguments[], int p_argument_count, char **r_result, Bool *r_pass, Bool *r_err)
{
*r_pass = False;
*r_err = False;
int r_success;
NSError *error = nil;
BOOL bookmarkDataIsStale;
NSURL *bookmarkFileURL = nil;
ExternalString theExternalString;
NSData *bookmarkData = nil;
const char *t_error;
t_error = NULL;
// Data is not copied. We are not responsible for memory management.
GetVariableEx(p_arguments[0], "", &theExternalString, &r_success);
if (r_success == EXTERNAL_FAILURE) {
t_error = "error: unable to get bookmark data from variable";
}
if (t_error == NULL)
{
// copy data into NSData
bookmarkData = [[NSData alloc] initWithBytes:theExternalString.buffer length:theExternalString.length];
if (bookmarkData == NULL) t_error = "error: unable to get bookmark data";
//NSLog(@"The bookmark data is: %@", bookmarkData);
}
if (t_error == NULL)
{
// e.g. file://localhost/Users/someuser/Desktop/File?applesecurityscope=3738613...
bookmarkFileURL = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:nil
bookmarkDataIsStale:&bookmarkDataIsStale
error:&error];
if (bookmarkFileURL == NULL) {
t_error = "error: unable to get URL from bookmark data";
NSLog(@"Error: %@", error);
} else {
[bookmarkFileURL startAccessingSecurityScopedResource];
NSString *filename = [bookmarkFileURL absoluteString];
*r_result = (char *)[filename UTF8String];
}
}
// Allocated so we need to release
[bookmarkData release];
if (t_error != NULL)
{
*r_result = strdup(t_error);
}
}
/**
* \brief Call this command when you are done modifing a file.
*
* \param pURLScopedURL The security scoped URL returned by secscopInitializeURLFromBookmarkData().
*
* \return empty
*/
void secscopStopUsingURL(char *p_arguments[], int p_argument_count, char **r_result, Bool *r_pass, Bool *r_err)
{
*r_pass = False;
*r_err = False;
const char *t_error;
t_error = NULL;
// This needs to be the security scoped URL with ?applesecurityscope appended to it.
NSString *filename = [[NSString alloc] initWithCString:p_arguments[0] encoding:NSUTF8StringEncoding];
NSURL *theURL = [[NSURL alloc] initFileURLWithPath:filename];
[theURL stopAccessingSecurityScopedResource];
//NSLog(@"theURL: %@", theURL);
[theURL release];
[filename release];
*r_result = strdup("");
}
EXTERNAL_DECLARE_COMMAND("secscopGetBookmarkFromURL", secscopGetBookmarkFromURL)
EXTERNAL_DECLARE_COMMAND("secscopInitializeURLFromBookmarkData", secscopInitializeURLFromBookmarkData)
EXTERNAL_DECLARE_COMMAND("secscopStopUsingURL", secscopStopUsingURL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment