Skip to content

Commit

Permalink
Merge branch 'SideStore:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
nythepegasus authored Jul 20, 2023
2 parents 2bee978 + b4b4cea commit 380889f
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
"version" : "4.4.2"
}
},
{
"identity" : "imobiledevice.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SideStore/iMobileDevice.swift",
"state" : {
"revision" : "74e481106dd155c0cd21bca6795fd9fe5f751654",
"version" : "1.0.5"
}
},
{
"identity" : "keychainaccess",
"kind" : "remoteSourceControl",
Expand Down
21 changes: 13 additions & 8 deletions AltStore/Operations/DeactivateAppOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,21 @@ final class DeactivateAppOperation: ResultOperation<InstalledApp>
let allIdentifiers = [installedApp.resignedBundleIdentifier] + appExtensionProfiles

for profile in allIdentifiers {
do {
try remove_provisioning_profile(profile)
} catch {
return self.finish(.failure(error))
var attempts = 5
while (attempts != 0){
print("Remove Provisioning profile attempts left: \(attempts)")
do {
try remove_provisioning_profile(profile)
self.progress.completedUnitCount += 1
installedApp.isActive = false
return self.finish(.success(installedApp))
} catch {
if (attempts == 0){
return self.finish(.failure(error))
} else { attempts -= 1 }
}
}
}

self.progress.completedUnitCount += 1
installedApp.isActive = false
self.finish(.success(installedApp))
}
}
}
65 changes: 15 additions & 50 deletions AltStore/Operations/InstallAppOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,59 +162,24 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
return
}
print("We are still installing after 3 seconds")

UNUserNotificationCenter.current().getNotificationSettings { settings in
switch (settings.authorizationStatus) {
case .authorized, .ephemeral, .provisional:
print("Notifications are enabled")

let content = UNMutableNotificationContent()
content.title = "Refreshing..."
content.body = "To finish refreshing, SideStore must be moved to the background, which it does by opening Safari. Please reopen SideStore after it is done refreshing!"
let notification = UNNotificationRequest(identifier: Bundle.Info.appbundleIdentifier + ".FinishRefreshNotification", content: content, trigger: UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false))
UNUserNotificationCenter.current().add(notification)

DispatchQueue.main.async { UIApplication.shared.open(URL(string: "x-web-search://")!) }

break
default:
print("Notifications are not enabled")

let alert = UIAlertController(title: "Finish Refresh", message: "To finish refreshing, SideStore must be moved to the background. To do this, you can either go to the Home Screen or open Safari by pressing Continue. Please reopen SideStore after doing this.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("Continue", comment: ""), style: .default, handler: { _ in
print("Opening Safari")
DispatchQueue.main.async { UIApplication.shared.open(URL(string: "x-web-search://")!) }
}))

DispatchQueue.main.async {
let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
if var topController = keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
topController.present(alert, animated: true)
} else {
print("No key window? Let's just open Safari")
UIApplication.shared.open(URL(string: "x-web-search://")!)
}
}

break
}
}
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
}
}

do {
try install_ipa(installedApp.bundleIdentifier)
installing = false
} catch {
installing = false
return self.finish(.failure(error))
var attempts = 10
while (attempts != 0){
print("Install ipa attempts left: \(attempts)")
do {
try install_ipa(installedApp.bundleIdentifier)
installing = false
installedApp.refreshedDate = Date()
return self.finish(.success(installedApp))
} catch {
if (attempts == 0){
installing = false
return self.finish(.failure(error))
} else { attempts -= 1 }
}
}

installedApp.refreshedDate = Date()
self.finish(.success(installedApp))
}
}

Expand Down
31 changes: 14 additions & 17 deletions AltStore/Operations/RefreshAppOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,27 @@ final class RefreshAppOperation: ResultOperation<InstalledApp>

do
{
if let error = self.context.error
{
throw error
}

guard let profiles = self.context.provisioningProfiles else { throw OperationError.invalidParameters }
if let error = self.context.error { return self.finish(.failure(error)) }

guard let app = self.context.app else { throw OperationError.appNotFound }
guard let profiles = self.context.provisioningProfiles else { return self.finish(.failure(OperationError.invalidParameters)) }
guard let app = self.context.app else { return self.finish(.failure(OperationError.appNotFound)) }

DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
print("Sending refresh app request...")

for p in profiles {
do {
let bytes = p.value.data.toRustByteSlice()
try install_provisioning_profile(bytes.forRust())
} catch {
return self.finish(.failure(error))
var attempts = 5
while (attempts != 0){
print("Install provisioning profile attempts left: \(attempts)")
do {
let bytes = p.value.data.toRustByteSlice()
try install_provisioning_profile(bytes.forRust())
} catch {
if (attempts == 0) {
return self.finish(.failure(error))
} else { attempts -= 1 }
}
}

self.progress.completedUnitCount += 1

let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.bundleIdentifier), app.bundleIdentifier)
Expand All @@ -72,9 +73,5 @@ final class RefreshAppOperation: ResultOperation<InstalledApp>
}
}
}
catch
{
self.finish(.failure(error))
}
}
}
25 changes: 25 additions & 0 deletions AltStore/Operations/ResignAppOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ private extension ResignAppOperation

// Prepare app
try prepare(appBundle, additionalInfoDictionaryValues: additionalValues)
try self.removeMissingAppExtensionReferences(from: appBundle)

if let directory = appBundle.builtInPlugInsURL, let enumerator = FileManager.default.enumerator(at: directory, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants])
{
Expand Down Expand Up @@ -267,4 +268,28 @@ private extension ResignAppOperation

return progress
}

func removeMissingAppExtensionReferences(from bundle: Bundle) throws
{
// If app extensions have been removed from an app (either by AltStore or the developer),
// we must remove all references to them from SC_Info/Manifest.plist (if it exists).

let scInfoURL = bundle.bundleURL.appendingPathComponent("SC_Info")
let manifestPlistURL = scInfoURL.appendingPathComponent("Manifest.plist")

guard let manifestPlist = NSMutableDictionary(contentsOf: manifestPlistURL), let sinfReplicationPaths = manifestPlist["SinfReplicationPaths"] as? [String] else { return }

// Remove references to missing files.
let filteredReplicationPaths = sinfReplicationPaths.filter { path in
guard let fileURL = URL(string: path, relativeTo: bundle.bundleURL) else { return false }

let fileExists = FileManager.default.fileExists(atPath: fileURL.path)
return fileExists
}

manifestPlist["SinfReplicationPaths"] = filteredReplicationPaths

// Save updated Manifest.plist to disk.
try manifestPlist.write(to: manifestPlistURL)
}
}
27 changes: 16 additions & 11 deletions AltStore/Operations/SendAppOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ final class SendAppOperation: ResultOperation<()>

if let error = self.context.error
{
self.finish(.failure(error))
return
return self.finish(.failure(error))
}

guard let resignedApp = self.context.resignedApp else { return self.finish(.failure(OperationError.invalidParameters)) }
Expand All @@ -46,18 +45,24 @@ final class SendAppOperation: ResultOperation<()>
print("AFC App `fileURL`: \(fileURL.absoluteString)")

if let data = NSData(contentsOf: fileURL) {
do {
let bytes = Data(data).toRustByteSlice()
try yeet_app_afc(app.bundleIdentifier, bytes.forRust())
} catch {
return self.finish(.failure(error))
var attempts = 10
while (attempts != 0){
print("Send app attempts left: \(attempts)")
do {
let bytes = Data(data).toRustByteSlice()
try yeet_app_afc(app.bundleIdentifier, bytes.forRust())
} catch {
attempts -= 1
if (attempts == 0) {
return self.finish(.failure(error))
} else { continue }
}
self.progress.completedUnitCount += 1
return self.finish(.success(()))
}

self.progress.completedUnitCount += 1
self.finish(.success(()))
} else {
print("IPA doesn't exist????")
self.finish(.failure(ALTServerError(.underlyingError)))
return self.finish(.failure(ALTServerError(.underlyingError)))
}
}
}
Loading

0 comments on commit 380889f

Please sign in to comment.