iOS:从 JSON 切换到 CoreData 以保持本地持久数据;这实用吗?数组内字典 数组内字典

Posted

技术标签:

【中文标题】iOS:从 JSON 切换到 CoreData 以保持本地持久数据;这实用吗?数组内字典 数组内字典【英文标题】:iOS: Switching from JSON to CoreData for keeping local persistent data; is this practical? Dictionary within array within dictionary within array 【发布时间】:2014-07-02 14:31:10 【问题描述】:

我上个月开始使用 Swift 和 ios。我正在开发一款 iPhone 健身应用程序,专门用于举重。到目前为止,我一直在应用程序的文档文件夹中使用 JSON 文件来存储所有用户的锻炼,并使用 let workoutData = NSJSONSerialization.JSONObjectWithData( . . . ) as NSArray 从文件中加载数据(以类似 UITableView 的格式显示),然后添加新的锻炼条目:

let newEntry: NSData = NSJSONSerialization.dataWithJSONObject(newData, options: .PrettyPrinted, error: nil)
newEntry.writeToFile(documentsPath, atomically: true)

起初这很好用,但现在我需要能够编辑锻炼、在任意日期添加新锻炼或删除特定锻炼。这需要在数组中的字典中进行大量循环,并且正确地对锻炼进行排序变得很困难。

考虑到我的数据性质,我觉得 CoreData 可能是未来的最佳选择。也就是说,这是我的 JSON 数据库结构的一个示例:

    [
  
  "day": "Thursday",
  "date": "June 5 2014",
  "lbs": true,
  "lifts": [
            
            "name": "SQUAT",
            "sets": 1,
            "reps": 5,
            "weight": 205,
            "warmup": true
            ,
            
            "name": "SQUAT",
            "sets": 3,
            "reps": 5,
            "weight": 245,
            ,
            
            "name": "BENCH PRESS",
            "sets": 1,
            "reps": 5,
            "weight": 135,
            "warmup": true
            ,
            
            "name": "BENCH PRESS",
            "sets": 3,
            "reps": 5,
            "weight": 185
            ,
            
            "name": "YATES ROW",
            "sets": 3,
            "reps": 5,
            "weight": 135,
            
            ]
  ,
  
  "day": "Wednesday",
  "date": "June 3 2014",
  "lbs": true,
  "lifts": [
            
            "name": "DEADLIFT",
            "sets": 1,
            "reps": 3,
            "weight": 255,
            "warmup": true
            ,
            
            "name": "DEADLIFT",
            "sets": 1,
            "reps": 5,
            "weight": 305,
            ,
            
            "name": "OVERHEAD PRESS",
            "sets": 1,
            "reps": 5,
            "weight": 95,
            "warmup": true
            ,
            
            "name": "OVERHEAD PRESS",
            "sets": 3,
            "reps": 5,
            "weight": 125
            ,
            
            "name": "CHIN-UPS",
            "sets": 3,
            "reps": 5,
            "weight": 180,
            
            ]
  ,
  
  "day": "Monday",
  "date": "June 1 2014",
  "lbs": true,
  "lifts": [

  ]
  
  ]

所以结构是:

    ***数组,包含每个锻炼日字典 锻炼日期字典,包含日期字符串、日期字符串和升降机数组 升降机阵列,每个升降机本身都是一本字典 举重字典,包含举重名称、组数、次数、重量和一个布尔值,指示这是否是热身组。

CoreData 实体似乎只允许相当简单的属性。我想我可以使用“Transformable”属性,或者使用很多 To-Many 关系,但如果没有必要,我宁愿不去学习这些。

那么,我应该把它搞定并弄清楚如何在 CoreData 中实现同样的结构吗?或者,这个数据结构是不是太复杂了?我是否应该完全摆脱数组/字典而只拥有一个扁平的“锻炼”实体,然后从 CoreData 加载数据后,在 ViewController 中手动将相同日期/类型的所有锻炼收集到组中?

或者,考虑到我的数据的性质,有没有比 CoreData 或 JSON 更适合使用的东西?也许是 SQLite?

【问题讨论】:

【参考方案1】:

如果我是你,我会使用 CoreData 或 CloudKit(用于在线存储)。原因是如果我是用户,并且我的训练跨越了一年,并且每次训练都有大量数据。这将永远加载到内存中。因此,您将不得不找出一种方法来分割您的数据,否则您的用户可能会等待一段时间才能将文件读入内存,或者文件可能会变得比分配的更大并且不会可以阅读。

我不知道您为什么说很难将这些存储到数据库中。在我看来,您已经有了一个可以相当容易地转换为 DBM 的结构。我认为你的表格应该是这样的:

锻炼:表 #1 wid(主键) 日期(时间戳) 电梯(数组:外键) 升降机:表 #2 盖子(主键) 名称(字符串) 套(数量) 代表(次数) 重量(个数) 热身(布尔)

不要害怕数据库,它们真的没有那么糟糕,它比将它们存储在文件中效率高 1000%。

【讨论】:

那么最好在数据库中定义结构,而不是我自己?我总是可以简单地拥有一个大型电梯数据库,并添加一个日期属性;然后当我填充 TableView 时,我可以选择一个日期范围,然后用该日期的所有升降机填充每个日期部分。这很糟糕吗? 抱歉,第一次使用 ***。我点击返回,以为它会开始新的一行。 @Hal Nope,这就是这样做的方法。基本上,您将使用NSPredicates 在数据库表中“选择”您的行,您将获取您的数据并使用它来填充您的 UITableViews。

以上是关于iOS:从 JSON 切换到 CoreData 以保持本地持久数据;这实用吗?数组内字典 数组内字典的主要内容,如果未能解决你的问题,请参考以下文章

从 CoreData 在 NSDictionary 中制作嵌套 JSON

将 iOS 应用从 NSCoding 转换为 Core Data

从集合视图移动到详细视图时如何利用 CoreData

在后台下载数据的同时,从 JSON 中下载数据并存储到 CoreData 和 Display

使用存储的 JSON 而不是 Core Data

填充 TableView 中的 JSON 数组和 CoreData