I use this code to tell my second class to save a file to the given path :
if ([defaults boolForKey:@"SaveAutomatically"]) {
basepath = [defaults objectForKey:@"SaveAutomaticallyPath"];
basepath = [basepath stringByAppendingPathComponent:[defaults objectForKey:@"SaveAutomaticallyName"]];
}
[NSThread detachNewThreadSelector:@selector(saveTo:) toTarget:controller withObject:basepath];
So, the saveTo:
method is called. It first checks if the given path is okay
if (![[[aPath pathExtension] lowercaseString] isEqualToString:@"icns"]) {
aPath = [aPath stringByAppendingPathExtension:@"icns"];
}
if ([[NSFileManager defaultManager] fileExistsAtPath:aPath]) {
[delegate error:@"File exists already."];
[self performSelectorOnMainThread:@selector(fs)
withObject:nil waitUntilDone:NO];
}
Then it does some stuff and creates a CGImageDestinationRef
:
NSURL *fileURL = [NSURL fileURLWithPath:aPath];
CGImageDestinationRef dr = CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeAppleICNS , count, NULL);
if (!dr) {
[delegate error:@"Unable to save icon file."];
[self performSelectorOnMainThread:@selector(fs)
withObject:nil waitUntilDone:NO];
return;
}
dr
is nil every time. If I give the saveTo
a path by using a NSSavePanel
it does not complain and works fine.
I tried logging the path in saveTo:
but that works fine (eg. /Users/Home/Desktop/Result.icns).
In other words, when the above code saves to /Users/Home/Desktop/Result.icns it fails, but when I let the user decide to save to that same path using an NSSavePanel
, there's no problem.
I'm using SandBoxing. How can I solve this?
A sandboxed app has no file access, outside of its own container folder, unless the user expressly permits it using the Open/Save Panel or via drag-and-drop. You will need to allow the user to choose the path they wish to save to and keep a security-scoped bookmark of that folder for later use (i.e. if you want to update that file after the app has restarted).
Here is a quote from Apple's Sandbox Design Guide:
Your sandboxed app can access file system locations outside of its container in the following three ways:
- At the specific direction of the user
- By using entitlements for specific file-system locations (described in “Entitlements and System Resource Access”)
- When the file system location is in certain directories that are world readable