【问题标题】:iOS: How to Populate CoreData with downloaded CSViOS:如何使用下载的 CSV 填充 CoreData
【发布时间】:2013-07-12 10:50:58
【问题描述】:

我一直在开发一个应用程序,用户每天输入存储在核心数据中的数据(两个属性为NSNumber,一个为NSDate),我想通过允许用户从外部导入数据来改进它文件,例如 csv 或任何其他支持的格式,只需单击按钮即可。有关如何有效地执行此操作的任何建议?

谢谢。

编辑: 只需添加 csv 文件的屏幕截图以及 csv 解析器的输出作为 NSArray。基本上需要在按钮点击时单独获取属性并将它们存储在核心数据中。

- csv 格式的输入文件:

- 示例 csv 解析器输出(NSarray):

【问题讨论】:

  • 您打算如何将 CSV 文件放到设备上并放到应用可以看到的地方?
  • 我在想也许可以用 iTunes 来获取它

标签: iphone ios objective-c core-data file-upload


【解决方案1】:

我最近需要实现类似的目标。

我的项目团队的几个成员想要将我们的应用原型拿出来展示给潜在客户,但又想向每个客户展示不同的数据。我们通过允许我们的项目团队成员在与客户会面之前创建自己的测试数据来解决这个问题。

我通过创建一个示例 .csv 文件并将其分发给项目团队中的其他人来实现这一点。他们用自己的测试数据填充它,并使用 iTunes 文件共享将 .csv 测试数据文件放到设备上。

加载时,应用会扫描其 Documents 目录以查找测试数据文件。如果存在,它会解析 .csv 文件并保存到数据库中。

对于 CSV 解析,我使用了 Dave DeLong 的 CHCSVParser:https://github.com/davedelong/CHCSVParser

在为您的应用设置 iTunes 文件共享方面提供了大量帮助。一个快速的谷歌找到了这个教程 (http://www.raywenderlich.com/1948/how-integrate-itunes-file-sharing-with-your-ios-app),如果你需要它应该可以帮助你。

Edit - 添加了关于在 Core Data 中存储 .csv 数据的帮助

您在原始帖子中声明您存储了一个 NSNumber 和 NSDate。以此为起点,您可能有一个 .csv 文件,格式如下:

+----------------+--------------+
+ NSNumberColumn | NSDateColumn |
+----------------+--------------+
+        1       |  2013-05-15  |
+        2       |  2013-06-15  |
+        3       |  2013-07-15  |
+----------------+--------------+

假设 CSV 解析器的输出是 NSArray 的 NSArray,您可以按如下方式创建核心数据对象:

我会为列号创建几个宏:

#define NSNumberColumn 0
#define NSDateColumn 1

然后遍历 .csv 文件中的行:

NSArray *rows = [NSArray arrayWithContentsOfCSVFile:pathToFile]; //CHCSVParser specific parsing method
for (NSArray *row in rows)
{
    NSString *numberString = [parsedCsvRow objectAtIndex:NSNumberColumn];
    NSString *dateString = [parsedCsvRow objectAtIndex:NSDateColumn];   

    NSNumber *number = // parse numberString to an NSNumber. Plenty of other posts on achieving this. 
    NSDate *date = // parse NSDate from dateString. Plenty of other posts on achieving this.

    NSManagedObjectContext *context = [self managedObjectContext];
    NSManagedObject *myCoreDataObject = [NSEntityDescription insertNewObjectForEntityForName:@"MyCoreDataObject" inManagedObjectContext:context];
    [myCoreDataObject setValue:number forKey:@"NSNumberColumn"];
    [myCoreDataObject setValue:date forKey:@"NSDateColumn"];
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"%@", [error localizedDescription]);
    }
}

注意:为简洁起见,省略了输入验证和空值检查。我还冒昧地编造了您的 NSManagedObject 属性名称,这需要更新。上面的代码应该被分成更合适的类结构。

我现在不在 Mac 上,所以很遗憾我无法检查这是否有效。

希望对您有所帮助。

【讨论】:

  • 感谢您的帮助,我查看了 itune 集成部分,它很棒,现在我需要弄清楚如何将预加载的 csv 数据放入核心数据实体中,以便在我每次调用时出现应用中的详细视图
  • 已编辑原始帖子,详细介绍了将 .csv 数据添加到 Core Data 实体,希望对您有所帮助。
  • 您好,我有以下格式的文件并尝试使用 csvparser (github.com/ha-minh-vuong/CSVParser) csv 文件的屏幕截图在问题的编辑中。我不确定它是否适用于您提供的代码(您是否测试过它?)。在任何情况下检查更新的编辑。谢谢
  • 我可以发现一个问题——变量名错误。试试看:NSString *numberString = [row objectAtIndex:NSNumberColumn];NSString *dateString = [row objectAtIndex:NSDateColumn];我一回家就测试。
  • 上下文保存应该在 for 循环之外,因为根据当前的截断代码,它在每个循环中保存数据。而不是需要在所有迭代完成后保存上下文。
【解决方案2】:

尝试使用 plist 或 json,iOS 已经支持它们而不是 CSV。 CSV 需要第三方解析器。使用 json 或 plist 你只需要遍历集合的元素来创建你的持久存储。如果您只有 CSV,您可以使用不同的免费工具进行中间转换,这些工具可以在互联网上免费找到,然后添加到您的捆绑包或发布到您的网站。

【讨论】:

  • 我实际上尝试过使用 json 并且它非常灵活,但我只是在为想要将数据转储到应用程序中的普通用户进一步思考什么是最简单的格式。
  • 好点,所以需要类似github.com/ha-minh-vuong/CSVParser
  • 你好,那个 csvparser 很好,现在我可以解析 csv 文件并得到一个 NSarray,但我不知道如何用它填充核心数据实体....跨度>
  • 很好地遍历它,并在每个循环中填充您的托管对象并保存上下文。
【解决方案3】:

当您已经解析完 CSV 文件并准备好在 Objective-C 中使用数据时,您可以执行以下操作。

  1. 为导入创建单独的上下文。您不知道数据有多大,因此您可能不想在导入时阻止现有上下文之一。

  2. 遍历解析数据中的条目并插入从每个条目配置的新托管对象。

  3. 每 200、500 或 1000 个条目(每个人都不同,您需要测试什么最适合您)保存上下文,并在需要时发布一个批次已导入的通知。

  4. 要保持低内存,请重置上下文并忘记您在此导入上下文中创建的所有对象。

  5. 循环结束后,别忘了保存最后一次。

现在如何将数据带入另一个上下文,比如 UI 上下文?

这取决于您组织核心数据堆栈的方式。例如,导入上下文可以配置为 UI 上下文的子项。在这种情况下,每次保存到导入上下文后,更改将被推送到 UI 上下文(不要忘记保存 UI 上下文以进一步推送更改)。

但这不是最有效的方法,因为 UI 上下文是主线程上的上下文,它参与了导入,并且在阻塞它的 UI 线程上完成了额外的工作。我建议不要创建导入上下文,而是直接连接到持久存储协调器。在这种情况下,要对 UI 上下文进行更改,您需要在每次保存后调用 mergeChangesFromContextDidSaveNotification: 方法,或者您只需在每次保存后和最后重新获取 UI 上下文。后者在 UI 上下文上更容易,特别是在 NSFetchedResultsController 上,如果你使用它,因为它不需要一个一个地重放对更新对象的更改。

【讨论】:

  • 我了解算法,只是我在 iO 方面不够精通,无法以编程方式处理这个.....
猜你喜欢
  • 2012-05-26
  • 2016-07-07
  • 2011-03-31
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多