mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 23:03:27 +01:00
146 lines
5.4 KiB
Swift
146 lines
5.4 KiB
Swift
//
|
|
// LaunchViewController.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 7/30/19.
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Roxas
|
|
import WidgetKit
|
|
|
|
import AltStoreCore
|
|
|
|
class LaunchViewController: RSTLaunchViewController
|
|
{
|
|
private var didFinishLaunching = false
|
|
|
|
private var destinationViewController: UIViewController!
|
|
|
|
override var launchConditions: [RSTLaunchCondition] {
|
|
let isDatabaseStarted = RSTLaunchCondition(condition: { DatabaseManager.shared.isStarted }) { (completionHandler) in
|
|
DatabaseManager.shared.start(completionHandler: completionHandler)
|
|
}
|
|
|
|
return [isDatabaseStarted]
|
|
}
|
|
|
|
override var childForStatusBarStyle: UIViewController? {
|
|
return self.children.first
|
|
}
|
|
|
|
override var childForStatusBarHidden: UIViewController? {
|
|
return self.children.first
|
|
}
|
|
|
|
override func viewDidLoad()
|
|
{
|
|
super.viewDidLoad()
|
|
|
|
// Create destinationViewController now so view controllers can register for receiving Notifications.
|
|
self.destinationViewController = self.storyboard!.instantiateViewController(withIdentifier: "tabBarController") as! TabBarController
|
|
}
|
|
}
|
|
|
|
extension LaunchViewController
|
|
{
|
|
override func handleLaunchError(_ error: Error)
|
|
{
|
|
do
|
|
{
|
|
throw error
|
|
}
|
|
catch let error as NSError
|
|
{
|
|
let title = error.userInfo[NSLocalizedFailureErrorKey] as? String ?? NSLocalizedString("Unable to Launch AltStore", comment: "")
|
|
|
|
let errorDescription: String
|
|
|
|
if #available(iOS 14.5, *)
|
|
{
|
|
let errorMessages = [error.debugDescription] + error.underlyingErrors.map { ($0 as NSError).debugDescription }
|
|
errorDescription = errorMessages.joined(separator: "\n\n")
|
|
}
|
|
else
|
|
{
|
|
errorDescription = error.debugDescription
|
|
}
|
|
|
|
let alertController = UIAlertController(title: title, message: errorDescription, preferredStyle: .alert)
|
|
alertController.addAction(UIAlertAction(title: NSLocalizedString("Retry", comment: ""), style: .default, handler: { (action) in
|
|
self.handleLaunchConditions()
|
|
}))
|
|
self.present(alertController, animated: true, completion: nil)
|
|
}
|
|
}
|
|
|
|
override func finishLaunching()
|
|
{
|
|
super.finishLaunching()
|
|
|
|
guard !self.didFinishLaunching else { return }
|
|
|
|
AppManager.shared.update()
|
|
AppManager.shared.updatePatronsIfNeeded()
|
|
PatreonAPI.shared.refreshPatreonAccount()
|
|
|
|
self.updateKnownSources()
|
|
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
|
|
// Add view controller as child (rather than presenting modally)
|
|
// so tint adjustment + card presentations works correctly.
|
|
self.destinationViewController.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
|
|
self.destinationViewController.view.alpha = 0.0
|
|
self.addChild(self.destinationViewController)
|
|
self.view.addSubview(self.destinationViewController.view, pinningEdgesWith: .zero)
|
|
self.destinationViewController.didMove(toParent: self)
|
|
|
|
UIView.animate(withDuration: 0.2) {
|
|
self.destinationViewController.view.alpha = 1.0
|
|
}
|
|
|
|
self.didFinishLaunching = true
|
|
}
|
|
}
|
|
|
|
private extension LaunchViewController
|
|
{
|
|
func updateKnownSources()
|
|
{
|
|
AppManager.shared.updateKnownSources { result in
|
|
switch result
|
|
{
|
|
case .failure(let error): print("[ALTLog] Failed to update known sources:", error)
|
|
case .success((_, let blockedSources)):
|
|
DatabaseManager.shared.persistentContainer.performBackgroundTask { context in
|
|
let blockedSourceIDs = Set(blockedSources.lazy.map { $0.identifier })
|
|
let blockedSourceURLs = Set(blockedSources.lazy.compactMap { $0.sourceURL })
|
|
|
|
let predicate = NSPredicate(format: "%K IN %@ OR %K IN %@",
|
|
#keyPath(Source.identifier), blockedSourceIDs,
|
|
#keyPath(Source.sourceURL), blockedSourceURLs)
|
|
|
|
let sourceErrors = Source.all(satisfying: predicate, in: context).map { (source) in
|
|
let blockedSource = blockedSources.first { $0.identifier == source.identifier }
|
|
return SourceError.blocked(source, bundleIDs: blockedSource?.bundleIDs, existingSource: source)
|
|
}
|
|
|
|
guard !sourceErrors.isEmpty else { return }
|
|
|
|
Task {
|
|
for error in sourceErrors
|
|
{
|
|
let title = String(format: NSLocalizedString("“%@” Blocked", comment: ""), error.$source.name)
|
|
let message = [error.localizedDescription, error.recoverySuggestion].compactMap { $0 }.joined(separator: "\n\n")
|
|
|
|
await self.presentAlert(title: title, message: message)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|