mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Tries to refresh apps that are about to expire first, and then always refreshes AltStore itself last, since refreshing AltStore means that the app will quit.
155 lines
4.5 KiB
Swift
155 lines
4.5 KiB
Swift
//
|
|
// DatabaseManager.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 5/20/19.
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import CoreData
|
|
|
|
import AltSign
|
|
import Roxas
|
|
|
|
public class DatabaseManager
|
|
{
|
|
public static let shared = DatabaseManager()
|
|
|
|
public let persistentContainer: RSTPersistentContainer
|
|
|
|
public private(set) var isStarted = false
|
|
|
|
private init()
|
|
{
|
|
self.persistentContainer = RSTPersistentContainer(name: "AltStore")
|
|
}
|
|
}
|
|
|
|
public extension DatabaseManager
|
|
{
|
|
func start(completionHandler: @escaping (Error?) -> Void)
|
|
{
|
|
guard !self.isStarted else { return completionHandler(nil) }
|
|
|
|
self.persistentContainer.loadPersistentStores { (description, error) in
|
|
guard error == nil else { return completionHandler(error!) }
|
|
|
|
self.prepareDatabase() { (result) in
|
|
switch result
|
|
{
|
|
case .failure(let error): completionHandler(error)
|
|
case .success:
|
|
self.isStarted = true
|
|
completionHandler(nil)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func signOut(completionHandler: @escaping (Error?) -> Void)
|
|
{
|
|
self.persistentContainer.performBackgroundTask { (context) in
|
|
if let account = self.activeAccount(in: context)
|
|
{
|
|
account.isActiveAccount = false
|
|
}
|
|
|
|
if let team = self.activeTeam(in: context)
|
|
{
|
|
team.isActiveTeam = false
|
|
}
|
|
|
|
do
|
|
{
|
|
try context.save()
|
|
|
|
Keychain.shared.reset()
|
|
|
|
completionHandler(nil)
|
|
}
|
|
catch
|
|
{
|
|
print("Failed to save when signing out.", error)
|
|
completionHandler(error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension DatabaseManager
|
|
{
|
|
var viewContext: NSManagedObjectContext {
|
|
return self.persistentContainer.viewContext
|
|
}
|
|
}
|
|
|
|
extension DatabaseManager
|
|
{
|
|
func activeAccount(in context: NSManagedObjectContext = DatabaseManager.shared.viewContext) -> Account?
|
|
{
|
|
let predicate = NSPredicate(format: "%K == YES", #keyPath(Account.isActiveAccount))
|
|
|
|
let activeAccount = Account.first(satisfying: predicate, in: context)
|
|
return activeAccount
|
|
}
|
|
|
|
func activeTeam(in context: NSManagedObjectContext = DatabaseManager.shared.viewContext) -> Team?
|
|
{
|
|
let predicate = NSPredicate(format: "%K == YES", #keyPath(Team.isActiveTeam))
|
|
|
|
let activeTeam = Team.first(satisfying: predicate, in: context)
|
|
return activeTeam
|
|
}
|
|
}
|
|
|
|
private extension DatabaseManager
|
|
{
|
|
func prepareDatabase(completionHandler: @escaping (Result<Void, Error>) -> Void)
|
|
{
|
|
self.persistentContainer.performBackgroundTask { (context) in
|
|
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "1.0"
|
|
|
|
let altStoreApp: App
|
|
|
|
if let app = App.first(satisfying: NSPredicate(format: "%K == %@", #keyPath(App.identifier), App.altstoreAppID), in: context)
|
|
{
|
|
altStoreApp = app
|
|
}
|
|
else
|
|
{
|
|
altStoreApp = App.makeAltStoreApp(in: context)
|
|
altStoreApp.version = version
|
|
}
|
|
|
|
let installedApp: InstalledApp
|
|
|
|
if let app = altStoreApp.installedApp
|
|
{
|
|
installedApp = app
|
|
}
|
|
else
|
|
{
|
|
installedApp = InstalledApp(app: altStoreApp, bundleIdentifier: altStoreApp.identifier, context: context)
|
|
}
|
|
|
|
installedApp.version = version
|
|
|
|
if let provisioningProfileURL = Bundle.main.url(forResource: "embedded", withExtension: "mobileprovision"), let provisioningProfile = ALTProvisioningProfile(url: provisioningProfileURL)
|
|
{
|
|
installedApp.refreshedDate = provisioningProfile.creationDate
|
|
installedApp.expirationDate = provisioningProfile.expirationDate
|
|
}
|
|
|
|
do
|
|
{
|
|
try context.save()
|
|
completionHandler(.success(()))
|
|
}
|
|
catch
|
|
{
|
|
completionHandler(.failure(error))
|
|
}
|
|
}
|
|
}
|
|
}
|