AppDelegate.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import UIKit
  19. import RealmSwift
  20. // Old data models
  21. /* V0
  22. class Person: Object {
  23. @objc dynamic var firstName = ""
  24. @objc dynamic var lastName = ""
  25. @objc dynamic var age = 0
  26. }
  27. */
  28. /* V1
  29. class Person: Object {
  30. @objc dynamic var fullName = "" // combine firstName and lastName into single field
  31. @objc dynamic var age = 0
  32. }
  33. */
  34. /* V2 */
  35. class Pet: Object {
  36. @objc dynamic var name = ""
  37. @objc dynamic var type = ""
  38. }
  39. class Person: Object {
  40. @objc dynamic var fullName = ""
  41. @objc dynamic var age = 0
  42. let pets = List<Pet>() // Add pets field
  43. }
  44. func bundleURL(_ name: String) -> URL? {
  45. return Bundle.main.url(forResource: name, withExtension: "realm")
  46. }
  47. #if !swift(>=4.2)
  48. extension UIApplication {
  49. typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey
  50. }
  51. #endif
  52. @UIApplicationMain
  53. class AppDelegate: UIResponder, UIApplicationDelegate {
  54. var window: UIWindow?
  55. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
  56. window = UIWindow(frame: UIScreen.main.bounds)
  57. window?.rootViewController = UIViewController()
  58. window?.makeKeyAndVisible()
  59. // copy over old data files for migration
  60. let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
  61. let defaultParentURL = defaultURL.deletingLastPathComponent()
  62. if let v0URL = bundleURL("default-v0") {
  63. do {
  64. try FileManager.default.removeItem(at: defaultURL)
  65. try FileManager.default.copyItem(at: v0URL, to: defaultURL)
  66. } catch {}
  67. }
  68. // define a migration block
  69. // you can define this inline, but we will reuse this to migrate realm files from multiple versions
  70. // to the most current version of our data model
  71. let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
  72. if oldSchemaVersion < 1 {
  73. migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
  74. if oldSchemaVersion < 1 {
  75. // combine name fields into a single field
  76. let firstName = oldObject!["firstName"] as! String
  77. let lastName = oldObject!["lastName"] as! String
  78. newObject?["fullName"] = "\(firstName) \(lastName)"
  79. }
  80. }
  81. }
  82. if oldSchemaVersion < 2 {
  83. migration.enumerateObjects(ofType: Person.className()) { _, newObject in
  84. // give JP a dog
  85. if newObject?["fullName"] as? String == "JP McDonald" {
  86. let jpsDog = migration.create(Pet.className(), value: ["Jimbo", "dog"])
  87. let dogs = newObject?["pets"] as? List<MigrationObject>
  88. dogs?.append(jpsDog)
  89. }
  90. }
  91. }
  92. print("Migration complete.")
  93. }
  94. Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 3, migrationBlock: migrationBlock)
  95. // print out all migrated objects in the default realm
  96. // migration is performed implicitly on Realm access
  97. print("Migrated objects in the default Realm: \(try! Realm().objects(Person.self))")
  98. //
  99. // Migrate a realms at a custom paths
  100. //
  101. if let v1URL = bundleURL("default-v1"), let v2URL = bundleURL("default-v2") {
  102. let realmv1URL = defaultParentURL.appendingPathComponent("default-v1.realm")
  103. let realmv2URL = defaultParentURL.appendingPathComponent("default-v2.realm")
  104. let realmv1Configuration = Realm.Configuration(fileURL: realmv1URL, schemaVersion: 2, migrationBlock: migrationBlock)
  105. let realmv2Configuration = Realm.Configuration(fileURL: realmv2URL, schemaVersion: 3, migrationBlock: migrationBlock)
  106. do {
  107. try FileManager.default.removeItem(at: realmv1URL)
  108. try FileManager.default.copyItem(at: v1URL, to: realmv1URL)
  109. try FileManager.default.removeItem(at: realmv2URL)
  110. try FileManager.default.copyItem(at: v2URL, to: realmv2URL)
  111. } catch {}
  112. // migrate realms at realmv1Path manually, realmv2Path is migrated automatically on access
  113. try! Realm.performMigration(for: realmv1Configuration)
  114. // print out all migrated objects in the migrated realms
  115. let realmv1 = try! Realm(configuration: realmv1Configuration)
  116. print("Migrated objects in the Realm migrated from v1: \(realmv1.objects(Person.self))")
  117. let realmv2 = try! Realm(configuration: realmv2Configuration)
  118. print("Migrated objects in the Realm migrated from v2: \(realmv2.objects(Person.self))")
  119. }
  120. return true
  121. }
  122. }