【问题标题】:NSFileManager creating folder (Cocoa error 513.)NSFileManager 创建文件夹(Cocoa 错误 513。)
【发布时间】:2011-03-27 05:56:29
【问题描述】:

我正在尝试在我的应用程序的 /sounds 文件夹中创建一个文件夹。

-(void)productPurchased:(UAProduct*) product {
    NSLog(@"[StoreFrontDelegate] Purchased: %@ -- %@", product.productIdentifier, product.title);

    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];

    NSError *error;

    NSString *dataPath = [NSString stringWithFormat:@"%@/sounds/%@", bundleRoot, product.title];

    if (![manager fileExistsAtPath:dataPath isDirectory:YES]) {
        [manager createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&error];
        NSLog(@"Creating folder");
    }

    NSLog(@"%@", error);
}

但我收到此错误:

Error Domain=NSCocoaErrorDomain Code=513 "The operation couldn’t be completed. (Cocoa error 513.)" UserInfo=0x175120 {NSFilePath=/var/mobile/Applications/D83FDFF9-2600-4056-9047-05F82633A2E4/App.app/sounds/Test Tones, NSUnderlyingError=0x117520 "The operation couldn’t be completed. Operation not permitted"}

我做错了什么? 谢谢。

【问题讨论】:

    标签: iphone nsfilemanager


    【解决方案1】:

    如果您在错误域 NSCocoaErrorDomain 上搜索 Google,您会发现代码 513 转换为错误 NSFileWriteNoPermissionError

    这为您提供了解决此问题的关键线索:

    This is the bundle directory containing the application itself. Because an application must be signed, you must not make changes to the contents of this directory at runtime. Doing so may prevent your application from launching later.

    具体来说,您不能修改已编译应用的捆绑文件夹的内容。这是因为 bundle 是编译后的应用程序。

    当您最终通过 iTunes App Store 分发应用程序时,该应用程序有一个数字签名来验证应用程序的内容。这个签名是在编译时生成的。

    如果您在编译后尝试更改捆绑包,则应用会更改并且数字签名不再有效。这会使应用程序无效——谁知道里面有什么代码,对吧? — 因此,Apple 已将 iOS 设置为在您尝试修改应用程序时抛出错误。

    您的应用可以写入one of three accepted app-specific folders<Application_Home>/Documents<Application_Home>/tmp<Application_Home>/Library/Caches,而不是写入包。

    您很可能想要写入<Application_Home>/Documents 文件夹。

    这些文件夹仅供您的应用访问。没有其他应用程序可以访问这些文件夹的内容。 (同样,您的应用无法访问其他应用的文件夹。)

    您可以设置您的应用程序以允许最终用户通过 iTunes 管理对文件数据的访问,通过 desktop file sharing support

    【讨论】:

    • 感谢您回答 Alex,如果可以,请更新最后一个链接,因为该页面不再存在!
    • 有趣的是(至少在 Xcode 6 和 iOS 8 上)你可以在模拟器上的 bundle 中创建目录,但是同样的代码在设备上会失败。
    • ^re: Jared Egan,Xcode 8 和 iOS 10 的模拟器仍然如此
    • @Alex Reynolds Documents, Temp and Cache 链接已失效
    • @JaredEgan 这让我头疼了 2 个小时...与其写信给 .applicationDirectory,不如写信给 .applicationSupportDirectory
    【解决方案2】:

    这是因为您不应该在运行时修改应用程序的捆绑包。相反,您应该在其他地方有一个文件夹,您可以在其中添加资源。

    编辑:
    您看到的错误很可能是因为您无法写入包。

    【讨论】:

    • +1 作为 iOS 安全模型的一部分,您无法在应用程序编译后修改应用程序包。这可以防止恶意软件在安装后修改应用程序的可能性。运行时生成的文件应保存到应用程序目录中 Library 文件夹的 Documents 文件夹中。对于用户永远不会通过应用程序本身以外的任何方式访问的文件,后者是首选。
    【解决方案3】:

    我在使用 Log 库时遇到了同样的问题。最后是路径格式问题。检查dataPath 格式。如果是Case 1,则有效。就我而言,它是Case 2,所以我无法创建目录。

    // Case 1
    /var/mobile/Containers/Data/Application/5FB2CD2D-91DC-4FB2-8D6F-06369C70BB4A/Library/Caches/AppLogs
    
    // Case 2, invalid format
    file://var/mobile/Containers/Data/Application/5FB2CD2D-91DC-4FB2-8D6F-06369C70BB4A/Library/Caches/AppLogs
    

    如果dataPath 有前缀,例如:file://,则无效


    对于NSURL 的实例,path 将返回类似case 1 的字符串,absolutePath 将返回类似case 2 的字符串。

    【讨论】:

      【解决方案4】:

      在我的案例中,我仍然不完全清楚 513 错误的含义,但我只是在尝试使用 [NSFileHandle fileHandleForReadingFromURL:theUrl error:&err ] 读取打开的文件 URL 时得到它。

      我从this answer 了解到,在 iOS 13 中,我现在需要使用startAccessingSecurityScopedResource 来访问在应用程序中打开的外部文件。当我按如下方式包装我的文件调用时,错误 513 停止发生:

      if( [myURL startAccessingSecurityScopedResource] ) 
      {
          NSFileHandle* myFile = [NSFileHandle fileHandleForReadingFromURL:myURL error:&err ];
          // ...Do file reads here...
          [theUrl stopAccessingSecurityScopedResource];
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-13
        • 2019-12-28
        • 2013-03-03
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多