iPhone和Core Data:如何在更新之间保留用户输入的数据? [英] iPhone and Core Data: how to retain user-entered data between updates?

查看:110
本文介绍了iPhone和Core Data:如何在更新之间保留用户输入的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个iPhone应用程序,它是一个动物目录。应用程序应该允许用户为每个动物添加自定义信息 - 让我们说一个评分(1到5的等级),以及他们可以在动物中输入的一些注释。然而,用户将不能修改动物数据本身。假设当应用程序更新时,(静态)目录部分应该很容易更改,但我们希望(动态)自定义用户信息部分在更新之间保留,因此用户不会丢失任何他们的自定义信息。

Consider an iPhone application that is a catalogue of animals. The application should allow the user to add custom information for each animal -- let's say a rating (on a scale of 1 to 5), as well as some notes they can enter in about the animal. However, the user won't be able to modify the animal data itself. Assume that when the application gets updated, it should be easy for the (static) catalogue part to change, but we'd like the (dynamic) custom user information part to be retained between updates, so the user doesn't lose any of their custom information.

我们可能想使用Core Data来构建此应用程序。让我们说,我们有一个以前的过程已经到位,以读取动物数据,以预先填充Core Data使用的支持(SQLite)存储。我们可以将此数据库文件嵌入应用程序包本身,因为它不会被修改。当用户将更新下载到应用程序时,新版本将包含最新(静态)动物目录数据库,因此我们不必担心它过时。

We'd probably want to use Core Data to build this app. Let's also say that we have a previous process already in place to read in animal data to pre-populate the backing (SQLite) store that Core Data uses. We can embed this database file into the application bundle itself, since it doesn't get modified. When a user downloads an update to the application, the new version will include the latest (static) animal catalogue database, so we don't ever have to worry about it being out of date.

但是,现在棘手的部分:我们如何以一种健全的方式存储(动态)用户自定义数据?

But, now the tricky part: how do we store the (dynamic) user custom data in a sound manner?

我的第一个想法是动态)数据库应存储在应用程序的Documents目录中,因此应用程序更新不会破坏现有数据。

My first thought is that the (dynamic) database should be stored in the Documents directory for the app, so application updates don't clobber the existing data. Am I correct?

我的第二个想法是,由于(动态)用户自定义数据库与(静态)动物目录不在同一个商店,我们可以'初始化Rating和Notes实体(在一个数据库中)和Animal实体(在另一个数据库中)之间的关系。在这种情况下,我想象一个解决方案是在Rating / Notes实体中有一个animalName字符串属性,并在运行时匹配它。这是最好的方法,还是有一种方法来同步两个不同的数据库在Core Data?

My second thought is that since the (dynamic) user custom data database is not in the same store as the (static) animal catalogue, we can't naively make a relationship between the Rating and the Notes entities (in one database) and the Animal entity (in the other database). In this case, I would imagine one solution would be to have an "animalName" string property in the Rating/Notes entity, and match it up at runtime. Is this the best way to do it, or is there a way to "sync" two different databases in Core Data?

推荐答案

虽然Amorya和MHarrison的答案是有效的,但他们有一个假设:一旦创建,不仅表格,而且每一行

While Amorya's and MHarrison's answers were valid, they had one assumption: that once created, not only the tables but each row in each table would always be the same.

问题是,我使用现有数据(周期性更新)预填充动物数据库的过程创建了一个新的数据库文件。换句话说,我不能依赖在Core Data中创建(静态)动物实体和(动态)Rating实体之间的关系,因为下一次重新生成应用程序时,该实体可能不存在。为什么不?因为我没有控制Core Data如何在幕后存储这种关系。因为它是一个SQLite后备存储,它可能是使用一个有外键关系的表。但是当你重新生成数据库时,你不能假设任何关于每行获得一个键的值。

The problem is that my process to pre-populate the "Animals" database, using existing data (that is updated periodically), creates a new database file each time. In other words, I can't rely on creating a relationship between the (static) Animal entity and a (dynamic) Rating entity in Core Data, since that entity may not exist the next time I regenerate the application. Why not? Because I have no control how Core Data is storing that relationship behind the scenes. Since it's an SQLite backing store, it's likely that it's using a table with foreign key relations. But when you regenerate the database, you can't assume anything about what values each row gets for a key. The primary key for Lion may be different the second time around, if I've added a Lemur to the list.

避免这个问题的唯一方法是需要预先设置一个Lemur,只填充数据库一次,然后每次有更新时手动更新行。但是,这种过程在我的情况下是不可能的。

The only way to avoid this problem would require pre-populating the database only once, and then manually updating rows each time there's an update. However, that kind of process isn't really possible in my case.

那么,解决方案是什么?那么,既然我不能依赖Core Data做的外键关系,我必须自己做。我做的是在我的数据库生成过程中引入一个中间步骤:而不是采取我的原始数据(这恰恰是UTF-8文本,但实际上是MS Word文件),并直接创建与Core Data SQLite数据库,我介绍一个中介步骤:我将.txt转换为.xml。为什么选择XML?好吧,不是因为它是一个银弹,而只是因为它是一个数据格式我可以很容易解析。那么这个XML文件有什么不同?我为每个动物生成的哈希值,使用MD5,我将假设是唯一的。什么是哈希值?好了,现在我可以创建两个数据库:一个用于静态动物数据(我已经有一个进程),一个用于动态评分数据库,iPhone应用程序创建并存储在应用程序的文档目录。对于每个Rating,我通过保存动物实体的哈希值与Animal创建一个伪关系。因此,每当用户在iPhone上引出动物详细视图时,我查询动态数据库,以查找是否存在与Animal.md5Hash值匹配的Rating实体。

So, what's the solution? Well, since I can't rely on the foreign key relations that Core Data makes, I have to make up my own. What I do is introduce an intermediate step in my database generation process: instead of taking my raw data (which happens to be UTF-8 text but is actually MS Word files) and creating the SQLite database with Core Data directly, I introduce an intermediary step: I convert the .txt to .xml. Why XML? Well, not because it's a silver bullet, but simply because it's a data format I can parse very easily. So what does this XML file have different? A hash value that I generate for each Animal, using MD5, that I'll assume is unique. What is the hash value for? Well, now I can create two databases: one for the "static" Animal data (for which I have a process already), and one for the "dynamic" Ratings database, which the iPhone app creates and which lives in the application's Documents directory. For each Rating, I create a pseudo-relationship with the Animal by saving the Animal entity's hash value. So every time the user brings up an Animal detail view on the iPhone, I query the "dynamic" database to find if a Rating entity exists that matches the Animal.md5Hash value.

因为我保存这个中间XML数据文件,下次有一个更新,我可以对比我用来看看什么改变的最后一个XML文件。现在,如果一个动物的名称改变了 - 让我们说一个拼写错误 - 我恢复该动物的原位哈希值。这意味着即使动物名称改变了,我仍然可以在动态数据库中找到匹配的评分(如果存在)。

Since I'm saving this intermediate XML data file, the next time there's an update, I can diff it against the last XML file I used to see what's changed. Now, if the name of an animal was changed -- let's say a typo was corrected -- I revert the hash value for that Animal in situ. This means that even if an Animal name is changed, I'll still be able to find a matching Rating, if it exists, in the "dynamic" database.

解决方案有另一个好的副作用:我不需要处理任何迁移问题。 应用程序附带的静态动物数据库可以保留嵌入作为应用程序资源。它可以改变它想要的一切。如果我修改其数据模型以添加更多实体,但是实际上这两个数据模型保持完全独立,那么动态评级数据库可能需要在某一点进行迁移。

This solution has another nice side effect: I don't need to handle any migration issues. The "static" Animal database that ships with the app can stay embedded as an app resource. It can change all it wants. The "dynamic" Ratings database may need migration at some point, if I modify its data model to add more entities, but in effect the two data models stay totally independent.

这篇关于iPhone和Core Data:如何在更新之间保留用户输入的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆