2010-09-07 33 views
1

我有基于CoreData的数据层(使用SQLite数据存储),我在iOS应用程序和服务器上使用iOS客户与之交谈。数据层(objc代码+ coredata模型/映射defns)按照惯例被编译到iOS包中,并被编译成一个Framework包以便在OSX上使用。CoreData无法在OSX框架包中找到映射模型,但在iOS中正常工作

我使用映射模型进行默认迁移的砖墙。

在iOS上,它工作正常。第一次在添加新数据模型版本后在模拟器中运行应用程序时,它会在您按照标准Apple文档呼叫addPersistentStoreWithType:configuration:...时迁移所有数据。

在OSX/PyObjC上,它以Persistent store migration failed, missing mapping model失败,即出于某种原因,映射模型.cdm文件无法在该包中找到,即使它存在。

如果您通过在包中查找来手动指定source/dest/mapping模型,然后通过NSMigrationManager手动调用迁移,则一切正常,例如,

bundle = objc.loadBundle("MyApp_OSX", globals(), 
          os.path.join(base, FRAMEWORK_FILENAME)) 

# URLs of input and output datastores 
datastoreURL = NSURL.fileURLWithPath_(datadir + "/MyApp.hsdb") 
outURL = NSURL.fileURLWithPath_(datadir + "/MyApp-migrated.hsdb") 

# URLs of old and new version MOMs and the mapping model 
momd = bundle.URLForResource_withExtension_("MyApp.momd", None) 
url1 = momd.URLByAppendingPathComponent_("MyApp 21.mom") 
url2 = momd.URLByAppendingPathComponent_("MyApp 22.mom") 
mappingURL = bundle.URLForResource_withExtension_("Test.cdm", None) 

# Old and new MOMs and the mapping model 
mom1 = NSManagedObjectModel.alloc().initWithContentsOfURL_(url1) 
mom2 = NSManagedObjectModel.alloc().initWithContentsOfURL_(url2) 
mm = NSMappingModel.alloc().initWithContentsOfURL_(mappingURL) 

# Do the migration  
migration = NSMigrationManager.alloc().initWithSourceModel_destinationModel_( 
    mom1, mom2) 

migration.migrateStoreFromURL_type_options_withMappingModel_toDestinationURL_destinationType_destinationOptions_error_(
    datastoreURL, NSSQLiteStoreType, None, mm, outURL, NSSQLiteStoreType, None, None) 

在这一点上我不知道为什么iOS版本能够找到映射模型成功迁移数据存储,但OSX/PyObjC版不能,尽管显然有被捆绑的映射模型,并且映射模型显然是有效的,因为它在您手动调用时起作用。

深入了解CoreData如何在捆绑包中搜索有效/适当的映射模型,以帮助确定如何在OSX上实现这项工作,我们将非常感激。

回答

1

我会怀疑有权限问题,因为这是iOS和Cocoa不同的地方,但是由于硬编码的URL起作用,情况并非如此。它看起来像一个NSBundle问题。

我会首先使用URLForResource:withExtension:的标准格式并分割名称和扩展名。这可能不是原因,但桥梁并不完美,你想消除任何可能的源错误。

如果您确认该文件夹中存在文件,请检查它是否有合理的路径。如果最终嵌套深度或路径名称中包含奇数字符,NSBundle可能找不到该文件。

+0

感谢您的回复TZ。我试着改变我的Python来分割文件名上的词干和扩展名,例如'mappingURL = bundle.URLForResource_withExtension_(“Test”,“cdm”)',它仍然在手动方法中工作,所以我不认为这是关于文件扩展名检测的一些事情被破坏。此外,cdm文件位于该软件包的基础'资源'目录中,所以我不认为这里有嵌套的事情。文件名中没有有趣的字符,所以我认为这也不是罪魁祸首。难倒! – glenc 2010-09-08 15:55:00

+0

另外 - 我检查了捆绑包中文件的权限,一切都看起来很理智。正如您所期望的,所有.cdm文件都处于模式0644中,所以我不认为这是权限问题。 – glenc 2010-09-08 16:09:34

+0

最后一件事 - 我不认为PyObjC桥应该在这里扮演一个角色,因为实际调用'NSPersistentStoreCoordinator#addPersistentStoreWithType:configuration:...'是在**里面完成**我已经实现了一个objc方法,我从Python中调用该方法,而不是直接调用'addPersistentStoreWithType'。所以'addPersistentStoreWithType'的调用上下文(至少和函数arg编组一样)在两种情况下都应该是相同的...... – glenc 2010-09-08 16:13:30

相关问题