diff --git a/Mastodon/Supporting Files/AppDelegate.swift b/Mastodon/Supporting Files/AppDelegate.swift index 2778baad6..79eaeb5cd 100644 --- a/Mastodon/Supporting Files/AppDelegate.swift +++ b/Mastodon/Supporting Files/AppDelegate.swift @@ -18,7 +18,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let appContext = AppContext() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - AuthenticationServiceProvider.shared.migrateLegacyAuthenticationsIfRequired(in: appContext.managedObjectContext) AuthenticationServiceProvider.shared.restore() AppSecret.default.register() diff --git a/MastodonIntent/Handler/SendPostIntentHandler.swift b/MastodonIntent/Handler/SendPostIntentHandler.swift index b457b1c91..af56ad523 100644 --- a/MastodonIntent/Handler/SendPostIntentHandler.swift +++ b/MastodonIntent/Handler/SendPostIntentHandler.swift @@ -17,7 +17,7 @@ final class SendPostIntentHandler: NSObject { var disposeBag = Set() - let coreDataStack = CoreDataStack() + let coreDataStack = CoreDataStack(isInMemory: true) lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext lazy var api: APIService = { let backgroundManagedObjectContext = coreDataStack.newTaskContext() diff --git a/MastodonSDK/Sources/CoreDataStack/CoreDataStack.swift b/MastodonSDK/Sources/CoreDataStack/CoreDataStack.swift index 48e69e375..ce512f303 100644 --- a/MastodonSDK/Sources/CoreDataStack/CoreDataStack.swift +++ b/MastodonSDK/Sources/CoreDataStack/CoreDataStack.swift @@ -22,10 +22,15 @@ public final class CoreDataStack { self.storeDescriptions = storeDescriptions } - public convenience init(databaseName: String = "shared") { + public convenience init(databaseName: String = "shared", isInMemory: Bool) { let storeURL = URL.storeURL(for: AppName.groupID, databaseName: databaseName) - let storeDescription = NSPersistentStoreDescription(url: storeURL) - storeDescription.url = URL(fileURLWithPath: "/dev/null") /// in-memory store with all features in favor of NSInMemoryStoreType + let storeDescription: NSPersistentStoreDescription + if isInMemory { + storeDescription = NSPersistentStoreDescription(url: URL(string: "file:///dev/null")!) /// in-memory store with all features in favor of NSInMemoryStoreType + } else { + storeDescription = NSPersistentStoreDescription(url: storeURL) + storeDescription.isReadOnly = true + } self.init(persistentStoreDescriptions: [storeDescription]) } @@ -123,16 +128,18 @@ extension CoreDataStack { } } -extension CoreDataStack { - - public func rebuild() { +public extension CoreDataStack { + func tearDown() { let oldStoreURL = persistentContainer.persistentStoreCoordinator.url(for: persistentContainer.persistentStoreCoordinator.persistentStores.first!) try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: oldStoreURL, ofType: NSSQLiteStoreType, options: nil) + } + + func rebuild() { + tearDown() CoreDataStack.load(persistentContainer: persistentContainer) { [weak self] in guard let self = self else { return } self.didFinishLoad.value = true } } - } diff --git a/MastodonSDK/Sources/MastodonCore/AppContext.swift b/MastodonSDK/Sources/MastodonCore/AppContext.swift index d8aa06fae..12eea2519 100644 --- a/MastodonSDK/Sources/MastodonCore/AppContext.swift +++ b/MastodonSDK/Sources/MastodonCore/AppContext.swift @@ -47,7 +47,14 @@ public class AppContext: ObservableObject { .eraseToAnyPublisher() public init() { - let _coreDataStack = CoreDataStack() + + /// Migrate existing Authentications to new Keychain-Based format +// var _legacyCoreDataStack: CoreDataStack? = CoreDataStack(isInMemory: false) +// AuthenticationServiceProvider.shared.migrateLegacyAuthenticationsIfRequired(in: _legacyCoreDataStack!.persistentContainer.viewContext) +// _legacyCoreDataStack!.tearDown() +// _legacyCoreDataStack = nil + + let _coreDataStack = CoreDataStack(isInMemory: true) let _managedObjectContext = _coreDataStack.persistentContainer.viewContext let _backgroundManagedObjectContext = _coreDataStack.persistentContainer.newBackgroundContext() coreDataStack = _coreDataStack diff --git a/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift b/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift index f7ec62718..81d0c2da7 100644 --- a/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift +++ b/MastodonSDK/Sources/MastodonCore/AuthenticationServiceProvider.swift @@ -69,27 +69,43 @@ public extension AuthenticationServiceProvider { } func migrateLegacyAuthenticationsIfRequired(in context: NSManagedObjectContext) { - guard !userDefaults.didMigrateAuthentications else { return } +// guard !userDefaults.didMigrateAuthentications else { return } defer { userDefaults.didMigrateAuthentications = true } do { - let request = NSFetchRequest(entityName: "MastodonAuthentication") + let request = NSFetchRequest(entityName: "MastodonAuthentication") let legacyAuthentications = try context.fetch(request) - self.authentications = legacyAuthentications.map { auth in - MastodonAuthentication( - identifier: auth.identifier, - domain: auth.domain, - username: auth.username, - appAccessToken: auth.appAccessToken, - userAccessToken: auth.userAccessToken, - clientID: auth.clientID, - clientSecret: auth.clientSecret, - createdAt: auth.createdAt, - updatedAt: auth.updatedAt, - activedAt: auth.activedAt, - userID: auth.userID + self.authentications = legacyAuthentications.compactMap { auth -> MastodonAuthentication? in + guard + let identifier = auth.value(forKey: "identifier") as? UUID, + let domain = auth.value(forKey: "domain") as? String, + let username = auth.value(forKey: "username") as? String, + let appAccessToken = auth.value(forKey: "appAccessToken") as? String, + let userAccessToken = auth.value(forKey: "userAccessToken") as? String, + let clientID = auth.value(forKey: "clientID") as? String, + let clientSecret = auth.value(forKey: "clientSecret") as? String, + let createdAt = auth.value(forKey: "createdAt") as? Date, + let updatedAt = auth.value(forKey: "updatedAt") as? Date, + let activedAt = auth.value(forKey: "activedAt") as? Date, + let userID = auth.value(forKey: "userID") as? String + + else { + return nil + } + return MastodonAuthentication( + identifier: identifier, + domain: domain, + username: username, + appAccessToken: appAccessToken, + userAccessToken: userAccessToken, + clientID: clientID, + clientSecret: clientSecret, + createdAt: createdAt, + updatedAt: updatedAt, + activedAt: activedAt, + userID: userID ) } } catch {