简体   繁体   English

沙盒 Mac 应用程序可以在哪里保存文件?

[英]Where can a sandboxed Mac app save files?

My Mac app is sandboxed and I need to save a file.我的 Mac 应用程序是沙盒化的,我需要保存一个文件。 Where do I save this file?我在哪里保存这个文件? I can't seem to find the specific place where this is allowed without using an open panel.如果不使用打开的面板,我似乎无法找到允许这样做的具体位置。 This is how I do it on iOS:这就是我在 iOS 上的做法:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];

What is the equivalent for the sandboxed directory on Mac? Mac 上沙盒目录的等效项是什么?

That code snippet works on the Mac regardless of whether your application is sandboxed.无论您的应用程序是否被沙盒化,该代码片段都可以在 Mac 上运行。

In a non-sandboxed Mac app, path will refer to the Documents folder in your home: eg /Users/username/Documents .在非沙盒 Mac 应用程序中, path将引用您家中的文档文件夹:例如/Users/username/Documents

In a sandboxed app, it refers to a folder within the app sandbox: eg /Users/username/Library/Containers/com.yourcompany.YourApp/Documents在沙盒应用程序中,它指的是应用程序沙盒中的文件夹:例如/Users/username/Library/Containers/com.yourcompany.YourApp/Documents

See the docs for details.有关详细信息,请参阅文档

Apple's Sandboxing guide is very useful, found here . Apple 的沙盒指南非常有用,可在此处找到。

You basically have a folder dedicated for your app, as described by theAmateurProgrammer in reply to my question here .您基本上有一个专用于您的应用程序的文件夹,正如 theAmateurProgrammer 在此处回答我的问题时所描述的那样。

~/Library/Container/com.yourcompany.yourappname/ ~/Library/Container/com.yourcompany.yourappname/

Here is what I have so far, I will improve it later:这是我目前所拥有的,稍后我会改进它:

//Create App directory if not exists:
NSFileManager* fileManager = [[NSFileManager alloc] init];
NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];
NSArray* urlPaths = [fileManager URLsForDirectory:NSApplicationSupportDirectory 
                                        inDomains:NSUserDomainMask];

NSURL* appDirectory = [[urlPaths objectAtIndex:0] URLByAppendingPathComponent:bundleID isDirectory:YES];

//TODO: handle the error
if (![fileManager fileExistsAtPath:[appDirectory path]]) {
    [fileManager createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:nil];
}

Converting @Mazyod's answer into Swift (5.1) :将@Mazyod 的答案转换为Swift (5.1)

var appPath: URL? {
    //Create App directory if not exists:
    let fileManager = FileManager()
    let urlPaths = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)
    if let bundleID = Bundle.main.bundleIdentifier, let appDirectory = urlPaths.first?.appendingPathComponent(bundleID,isDirectory: true) {
        var objCTrue: ObjCBool = true
        let path = appDirectory.path
        if !fileManager.fileExists(atPath: path,isDirectory: &objCTrue) {
            do {
                try fileManager.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
            } catch {
                return nil
            }
        }
        return appDirectory
    }
    return nil
}

However, the directory has changed and I am not sure that the additonal repetition of the bundle ID is needed as the path is但是,目录已更改,我不确定是否需要额外重复包 ID,因为路径是

"/Users/**user name**/Library/Containers/**bundleID**/Data/Library/Application Support/**bundleID**". 

But it seems to work.但它似乎工作。

Is is even easier.是更容易。 For sandboxed apps on macOS the function NSHomeDirectory gives you the path where you have read and write access and can save all your files.对于 macOS 上的沙盒应用程序, NSHomeDirectory为您提供了具有读写访问权限并可以保存所有文件的路径。 It will be a path like this会是这样的路径

/Users/username/Library/Containers/com.yourcompany.YourApp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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