mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Uses UTIs to determine whether apps are installed or not
AltStore now inserts an app-specific UTI when resigning apps, and it periodically checks whether that app has been deleted by checking whether UTTypeCopyDeclaration returns nil for the same app-specific UTI.
This commit is contained in:
@@ -18,6 +18,7 @@ public extension Bundle
|
||||
public static let appGroups = "ALTAppGroups"
|
||||
|
||||
public static let urlTypes = "CFBundleURLTypes"
|
||||
public static let exportedUTIs = "UTExportedTypeDeclarations"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
import MobileCoreServices
|
||||
|
||||
import AltSign
|
||||
import AltKit
|
||||
@@ -55,16 +56,19 @@ extension AppManager
|
||||
do
|
||||
{
|
||||
let installedApps = try context.fetch(fetchRequest)
|
||||
for app in installedApps where app.storeApp != nil
|
||||
for app in installedApps
|
||||
{
|
||||
let uti = UTTypeCopyDeclaration(app.installedAppUTI as CFString)?.takeRetainedValue() as NSDictionary?
|
||||
|
||||
if app.bundleIdentifier == StoreApp.altstoreAppID
|
||||
{
|
||||
self.scheduleExpirationWarningLocalNotification(for: app)
|
||||
}
|
||||
else
|
||||
{
|
||||
if !UIApplication.shared.canOpenURL(app.openAppURL)
|
||||
if uti == nil
|
||||
{
|
||||
// This UTI is not declared by any apps, which means this app has been deleted by the user.
|
||||
context.delete(app)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +187,12 @@ extension InstalledApp
|
||||
return directoryURL
|
||||
}
|
||||
|
||||
class func installedAppUTI(forBundleIdentifier bundleIdentifier: String) -> String
|
||||
{
|
||||
let installedAppUTI = "io.altstore.Installed." + bundleIdentifier
|
||||
return installedAppUTI
|
||||
}
|
||||
|
||||
var directoryURL: URL {
|
||||
return InstalledApp.directoryURL(for: self)
|
||||
}
|
||||
@@ -198,4 +204,8 @@ extension InstalledApp
|
||||
var refreshedIPAURL: URL {
|
||||
return InstalledApp.refreshedIPAURL(for: self)
|
||||
}
|
||||
|
||||
var installedAppUTI: String {
|
||||
return InstalledApp.installedAppUTI(forBundleIdentifier: self.resignedBundleIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,6 +372,17 @@ private extension ResignAppOperation
|
||||
infoDictionary[Bundle.Info.appGroups] = appGroups
|
||||
}
|
||||
|
||||
// Add app-specific exported UTI so we can check later if this app (extension) is installed or not.
|
||||
let installedAppUTI = ["UTTypeConformsTo": [],
|
||||
"UTTypeDescription": "AltStore Installed App",
|
||||
"UTTypeIconFiles": [],
|
||||
"UTTypeIdentifier": InstalledApp.installedAppUTI(forBundleIdentifier: profile.bundleIdentifier),
|
||||
"UTTypeTagSpecification": [:]] as [String : Any]
|
||||
|
||||
var exportedUTIs = infoDictionary[Bundle.Info.exportedUTIs] as? [[String: Any]] ?? []
|
||||
exportedUTIs.append(installedAppUTI)
|
||||
infoDictionary[Bundle.Info.exportedUTIs] = exportedUTIs
|
||||
|
||||
try (infoDictionary as NSDictionary).write(to: bundle.infoPlistURL)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user