【问题标题】:iOS code: Fails on other machines, but not mine with [NSFileManager copyItemAtPath:toPath:error:]: source path is nil'iOS 代码:在其他机器上失败,但不是我的 [NSFileManager copyItemAtPath:toPath:error:]: source path is nil'
【发布时间】:2012-10-06 02:28:46
【问题描述】:

我正在与一个团队一起开发,使用的 Mac 的映像都完全相同。使用我编写代码的机器,我可以以编程方式创建然后写入 pList 文件。但是当我使用我的家用机器(相同的图像)或当我的队友在他们的机器上测试代码时,我们会因 [NSFileManager copyItemAtPath:toPath:error:]: source path is nil' 错误而崩溃。在调试中,文件路径是有效的。但是,该捆绑包位于:

 NSString *bundle = [[NSBundle mainBundle]pathForResource:@"Family" ofType:@"plist"];
    [pListfileMgr copyItemAtPath:bundle toPath: pListpath error:&error];

为零。我们正在使用 git 对我们的代码进行版本控制。我们一直将 .DS_Store 和 /userdata/ 文件排除在存储库之外,除非我遗漏了什么。到底是怎么回事?这是代码,几乎是从here逐字复制的:

NSError *error;
NSArray *pListpaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,  YES);

NSString *pListdocumentsDirectory = [pListpaths objectAtIndex:0];

NSString *pListpath = [pListdocumentsDirectory stringByAppendingPathComponent:@"Family.plist"];
NSFileManager *pListfileMgr = [NSFileManager defaultManager];

//Create a plist if it doesn't alread exist
if (![pListfileMgr fileExistsAtPath: pListpath])
{
    NSString *bundle = [[NSBundle mainBundle]pathForResource:@"Family" ofType:@"plist"];
    [pListfileMgr copyItemAtPath:bundle toPath: pListpath error:&error];
}

NSMutableDictionary *thePList = [[NSMutableDictionary alloc] initWithContentsOfFile: pListpath];

[thePList setObject:[NSString stringWithFormat:@"%@", numberOfPeopleInFamilyOfOrigin] forKey:@"famSize"];
[thePList writeToFile: pListpath atomically: YES];

【问题讨论】:

  • 仍在寻求答案。我只是想强调,如果这个 plist 文件不存在,我们希望能够创建它。它主要用于编写 TO,而不是手动创建以读取静态值以填充表格或其他一些字段。如果我理解了,下面的@Olaf 说我应该确保文件资源正在复制到我队友的包中。这不是我的目标(除非我错了,不知道我在说什么)。
  • 更新:我从我的模拟器中删除了该应用程序并运行了一个新版本。现在我机器上的项目抛出了同样的错误。

标签: ios file-io nsfilemanager


【解决方案1】:

我相信您误解了上面列出的代码的意图。

以下块正在检查位于路径pListpath 的文件是否存在。如果pListpath 中不存在文件,它会将文件从in 包复制到pListpath

//Create a plist if it doesn't alread exist
if (![pListfileMgr fileExistsAtPath: pListpath])
{
    NSString *bundle = [[NSBundle mainBundle]pathForResource:@"Family" ofType:@"plist"];
    [pListfileMgr copyItemAtPath:bundle toPath: pListpath error:&error];
}

也就是说,你必须在你的包中发送一个名为 Family.plist 的文件,目的是如果路径中不存在 plist,则此文件将充当 默认 plist pListpath.

【讨论】:

  • 这正是让我感到困惑并在其他机器上引起不同行为的原因。我认为代码的意思是“如果文件不存在于包中,则在包中创建它”。我认为数据将被写入捆绑文件。当我看到它已创建并写入本地目录时,我想“很好,我的应用程序中不再需要该文件;它什么都不做”并立即将其删除并推送我的更改。因为我的文件存在于 pListpath 中,所以对我来说一切都很好。但是我的队友那里没有文件,他们的包中也没有文件,所以它崩溃了。
  • 我还有一个术语问题:bundle 是在构建过程中与您的应用“捆绑”的东西。所以,“它在你的包里吗?”意思是,“它是构成你的应用程序的文件之一吗?”就我而言,更确切地说是“你能在你的 xCode 文件导航器中的文件中看到它吗?”也许太明显了,但希望这对其他人有所帮助。
【解决方案2】:

在这种情况下我会尝试几件事:

打印出pListpath 的值,然后检查它是否存在于本地文件系统上,或者目录路径是否构造错误。

如果路径构造中不存在问题,我会显式创建Family.plist 并确保将其包含在Build Phases > Copy Bundle Resources 下。

此外,在共享环境中工作时,经常会产生杂乱无章的情况,清除我项目的派生数据通常有助于解决一些问题。您可以通过以下方式做到这一点: 1) 打开组织者。 2) 导航到项目选项卡。 3) 在左侧找到并选择您的项目。 4) 删除派生数据。

【讨论】:

    【解决方案3】:

    Family.plist 是否存在于您的 App 包中?

    Xcode 习惯于不将更改(添加)的资源更新到包中。通常的补救措施是从模拟器/设备上删除应用程序并安装新的。

    如果您的队友在他们的模拟器上安装了较旧的版本,即全新版本,但第一次安装的时间在 Family.plist 添加到项目之前,那么可能就是这样。

    您的队友可以通过导航(在 Finder 中)到 ~/Library/Application Support/iPhone Simulator 来验证 Family.plist 的存在,然后执行 Show Package ContentsyourAppName.app

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 2013-01-13
      • 2013-05-05
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多