mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
83 lines
3.0 KiB
Swift
83 lines
3.0 KiB
Swift
|
|
//
|
||
|
|
// AppManager.swift
|
||
|
|
// AltDaemon
|
||
|
|
//
|
||
|
|
// Created by Riley Testut on 6/1/20.
|
||
|
|
// Copyright © 2020 Riley Testut. All rights reserved.
|
||
|
|
//
|
||
|
|
|
||
|
|
import Foundation
|
||
|
|
|
||
|
|
import AltSign
|
||
|
|
|
||
|
|
private extension URL
|
||
|
|
{
|
||
|
|
static let profilesDirectoryURL = URL(fileURLWithPath: "/var/MobileDevice/ProvisioningProfiles", isDirectory: true)
|
||
|
|
}
|
||
|
|
|
||
|
|
struct AppManager
|
||
|
|
{
|
||
|
|
static let shared = AppManager()
|
||
|
|
|
||
|
|
private init()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
func installApp(at fileURL: URL, bundleIdentifier: String, activeProfiles: Set<String>?) throws
|
||
|
|
{
|
||
|
|
let lsApplicationWorkspace = unsafeBitCast(NSClassFromString("LSApplicationWorkspace")!, to: LSApplicationWorkspace.Type.self)
|
||
|
|
|
||
|
|
let options = ["CFBundleIdentifier": bundleIdentifier, "AllowInstallLocalProvisioned": NSNumber(value: true)] as [String : Any]
|
||
|
|
try lsApplicationWorkspace.default.installApplication(fileURL, withOptions: options)
|
||
|
|
}
|
||
|
|
|
||
|
|
func removeApp(forBundleIdentifier bundleIdentifier: String)
|
||
|
|
{
|
||
|
|
let lsApplicationWorkspace = unsafeBitCast(NSClassFromString("LSApplicationWorkspace")!, to: LSApplicationWorkspace.Type.self)
|
||
|
|
lsApplicationWorkspace.default.uninstallApplication(bundleIdentifier, withOptions: nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
func install(_ profiles: Set<ALTProvisioningProfile>, activeProfiles: Set<String>?) throws
|
||
|
|
{
|
||
|
|
let installingBundleIDs = Set(profiles.map(\.bundleIdentifier))
|
||
|
|
|
||
|
|
let profileURLs = try FileManager.default.contentsOfDirectory(at: .profilesDirectoryURL, includingPropertiesForKeys: nil, options: [])
|
||
|
|
|
||
|
|
// Remove all inactive profiles (if active profiles are provided), and the previous profiles.
|
||
|
|
for fileURL in profileURLs
|
||
|
|
{
|
||
|
|
guard let profile = ALTProvisioningProfile(url: fileURL) else { continue }
|
||
|
|
|
||
|
|
if installingBundleIDs.contains(profile.bundleIdentifier) || (activeProfiles?.contains(profile.bundleIdentifier) == false && profile.isFreeProvisioningProfile)
|
||
|
|
{
|
||
|
|
try FileManager.default.removeItem(at: fileURL)
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
print("Ignoring:", profile.bundleIdentifier, profile.uuid)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for profile in profiles
|
||
|
|
{
|
||
|
|
let destinationURL = URL.profilesDirectoryURL.appendingPathComponent(profile.uuid.uuidString.lowercased())
|
||
|
|
try profile.data.write(to: destinationURL, options: .atomic)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func removeProvisioningProfiles(forBundleIdentifiers bundleIdentifiers: Set<String>) throws
|
||
|
|
{
|
||
|
|
let profileURLs = try FileManager.default.contentsOfDirectory(at: .profilesDirectoryURL, includingPropertiesForKeys: nil, options: [])
|
||
|
|
|
||
|
|
for fileURL in profileURLs
|
||
|
|
{
|
||
|
|
guard let profile = ALTProvisioningProfile(url: fileURL) else { continue }
|
||
|
|
|
||
|
|
if bundleIdentifiers.contains(profile.bundleIdentifier)
|
||
|
|
{
|
||
|
|
try FileManager.default.removeItem(at: fileURL)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|