我正在使用realmSwift开发应用程序。我想最初在realm db上设置预设数据,然后我希望它在用户打开应用程序时显示并使其可写。我根据有关域绑定的其他问题编写了一些代码。例如Realm - Add file with initial data to project (iOS/Swift)和Realm fileExists is always true 然后我设法在模拟器上做我想做的事,但它不能在物理设备上工作。这是我在AppDelegate上编写的代码
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
openRealm()
let config = Realm.Configuration(
fileURL: Bundle.main.url(forResource: "default", withExtension: "realm"),
readOnly: true)
var realm = try! Realm(configuration: config)
print(Realm.Configuration.defaultConfiguration.fileURL)
return true
}
func openRealm() {
let realm = try! Realm()
let bundlePath = Bundle.main.path(forResource: "default", ofType: "realm")
let destPath = Realm.Configuration.defaultConfiguration.fileURL?.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: destPath!) {
//File exist, do nothing
print("File exist")
try! fileManager.removeItem(atPath: destPath!)
do {
//Copy file from bundle to Realm default path
try fileManager.copyItem(atPath: bundlePath!, toPath: destPath!)
print("Copied")
} catch {
print("\n",error)
}
} else {
do {
try fileManager.copyItem(atPath: bundlePath!, toPath: destPath!)
print("Copied")
} catch {
print("\n",error)
}
}
}
答案 0 :(得分:1)
您的代码有3个问题:首先,您不应该使用if分支的true
部分,因为只要您从AppDelegate的openRealm()
运行applicationDidFinishLaunching
在您对Realm
进行任何调用之前,default.realm
文件存在的唯一原因是因为您的应用未首次启动,因此您不应该覆盖它。
其次,您不应该在let realm = try! Realm()
函数的开头调用openRealm
,因为这实际上会创建一个realm
,这将比检测它更难如果预先填充的.realm
文件已经复制到defaultPath
。实际上,您根本不需要在try! Realm()
函数中调用openRealm()
,除非您想在从代码中的任何其他位置打开Realm之前执行迁移。
func openRealm() {
let bundlePath = Bundle.main.path(forResource: "default", ofType: "realm")!
let defaultPath = Realm.Configuration.defaultConfiguration.fileURL?.path!
let fileManager = FileManager.default
// Only need to copy the prepopulated `.realm` file if it doesn't exist yet
if !fileManager.fileExists(atPath: defaultPath){
print("use pre-populated database")
do {
try fileManager.copyItem(atPath: bundlePath, toPath: defaultPath)
print("Copied")
} catch {
print(error)
}
}
最后,您不应该使用Realm
覆盖bundlePath
的路径来创建新配置,因为应用程序包中的文件不应该被修改(这将破坏您的代码签名)。此外,您已将预填充文件从应用程序包复制到Realm的defaultPath
,因此如果您只是调用Realm()
,它将修改预填充文件,因为它存储在默认位置。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
openRealm()
print(Realm.Configuration.defaultConfiguration.fileURL)
return true
}