8

NSSavePanel在为 Mac App Store 沙盒化应用程序后,我在保存字符串文件时遇到问题。我设置com.apple.security.files.user-selected.read-writeYES并且NSOpenPanel正在按应有的方式工作。

但是,当我尝试保存新文件时,似乎一切正常,但是没有保存的文件应该在....

这是我用来保存文件的代码:

NSSavePanel *save = [NSSavePanel savePanel];

long int result = [save runModal];

if (result == NSOKButton)
{
    NSString *selectedFile = [save filename];
    NSString *fileName = [[NSString alloc] initWithFormat:@"%@.dat", selectedFile];
    NSString *arrayCompleto = [[NSString alloc]initWithFormat:@"bla bla bla"];
    [arrayCompleto writeToFile:fileName
                    atomically:NO
                      encoding:NSUTF8StringEncoding
                         error:nil];
}
4

1 回答 1

11

首先,-[NSSavePanel filename]选择器已被弃用。改为使用-[NSSavePanel URL]。其次,-[NSString writeToFile:atomically:encoding:error]告诉你你做错了什么的方式是error:(NSError**)争论。

您还应该特别处理文件 I/O 的错误,因为即使您的代码 100% 正确,用户的系统上仍然可能存在错误(权限不足等),并且将错误呈现给用户将允许他们看到它失败了(并且知道为什么)。处理代码中的错误也将使您的应用程序恢复。例如,如果您尝试读取您粘贴的代码下方的文件(在将其写入磁盘之后),但用户尝试将其写入他们无权访问的网络共享,您的应用程序可能会崩溃。如果您知道写入失败,您可以进行相应的操作(可能会提示输入不同的保存位置)。

但是,在这种情况下,我相信以下行是您的问题:

NSString *fileName = [[NSString alloc] initWithFormat:@"%@.dat", selectedFile];

当您的应用程序被沙盒化时,用户需要通过打开/保存面板授予您对特定文件特定目录的权限,以将它们带入您的沙盒。您正在做的是获取用户授予您写入权限的文件并说“这很好,但我想保存一个不同的文件”,这违反了沙箱。您应该做的是在保存面板中设置扩展名。完整的固定解决方案是:

NSSavePanel *save = [NSSavePanel savePanel];
[save setAllowedFileTypes:[NSArray arrayWithObject:@"dat"]];
[save setAllowsOtherFileTypes:NO];

NSInteger result = [save runModal];

if (result == NSOKButton)
{
     NSString *selectedFile = [[save URL] path];
     NSString *arrayCompleto = @"bla bla bla";

     NSError *error = nil;
     [arrayCompleto writeToFile:selectedFile
                     atomically:NO
                       encoding:NSUTF8StringEncoding
                          error:&error];
}

if (error) {
    // This is one way to handle the error, as an example
    [NSApp presentError:error];
}

如果将来有其他问题,您可以error在运行时检查 的值。调试时,在语句中设置断点if (error)以检查error对象的值(po error在 Xcode 的调试器中执行 a)。这应该可以帮助您找出问题所在。

于 2012-05-23T12:30:03.917 回答