Skip to content

Commit

Permalink
Migrate existing data into shared app groups
Browse files Browse the repository at this point in the history
  • Loading branch information
GianniCarlo committed Oct 30, 2018
1 parent 98f221e commit dd8ec81
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 8 deletions.
3 changes: 3 additions & 0 deletions BookPlayer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,9 @@
DevelopmentTeam = FV9NULGJG4;
LastSwiftMigration = 0900;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
com.apple.BackgroundModes = {
enabled = 1;
};
Expand Down
6 changes: 0 additions & 6 deletions BookPlayer/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
defaults.set(true, forKey: Constants.UserDefaults.completedFirstLaunch.rawValue)
}

// Migrate file security to make autoplay on background work
if !defaults.bool(forKey: Constants.UserDefaults.fileProtectionMigration.rawValue) {
DataManager.makeFilesPublic()
defaults.set(true, forKey: Constants.UserDefaults.fileProtectionMigration.rawValue)
}

// Appearance
UINavigationBar.appearance().titleTextAttributes = [
NSAttributedStringKey.foregroundColor: UIColor.init(hex: "#37454E")
Expand Down
4 changes: 4 additions & 0 deletions BookPlayer/BookPlayer.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.tortugapower.bookplayer.files</string>
</array>
</dict>
</plist>
2 changes: 1 addition & 1 deletion BookPlayer/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ enum Constants {
enum UserDefaults: String {
// Application information
case completedFirstLaunch = "userSettingsCompletedFirstLaunch"
case fileProtectionMigration = "userSettingsFileProtectionMigration"
case appGroupsMigration = "userSettingsAppGroupsMigration"
case lastPauseTime = "userSettingsLastPauseTime"
case lastPlayedBook = "userSettingsLastPlayedBook"

Expand Down
35 changes: 34 additions & 1 deletion BookPlayer/Library/FileManagement/DataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class DataManager {
return processedFolderURL
}

private static var storeUrl: URL {
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.tortugapower.bookplayer.files")!.appendingPathComponent("BookPlayer.sqlite")
}

// MARK: - Operations
class func start(_ operation: Operation) {
self.queue.addOperation(operation)
Expand All @@ -60,9 +64,38 @@ class DataManager {
}

// MARK: - Core Data stack
class func migrateStack() throws {
let name = "BookPlayer"
let container = NSPersistentContainer(name: name)
let psc = container.persistentStoreCoordinator

let oldStoreUrl = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last!
.appendingPathComponent("\(name).sqlite")

let options = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true
]

guard let oldStore = try? psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: oldStoreUrl, options: options) else {
// couldn't load old store
return
}

try psc.migratePersistentStore(oldStore, to: self.storeUrl, options: nil, withType: NSSQLiteStoreType)
}

private static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "BookPlayer")
let name = "BookPlayer"

let container = NSPersistentContainer(name: name)

let description = NSPersistentStoreDescription()
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.url = storeUrl

container.persistentStoreDescriptions = [description]

container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error as NSError? {
Expand Down
27 changes: 27 additions & 0 deletions BookPlayer/Library/LibraryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ class LibraryViewController: BaseListViewController, UIGestureRecognizerDelegate

self.loadLibrary()

// handle CoreData migration into shared app groups
if !UserDefaults.standard.bool(forKey: Constants.UserDefaults.appGroupsMigration.rawValue) {
self.migrateCoreDataStack()
UserDefaults.standard.set(true, forKey: Constants.UserDefaults.appGroupsMigration.rawValue)
}

guard let identifier = UserDefaults.standard.string(forKey: Constants.UserDefaults.lastPlayedBook.rawValue),
let item = self.library.getItem(with: identifier) else {
return
Expand Down Expand Up @@ -75,6 +81,27 @@ class LibraryViewController: BaseListViewController, UIGestureRecognizerDelegate
DataManager.notifyPendingFiles()
}

/**
* Migrates existing stack into the new container app groups.
* In case it fails, it loads all the files from the Processed folder
*/
func migrateCoreDataStack() {
DataManager.makeFilesPublic()
do {
try DataManager.migrateStack()
} catch {
// Migration failed, fallback: load all books from processed folder
if let fileUrls = DataManager.getFiles(from: DataManager.getProcessedFolderURL()) {
let fileItems = fileUrls.map { (url) -> FileItem in
return FileItem(originalUrl: url, processedUrl: url, destinationFolder: url)
}
DataManager.insertBooks(from: fileItems, into: self.library) {
self.reloadData()
}
}
}
}

override func handleOperationCompletion(_ files: [FileItem]) {
DataManager.insertBooks(from: files, into: self.library) {
self.reloadData()
Expand Down

0 comments on commit dd8ec81

Please sign in to comment.