mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 14:53:25 +01:00
Prioritizes app refresh order
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.
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
<entity name="InstalledApp" representedClassName="InstalledApp" syncable="YES">
|
||||
<attribute name="bundleIdentifier" attributeType="String" syncable="YES"/>
|
||||
<attribute name="expirationDate" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="refreshedDate" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="version" attributeType="String" syncable="YES"/>
|
||||
<relationship name="app" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="App" inverseName="installedApp" inverseEntity="App" syncable="YES"/>
|
||||
<uniquenessConstraints>
|
||||
@@ -57,7 +58,7 @@
|
||||
<elements>
|
||||
<element name="Account" positionX="-36" positionY="90" width="128" height="135"/>
|
||||
<element name="App" positionX="-63" positionY="-18" width="128" height="210"/>
|
||||
<element name="InstalledApp" positionX="-63" positionY="0" width="128" height="105"/>
|
||||
<element name="InstalledApp" positionX="-63" positionY="0" width="128" height="120"/>
|
||||
<element name="Team" positionX="-45" positionY="81" width="128" height="120"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import CoreData
|
||||
|
||||
import AltSign
|
||||
import Roxas
|
||||
|
||||
public class DatabaseManager
|
||||
@@ -120,14 +121,23 @@ private extension DatabaseManager
|
||||
altStoreApp.version = version
|
||||
}
|
||||
|
||||
if let installedApp = altStoreApp.installedApp
|
||||
let installedApp: InstalledApp
|
||||
|
||||
if let app = altStoreApp.installedApp
|
||||
{
|
||||
installedApp.version = version
|
||||
installedApp = app
|
||||
}
|
||||
else
|
||||
{
|
||||
let installedApp = InstalledApp(app: altStoreApp, bundleIdentifier: altStoreApp.identifier, expirationDate: Date(), context: context)
|
||||
installedApp.version = version
|
||||
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
|
||||
|
||||
@@ -16,6 +16,7 @@ class InstalledApp: NSManagedObject, Fetchable
|
||||
@NSManaged var bundleIdentifier: String
|
||||
@NSManaged var version: String
|
||||
|
||||
@NSManaged var refreshedDate: Date
|
||||
@NSManaged var expirationDate: Date
|
||||
|
||||
/* Relationships */
|
||||
@@ -26,7 +27,7 @@ class InstalledApp: NSManagedObject, Fetchable
|
||||
super.init(entity: entity, insertInto: context)
|
||||
}
|
||||
|
||||
init(app: App, bundleIdentifier: String, expirationDate: Date, context: NSManagedObjectContext)
|
||||
init(app: App, bundleIdentifier: String, context: NSManagedObjectContext)
|
||||
{
|
||||
super.init(entity: InstalledApp.entity(), insertInto: context)
|
||||
|
||||
@@ -35,7 +36,9 @@ class InstalledApp: NSManagedObject, Fetchable
|
||||
self.version = app.version
|
||||
|
||||
self.bundleIdentifier = bundleIdentifier
|
||||
self.expirationDate = expirationDate
|
||||
|
||||
self.refreshedDate = Date()
|
||||
self.expirationDate = self.refreshedDate.addingTimeInterval(60 * 60 * 24 * 7) // Rough estimate until we get real values from provisioning profile.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +48,52 @@ extension InstalledApp
|
||||
{
|
||||
return NSFetchRequest<InstalledApp>(entityName: "InstalledApp")
|
||||
}
|
||||
|
||||
class func fetchAltStore(in context: NSManagedObjectContext) -> InstalledApp?
|
||||
{
|
||||
let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.app.identifier), App.altstoreAppID)
|
||||
|
||||
let altStore = InstalledApp.first(satisfying: predicate, in: context)
|
||||
return altStore
|
||||
}
|
||||
|
||||
class func fetchAppsForRefreshingAll(in context: NSManagedObjectContext) -> [InstalledApp]
|
||||
{
|
||||
let predicate = NSPredicate(format: "%K != %@", #keyPath(InstalledApp.app.identifier), App.altstoreAppID)
|
||||
|
||||
var installedApps = InstalledApp.all(satisfying: predicate,
|
||||
sortedBy: [NSSortDescriptor(keyPath: \InstalledApp.expirationDate, ascending: true)],
|
||||
in: context)
|
||||
|
||||
if let altStoreApp = InstalledApp.fetchAltStore(in: context)
|
||||
{
|
||||
// Refresh AltStore last since it causes app to quit.
|
||||
installedApps.append(altStoreApp)
|
||||
}
|
||||
|
||||
return installedApps
|
||||
}
|
||||
|
||||
class func fetchAppsForBackgroundRefresh(in context: NSManagedObjectContext) -> [InstalledApp]
|
||||
{
|
||||
let date = Date().addingTimeInterval(-120)
|
||||
|
||||
let predicate = NSPredicate(format: "(%K < %@) AND (%K != %@)",
|
||||
#keyPath(InstalledApp.refreshedDate), date as NSDate,
|
||||
#keyPath(InstalledApp.app.identifier), App.altstoreAppID)
|
||||
|
||||
var installedApps = InstalledApp.all(satisfying: predicate,
|
||||
sortedBy: [NSSortDescriptor(keyPath: \InstalledApp.expirationDate, ascending: true)],
|
||||
in: context)
|
||||
|
||||
if let altStoreApp = InstalledApp.fetchAltStore(in: context), altStoreApp.refreshedDate < date
|
||||
{
|
||||
// Refresh AltStore last since it causes app to quit.
|
||||
installedApps.append(altStoreApp)
|
||||
}
|
||||
|
||||
return installedApps
|
||||
}
|
||||
}
|
||||
|
||||
extension InstalledApp
|
||||
@@ -67,10 +116,10 @@ extension InstalledApp
|
||||
return appsDirectoryURL
|
||||
}
|
||||
|
||||
class func ipaURL(for app: App) -> URL
|
||||
class func fileURL(for app: App) -> URL
|
||||
{
|
||||
let ipaURL = self.directoryURL(for: app).appendingPathComponent("App.ipa")
|
||||
return ipaURL
|
||||
let appURL = self.directoryURL(for: app).appendingPathComponent("App.app")
|
||||
return appURL
|
||||
}
|
||||
|
||||
class func refreshedIPAURL(for app: App) -> URL
|
||||
@@ -79,7 +128,6 @@ extension InstalledApp
|
||||
return ipaURL
|
||||
}
|
||||
|
||||
|
||||
class func directoryURL(for app: App) -> URL
|
||||
{
|
||||
let directoryURL = InstalledApp.appsDirectoryURL.appendingPathComponent(app.identifier)
|
||||
@@ -94,8 +142,8 @@ extension InstalledApp
|
||||
return InstalledApp.directoryURL(for: self.app)
|
||||
}
|
||||
|
||||
var ipaURL: URL {
|
||||
return InstalledApp.ipaURL(for: self.app)
|
||||
var fileURL: URL {
|
||||
return InstalledApp.fileURL(for: self.app)
|
||||
}
|
||||
|
||||
var refreshedIPAURL: URL {
|
||||
|
||||
Reference in New Issue
Block a user