From e7930b95d061fba154f91967016341208d2210e1 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Tue, 21 Jan 2020 16:53:34 -0800 Subject: [PATCH] Adds InstalledExtension --- AltStore.xcodeproj/project.pbxproj | 4 + .../AltStore 2.xcdatamodel/contents | 142 ++++++++++-------- AltStore/Model/InstalledApp.swift | 15 +- AltStore/Model/InstalledExtension.swift | 66 ++++++++ AltStore/Operations/InstallAppOperation.swift | 30 ++++ 5 files changed, 191 insertions(+), 66 deletions(-) create mode 100644 AltStore/Model/InstalledExtension.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 445e1b60..8fae2f82 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -144,6 +144,7 @@ BF9ABA4F22DD41A9008935CF /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF9ABA4E22DD41A9008935CF /* UIColor+Hex.swift */; }; BFA8172923C56042001B5953 /* ServerConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA8172823C56042001B5953 /* ServerConnection.swift */; }; BFA8172B23C5633D001B5953 /* FetchAnisetteDataOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA8172A23C5633D001B5953 /* FetchAnisetteDataOperation.swift */; }; + BFA8172D23C5823E001B5953 /* InstalledExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA8172C23C5823E001B5953 /* InstalledExtension.swift */; }; BFA8172F23C5831A001B5953 /* PrepareDeveloperAccountOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA8172E23C5831A001B5953 /* PrepareDeveloperAccountOperation.swift */; }; BFB11692229322E400BB457C /* DatabaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB11691229322E400BB457C /* DatabaseManager.swift */; }; BFB1169B2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB1169A2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift */; }; @@ -469,6 +470,7 @@ BF9B63C5229DD44D002F0A62 /* AltSign.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AltSign.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BFA8172823C56042001B5953 /* ServerConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConnection.swift; sourceTree = ""; }; BFA8172A23C5633D001B5953 /* FetchAnisetteDataOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchAnisetteDataOperation.swift; sourceTree = ""; }; + BFA8172C23C5823E001B5953 /* InstalledExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledExtension.swift; sourceTree = ""; }; BFA8172E23C5831A001B5953 /* PrepareDeveloperAccountOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrepareDeveloperAccountOperation.swift; sourceTree = ""; }; BFB11691229322E400BB457C /* DatabaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseManager.swift; sourceTree = ""; }; BFB1169A2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "JSONDecoder+ManagedObjectContext.swift"; sourceTree = ""; }; @@ -1071,6 +1073,7 @@ BFE6326722A858F300F30809 /* Account.swift */, BF3D648722E79A3700E9056B /* AppPermission.swift */, BFBBE2E022931F81002097FA /* InstalledApp.swift */, + BFA8172C23C5823E001B5953 /* InstalledExtension.swift */, BFB6B21A23186D640022A802 /* NewsItem.swift */, BFD5D6E9230CCAE5007955AB /* PatreonAccount.swift */, BF02419322F2156E00129732 /* RefreshAttempt.swift */, @@ -1693,6 +1696,7 @@ BFD5D6F4230DDB0A007955AB /* Campaign.swift in Sources */, BFB6B21B23186D640022A802 /* NewsItem.swift in Sources */, BFF0B6982322CAB8007A79E1 /* InstructionsViewController.swift in Sources */, + BFA8172D23C5823E001B5953 /* InstalledExtension.swift in Sources */, BFD5D6E8230CC961007955AB /* PatreonAPI.swift in Sources */, BF9ABA4522DCFF43008935CF /* BrowseViewController.swift in Sources */, BF43002E22A714AF0051E2BC /* Keychain.swift in Sources */, diff --git a/AltStore/Model/AltStore.xcdatamodeld/AltStore 2.xcdatamodel/contents b/AltStore/Model/AltStore.xcdatamodeld/AltStore 2.xcdatamodel/contents index 20984afc..7f9e32a5 100644 --- a/AltStore/Model/AltStore.xcdatamodeld/AltStore 2.xcdatamodel/contents +++ b/AltStore/Model/AltStore.xcdatamodeld/AltStore 2.xcdatamodel/contents @@ -1,12 +1,12 @@ - - - - - - + + + + + + @@ -14,19 +14,20 @@ - - - + + + - - - - - - - + + + + + + + + @@ -34,19 +35,29 @@ + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + @@ -54,10 +65,10 @@ - - - - + + + + @@ -65,10 +76,10 @@ - - - - + + + + @@ -76,11 +87,11 @@ - - - - - + + + + + @@ -88,25 +99,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -114,11 +125,11 @@ - - - - - + + + + + @@ -130,6 +141,7 @@ + diff --git a/AltStore/Model/InstalledApp.swift b/AltStore/Model/InstalledApp.swift index cd6bd1b8..61c49f0b 100644 --- a/AltStore/Model/InstalledApp.swift +++ b/AltStore/Model/InstalledApp.swift @@ -11,8 +11,20 @@ import CoreData import AltSign +protocol InstalledAppProtocol: Fetchable +{ + var name: String { get } + var bundleIdentifier: String { get } + var resignedBundleIdentifier: String { get } + var version: String { get } + + var refreshedDate: Date { get } + var expirationDate: Date { get } + var installedDate: Date { get } +} + @objc(InstalledApp) -class InstalledApp: NSManagedObject, Fetchable +class InstalledApp: NSManagedObject, InstalledAppProtocol { /* Properties */ @NSManaged var name: String @@ -27,6 +39,7 @@ class InstalledApp: NSManagedObject, Fetchable /* Relationships */ @NSManaged var storeApp: StoreApp? @NSManaged var team: Team? + @NSManaged var appExtensions: Set var isSideloaded: Bool { return self.storeApp == nil diff --git a/AltStore/Model/InstalledExtension.swift b/AltStore/Model/InstalledExtension.swift new file mode 100644 index 00000000..fe9fcea0 --- /dev/null +++ b/AltStore/Model/InstalledExtension.swift @@ -0,0 +1,66 @@ +// +// InstalledExtension.swift +// AltStore +// +// Created by Riley Testut on 1/7/20. +// Copyright © 2020 Riley Testut. All rights reserved. +// + +import Foundation +import CoreData + +import AltSign + +@objc(InstalledExtension) +class InstalledExtension: NSManagedObject, InstalledAppProtocol +{ + /* Properties */ + @NSManaged var name: String + @NSManaged var bundleIdentifier: String + @NSManaged var resignedBundleIdentifier: String + @NSManaged var version: String + + @NSManaged var refreshedDate: Date + @NSManaged var expirationDate: Date + @NSManaged var installedDate: Date + + /* Relationships */ + @NSManaged var parentApp: InstalledApp? + + private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) + { + super.init(entity: entity, insertInto: context) + } + + init(resignedAppExtension: ALTApplication, originalBundleIdentifier: String, context: NSManagedObjectContext) + { + super.init(entity: InstalledExtension.entity(), insertInto: context) + + self.name = resignedAppExtension.name + self.bundleIdentifier = originalBundleIdentifier + self.resignedBundleIdentifier = resignedAppExtension.bundleIdentifier + + self.version = resignedAppExtension.version + + if let provisioningProfile = resignedAppExtension.provisioningProfile + { + self.refreshedDate = provisioningProfile.creationDate + self.expirationDate = provisioningProfile.expirationDate + } + else + { + self.refreshedDate = Date() + self.expirationDate = self.refreshedDate.addingTimeInterval(60 * 60 * 24 * 7) // Rough estimate until we get real values from provisioning profile. + } + + self.installedDate = Date() + } +} + +extension InstalledExtension +{ + @nonobjc class func fetchRequest() -> NSFetchRequest + { + return NSFetchRequest(entityName: "InstalledExtension") + } +} diff --git a/AltStore/Operations/InstallAppOperation.swift b/AltStore/Operations/InstallAppOperation.swift index a46db63d..f6e7c299 100644 --- a/AltStore/Operations/InstallAppOperation.swift +++ b/AltStore/Operations/InstallAppOperation.swift @@ -59,6 +59,36 @@ class InstallAppOperation: ResultOperation installedApp.installedDate = Date() } + var installedExtensions = Set() + + if + let bundle = Bundle(url: resignedApp.fileURL), + let directory = bundle.builtInPlugInsURL, + let enumerator = FileManager.default.enumerator(at: directory, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants]) + { + for case let fileURL as URL in enumerator + { + guard let appExtensionBundle = Bundle(url: fileURL) else { continue } + guard let appExtension = ALTApplication(fileURL: appExtensionBundle.bundleURL) else { continue } + + let installedExtension: InstalledExtension + + if let appExtension = installedApp.appExtensions.first(where: { $0.bundleIdentifier == appExtension.bundleIdentifier }) + { + installedExtension = appExtension + } + else + { + installedExtension = InstalledExtension(resignedAppExtension: appExtension, originalBundleIdentifier: appExtension.bundleIdentifier, context: backgroundContext) + installedExtension.installedDate = Date() + } + + installedExtensions.insert(installedExtension) + } + } + + installedApp.appExtensions = installedExtensions + installedApp.version = resignedApp.version if let profile = resignedApp.provisioningProfile