如何在我的项目中创建第二个目标来为 iOS 创建一个预填充的数据库
Posted
技术标签:
【中文标题】如何在我的项目中创建第二个目标来为 iOS 创建一个预填充的数据库【英文标题】:How do I create second target in my project to create a pre-populated database for iOS 【发布时间】:2011-08-17 16:19:38 【问题描述】:我目前有一个 ios 应用程序,它可以从一堆 pList 文件中“引导”它的数据库(我在开发期间有数据库更改时使用)或复制预先存在的数据库以在设备上首次运行(我使用在模拟器中创建的数据库)。
这变得一团糟:我必须翻转标志来决定我是否正在引导,我不想意外分发“引导”版本,我也不想分发 plist(那么目标设备将拥有 3 个数据副本:捆绑的 db、plist 和 db 的可写副本。
我想做的是创建一个使用相同对象模型的单独桌面应用程序。 plist 将由桌面应用程序使用,我将运行它来生成数据库(或者甚至可能为数据库调整提供 GUI!)。 iPhone 和桌面应用程序将共享相同的数据模型。并且桌面应用程序会写入与 iOS 应用程序捆绑在一起的数据库,所以我不必记得从模拟器中复制。
到目前为止,我已经能够找到一些帖子说这样做很简单......但是教程或提示会有所帮助。
【问题讨论】:
曾经有一个非常方便的技巧,您可以将 CoreData 对象从模型中选择拖动到 nib 文件中以自动生成 UI,但我似乎无法在Xcode 4. :-( 【参考方案1】:萨沙,
我在现有项目中创建了一个新目标,并且能够创建我的自举核心数据数据库。这一点都不难。您可以重复使用大部分现有代码。
安德鲁
【讨论】:
谢谢安德鲁。听起来您正在做我想做的事,但是我不确定在项目中添加了第二个目标后该怎么做。 (到目前为止,我所有的项目都是非常简单的单目标应用程序)。一旦我创建了第二个目标,您可以提供的任何关于如何设置我的第二个目标的指示(包括在文档中查找的位置,如果这是最简单的)将是最有帮助的。谢谢! Sasha,目标只是代码和构建规则的集合。它在 Apple 的各种 Xcode 文档中有很好的记录。在您的情况下,您希望构建一个应用程序来创建数据库,并以适当的方式设置所有标志。如果您正在构建一个 iOS 应用程序,那么您可能希望在模拟器中运行。完成构建应用程序后,将其与其他资源一起放置,然后编写一些代码将其移出捆绑包并移入文档文件夹。然后它的行为就好像它最初是在那里创建的。安德鲁【参考方案2】:你有很多选择。您可以创建一个并行应用程序,其唯一职责是在您的主应用程序中预填充数据库。或者您可以使用脚本直接填充数据库文件。我提供了一个很好的教程的链接,该教程描述了后一种方法。
http://www.raywenderlich.com/980/core-data-tutorial-how-to-preloadimport-existing-data
【讨论】:
感谢知觉。 Ray Wenderlinch 有一些非常棒的教程。这个唯一的问题是它让你弄乱了 sqlite 中的模式,这可能有效但不受 Apple 支持,因此可能会在路上咬你。但请相信我,这并不是说我没有受到诱惑,这会容易得多。【参考方案3】:我看到在我从事的项目中处理这个问题的方式很简单。制作两个目标,并为每个目标配置适当的标志。你会有你的“旗帜翻转”,但不会那么复杂,你可以很容易地分辨出你正在建造哪一个。
【讨论】:
【参考方案4】:从您的问题看来,您似乎可以在桌面上创建 Core Data Persistent Store。 (这里需要注意的是确保您使用的是共享的核心数据模型。)
鉴于此,您应该将 DB 捆绑为应用程序资源,如果在应用程序启动时找不到它,则将其复制到位。
你应该这样做:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if (![self persistentStoreExists]) // First run.
[self copyPersistentStoreFromBundleResources];
// ... continue here.
#pragma mark -
#pragma mark First Run Core Data Import
- (BOOL)persistentStoreExists
NSString *storePath = [[[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite" ] path];
NSFileManager *fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:storePath];
- (void)copyPersistentStoreFromBundleResources
NSLog(@"Installing default DB from bundle.");
NSString *storePath = [[[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite" ] path];
NSString *defaultStorePath = [[NSBundle mainBundle]
pathForResource:@"MyApp" ofType:@"sqlite"];
if (defaultStorePath == nil)
NSLog(@"Error finding default store");
return;
else
BOOL copiedDefaultStore = [[NSFileManager defaultManager]
copyItemAtPath:defaultStorePath
toPath:storePath
error:nil];
if (! copiedDefaultStore)
NSLog(@"Error copying default store");
return;
#pragma mark -
#pragma mark Application's Documents directory
/**
Returns the URL to the application's Documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
【讨论】:
谢谢卡尔顿。如果数据库不存在,我的启动代码可以正常工作以复制数据库(尽管乍一看你在这里得到的东西看起来更干净,但我可能会改用它)。我遇到的问题是首先生成数据库,并在两个应用程序之间共享数据模型。我会在原来的问题中澄清这一点......以上是关于如何在我的项目中创建第二个目标来为 iOS 创建一个预填充的数据库的主要内容,如果未能解决你的问题,请参考以下文章