简体   繁体   中英

Copy a file in Cocoa App with / without sandboxing enabled

First Issue: No Sandboxing

I am having an issue with some code to copy a file. With sandboxing turned off completely and this code.

- (IBAction)installWidget:(id)sender 
{
    // copy widgets to users library
    NSError* error = nil;

    NSString *testUrl = @"~/Library/Widgets/test.wdgt";
    if ([[NSFileManager defaultManager]fileExistsAtPath:testUrl]) {
        NSLog(@"yes");
    }
    NSString *testUrl2 = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"test.wdgt"];
    if ([[NSFileManager defaultManager]fileExistsAtPath:testUrl2]) {
        NSLog(@"yes");
    }

    [[NSFileManager defaultManager] removeItemAtPath:testUrl error:nil];
    [[NSFileManager defaultManager]copyItemAtPath:testUrl2 toPath:testUrl error:&error];

    if (error != nil) {
        NSLog(@"%@", [error localizedDescription]);
    }
}

With sandboxing turned off I get the following error.

The file “test.wdgt” doesn't exist. I tried zipping it thinking it was a flat file issue when changing the code from test.wdgt to test.zip I got the same error. The file is included in the resources bundle but its not letting me copy it.

I tried moving the app from outside of the build folder, same issue. I also tried cleaning the build folder same issue.

Second Issue: With Sandboxing

I get the following error with Sandboxing enabled. You don't have permission to access the directory Widgets.

Entitlement file looks like this

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.movies.read-write</key>
<true/>
<key>com.apple.security.assets.music.read-write</key>
<true/>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.print</key>
<true/>
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
    <string>/Users/jon/Library/Widgets/</string>
</array>
</dict>
</plist>

I am beating my head against the wall. I tried adding a simple image and then replacing the image name with the widget name and it copied fine as long as sandboxing was disabled. I wrote a widget thats works with my app and I want to distribute it by allowing the user to install the widget by clicking a button in the app or from a menu item. Any help is appreciated.

On the non-sandbox question, you need to expand the tilde( ~ ) before using that in a path for file system operations. One way to do this is by calling -stringByExpandingTildeInPath on the string you have created, but the best practice for getting folders like this would be to use:

NSArray *paths = NSSearchPathForDirectoriesInDomains
                           ( NSLibraryDirectory, NSUserDomainMask, YES);

This will return an array (should only be 1 element) containing the string to the path for the User's Library directory. Then you can add your specific path elements to that by using -stringByAppendingPathComponent: .

Thus, you'd get the full path by taking:

NSString *widgetsPath = [[paths objectAtIndex: 0] stringByAppendingPathComponent:
                             @"Widgets"];

As for doing in the sandbox, your current code will fail due to the wrong directory, which won't have access (since ~ is being interpreted as a path component and not to replace the User's home directory). However, you obviously can't use the absolute-path exception in shipping code by enumerating every user. Chances are you will need to find another approach to installing this if you are going to be sandboxed. You may be able to just open the widget file and thus get the OS to offer to copy it for you. Otherwise, you're going to have to ask the user's permission in some way, such as by popping up an open window and passing in the path to the user's Widget folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM