### Handle AltServer Requests Source: https://context7.com/altstoreio/altstore/llms.txt Processes app installation and JIT enabling requests from AltStore clients. Requires an active connection and appropriate request objects. ```swift // AltServer request handling examples // Handle app preparation request func handlePrepareAppRequest(_ request: PrepareAppRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) { // 1. Receive the IPA data connection.receiveData(expectedSize: request.contentSize) { result in let data = try result.get() // 2. Write to temporary file let tempURL = FileManager.default.temporaryDirectory .appendingPathComponent(UUID().uuidString + ".ipa") try data.write(to: tempURL) // 3. Wait for begin installation request connection.receiveRequest() { result in switch result { case .success(.beginInstallation(let installRequest)): // 4. Install the app ALTDeviceManager.shared.installApp( at: tempURL, toDeviceWithUDID: request.udid, activeProvisioningProfiles: installRequest.activeProfiles ) { result in completionHandler(result.map { _ in InstallationProgressResponse(progress: 1.0) }) } default: completionHandler(.failure(ALTServerError(.unknownRequest))) } } } } // Handle JIT enable request func handleEnableUnsignedCodeExecutionRequest(_ request: EnableUnsignedCodeExecutionRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) { guard let device = ALTDeviceManager.shared.availableDevices .first(where: { $0.identifier == request.udid }) else { return completionHandler(.failure(ALTServerError(.deviceNotFound))) } let process: AppProcess if let processID = request.processID { process = .pid(processID) } else if let processName = request.processName { process = .name(processName) } else { return completionHandler(.failure(ALTServerError(.invalidRequest))) } Task { do { try await JITManager.shared.enableUnsignedCodeExecution(process: process, device: device) completionHandler(.success(EnableUnsignedCodeExecutionResponse())) } catch { completionHandler(.failure(ALTServerError(error))) } } } ``` -------------------------------- ### Install Applications via ALTDeviceManager Source: https://context7.com/altstoreio/altstore/llms.txt Use ALTDeviceManager to sign and install IPA files onto connected iOS devices using provided Apple ID credentials. ```swift import AltSign // Install an app to a connected device let ipaURL = URL(fileURLWithPath: "/path/to/app.ipa") let device: ALTDevice = ALTDeviceManager.shared.availableDevices.first! ALTDeviceManager.shared.installApplication( at: ipaURL, to: device, appleID: "user@example.com", password: "app-specific-password" ) { result in switch result { case .success(let application): print("Installed: \(application.name)") print("Bundle ID: \(application.bundleIdentifier)") case .failure(let error): print("Installation failed: \(error.localizedDescription)") } } ``` -------------------------------- ### Manage App Lifecycle with AppManager Source: https://context7.com/altstoreio/altstore/llms.txt Use the AppManager singleton to perform installation, updates, refreshing of provisioning profiles, and JIT activation. These operations are asynchronous and require a presenting view controller for UI interactions. ```swift import AltStoreCore import AltSign // Access the shared AppManager instance let appManager = AppManager.shared // Install an app from a StoreApp let storeApp: StoreApp = // ... fetched from source let (task, progress) = await appManager.installAsync(storeApp, presentingViewController: viewController) do { let installedApp = try await task.value print("Successfully installed: \(installedApp.wrappedValue.name)") } catch { print("Installation failed: \(error.localizedDescription)") } // Update an installed app let installedApp: InstalledApp = // ... from database let (updateTask, updateProgress) = await appManager.updateAsync(installedApp, presentingViewController: viewController) // Refresh apps (resign provisioning profiles) let appsToRefresh = InstalledApp.fetchActiveApps(in: context) let group = appManager.refresh(appsToRefresh, presentingViewController: viewController) group.completionHandler = { results in for (bundleID, result) in results { switch result { case .success(let app): print("Refreshed \(app.name)") case .failure(let error): print("Failed to refresh \(bundleID): \(error)") } } } // Enable JIT for an app appManager.enableJIT(for: installedApp) { result in switch result { case .success: print("JIT enabled successfully") case .failure(let error): print("Failed to enable JIT: \(error)") } } ``` -------------------------------- ### Manage Core Data Storage Source: https://context7.com/altstoreio/altstore/llms.txt Initializes the database and performs CRUD operations on installed apps and store sources. Uses background contexts for asynchronous database tasks. ```swift import AltStoreCore import CoreData // Initialize the database DatabaseManager.shared.start { error in if let error = error { print("Database error: \(error)") } } // Fetch installed apps let context = DatabaseManager.shared.viewContext let installedApps = InstalledApp.all(in: context) for app in installedApps { print("\(app.name) - expires: \(app.expirationDate)") } // Fetch active apps (count against 3-app limit) let activeApps = InstalledApp.fetchActiveApps(in: context) // Fetch apps needing refresh let fetchRequest = InstalledApp.fetchRequest() fetchRequest.predicate = NSPredicate( format: "%K < %@", #keyPath(InstalledApp.expirationDate), Date().addingTimeInterval(24 * 60 * 60) as NSDate ) let appsNeedingRefresh = try context.fetch(fetchRequest) // Query store apps from sources let storeAppRequest = StoreApp.fetchRequest() storeAppRequest.predicate = NSPredicate( format: "%K == %@", #keyPath(StoreApp.bundleIdentifier), "com.example.app" ) if let storeApp = try context.fetch(storeAppRequest).first { print("Found: \(storeApp.name) by \(storeApp.developerName)") } // Background context for async operations DatabaseManager.shared.persistentContainer.performBackgroundTask { context in // Perform database operations try? context.save() } ``` -------------------------------- ### Handle AltStore URL Schemes in Swift Source: https://context7.com/altstoreio/altstore/llms.txt Functions to parse incoming deep links for app installation and source management, posting notifications to the AppDelegate upon successful extraction of parameters. ```swift // AltStore URL schemes // Install an app from URL // altstore://install?url=https://example.com/app.ipa func handleInstallURL(_ url: URL) { guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems, let downloadURLString = queryItems.first(where: { $0.name == "url" })?.value, let downloadURL = URL(string: downloadURLString) else { return } NotificationCenter.default.post( name: AppDelegate.importAppDeepLinkNotification, object: nil, userInfo: [AppDelegate.importAppDeepLinkURLKey: downloadURL] ) } // Add a source // altstore://source?url=https://example.com/source.json func handleSourceURL(_ url: URL) { guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems, let sourceURLString = queryItems.first(where: { $0.name == "url" })?.value, let sourceURL = URL(string: sourceURLString) else { return } NotificationCenter.default.post( name: AppDelegate.addSourceDeepLinkNotification, object: nil, userInfo: [AppDelegate.addSourceDeepLinkURLKey: sourceURL] ) } // Open Patreon settings // altstore://patreon // Handle app backup response // altstore://appbackupresponse/success // altstore://appbackupresponse/failure?errorDomain=...&errorCode=...&errorDescription=... ``` -------------------------------- ### Refresh Provisioning Profile for Installed App Source: https://context7.com/altstoreio/altstore/llms.txt Use RefreshAppOperation to refresh an app's provisioning profile without a full reinstall. Requires an AppOperationContext with bundle identifier and authentication context. ```swift import AltStoreCore import AltSign // Create refresh operation context let context = AppOperationContext( bundleIdentifier: installedApp.bundleIdentifier, authenticatedContext: authContext ) context.app = ALTApplication(fileURL: installedApp.fileURL) // Create and configure the refresh operation let refreshOperation = RefreshAppOperation(context: context) refreshOperation.resultHandler = { result in switch result { case .success(let refreshedApp): print("Refreshed \(refreshedApp.name)") print("New expiration: \(refreshedApp.expirationDate)") case .failure(let error): print("Refresh failed: \(error)") } } ``` -------------------------------- ### Clone the AltStore Repository Source: https://github.com/altstoreio/altstore/blob/marketplace/README.md Initial step to download the project source code from GitHub. ```bash git clone https://github.com/rileytestut/AltStore.git ``` -------------------------------- ### Discover and Connect to AltServer Source: https://context7.com/altstoreio/altstore/llms.txt Use ServerManager to discover AltServer instances via mDNS or USB and establish a connection to perform requests like anisette data retrieval. ```swift import AltStoreCore import Network // Start discovering AltServers on the network ServerManager.shared.startDiscovering() // Access discovered servers let servers = ServerManager.shared.discoveredServers for server in servers { print("Found server: \(server.localizedName ?? "Unknown")") print(" Connection type: \(server.connectionType)") print(" Is preferred: \(server.isPreferred)") } // Connect to a specific server ServerManager.shared.connect(to: server) { result in switch result { case .success(let connection): print("Connected to server!") // Send an anisette data request let request = AnisetteDataRequest() connection.send(request) { sendResult in switch sendResult { case .success: connection.receiveResponse { responseResult in switch responseResult { case .success(.anisetteData(let response)): print("Received anisette data") case .failure(let error): print("Error: \(error)") default: break } } case .failure(let error): print("Send failed: \(error)") } } case .failure(let error): print("Connection failed: \(error)") } } // Stop discovering when done ServerManager.shared.stopDiscovering() ``` -------------------------------- ### Handle App Sources and Manifests Source: https://context7.com/altstoreio/altstore/llms.txt Manage app sources by fetching from URLs, adding new sources, and updating existing ones. Sources are defined by a specific JSON manifest structure. ```swift import AltStoreCore // Fetch a source from URL let sourceURL = URL(string: "https://apps.altstore.io/")! let source = try await AppManager.shared.fetchSource(sourceURL: sourceURL) print("Source: \(source.name)") print("Apps: \(source.apps.count)") for app in source.apps { print("- \(app.name) (\(app.bundleIdentifier))") } // Add a new source with user confirmation try await AppManager.shared.add(source, message: "Make sure to only add sources that you trust.", presentingViewController: viewController) // Fetch all configured sources let (sources, context) = try await AppManager.shared.fetchSources() try context.save() // Update all sources and check for updates AppManager.shared.updateAllSources { result in switch result { case .success: print("Sources updated successfully") case .failure(let error): print("Failed to update sources: \(error)") } } ``` ```json { "name": "My Source", "identifier": "com.example.source", "subtitle": "Custom apps for everyone", "description": "A collection of useful apps", "iconURL": "https://example.com/icon.png", "website": "https://example.com", "apps": [ { "name": "My App", "bundleIdentifier": "com.example.myapp", "developerName": "Developer", "subtitle": "A great app", "localizedDescription": "Full description here", "iconURL": "https://example.com/app-icon.png", "screenshotURLs": ["https://example.com/screenshot1.png"], "versions": [ { "version": "1.0", "date": "2024-01-01", "downloadURL": "https://example.com/app.ipa", "size": 10000000 } ] } ] } ``` -------------------------------- ### Create and launch a privileged task Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Configures and launches a task with root privileges. The launch call is blocking and triggers a system password prompt. ```objective-c // Create task STPrivilegedTask *privilegedTask = [STPrivilegedTask new]; [privilegedTask setLaunchPath:@"/usr/bin/touch"]; [privilegedTask setArguments:@[@"/etc/my_test_file"]]; // Setting working directory is optional, defaults to / // NSString *path = [[NSBundle mainBundle] resourcePath]; // [privilegedTask setCurrentDirectoryPath:path]; // Launch it, user is prompted for password (blocking) OSStatus err = [privilegedTask launch]; if (err == errAuthorizationSuccess) { NSLog(@"Task successfully launched"); } else if (err == errAuthorizationCanceled) { NSLog(@"User cancelled"); } else { NSLog(@"Something went wrong"); } ``` -------------------------------- ### Run System Information Script Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md This shell script is executed by the sample app to gather user, ID, and directory information. It then exits with a status code of 5. ```shell #!/bin/sh echo "/usr/bin/whoami:" whoami echo "" echo "Real User ID:" echo $UID \($USER\) echo "" echo "Effective User ID:" /usr/bin/id -u echo "" echo "Current working directory:" echo "$PWD" exit 5 ``` -------------------------------- ### Launch with external AuthorizationRef Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Allows providing a custom AuthorizationRef for the task launch. ```objective-c // ... Create your own AuthorizationRef [STPrivilegedTask launchedPrivilegedTaskWithLaunchPath:@"/bin/sh" arguments:@"/path/to/script" currentDirectory:@"/" authorization:authRef] ``` -------------------------------- ### Launch a privileged task using a one-liner Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md A convenience method for launching a task in a single line. ```objective-c OSStatus err = [STPrivilegedTask launchedPrivilegedTaskWithLaunchPath:@"/bin/sh" arguments:@[@"/path/to/script.sh"]]; ``` -------------------------------- ### Observe task termination Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Demonstrates how to detect when a task finishes using notifications or a termination handler block. ```objective-c [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(privilegedTaskFinished:) name:STPrivilegedTaskDidTerminateNotification object:nil]; - (void)privilegedTaskFinished:(NSNotification *)aNotification { // Do something } ``` ```objective-c privilegedTask.terminationHandler = ^(STPrivilegedTask *privilegedTask) { NSLog(@"Terminating task: %@", [privilegedTask description]); }; ``` -------------------------------- ### Configure Background Fetch Interval Source: https://context7.com/altstoreio/altstore/llms.txt Sets the minimum interval for background fetch operations. Also requests user permission for notifications. ```swift import AltStoreCore import BackgroundTasks // Configure background refresh func prepareForBackgroundFetch() { // Register for background fetch UIApplication.shared.setMinimumBackgroundFetchInterval(1 * 60 * 60) // 1 hour // Request notification permissions UNUserNotificationCenter.current().requestAuthorization( options: [.alert, .badge, .sound] ) { granted, error in // Handle permission result } } ``` -------------------------------- ### Update Project Submodules Source: https://github.com/altstoreio/altstore/blob/marketplace/README.md Initializes and updates all git submodules required for the project. ```bash cd AltStore git submodule update --init --recursive ``` -------------------------------- ### Perform Background App Refresh Source: https://context7.com/altstoreio/altstore/llms.txt Fetches apps that require refreshing and initiates the background refresh process. Reports success or failure. ```swift import AltStoreCore import BackgroundTasks // Perform background refresh func performBackgroundRefresh(completion: @escaping (UIBackgroundFetchResult) -> Void) { // Fetch apps that need refresh DatabaseManager.shared.persistentContainer.performBackgroundTask { context in let installedApps = InstalledApp.fetchAppsForBackgroundRefresh(in: context) AppManager.shared.backgroundRefresh(installedApps) { result in switch result { case .success(let results): let refreshedCount = results.values.filter { if case .success = $0 { return true } return false }.count print("Refreshed \(refreshedCount) apps") completion(.newData) case .failure(let error): print("Background refresh failed: \(error)") completion(.failed) } } } } ``` -------------------------------- ### Read task output synchronously Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Blocks execution until the task finishes, then reads the output from the file handle. ```objective-c // ... Launch task [privilegedTask waitUntilExit]; // This is blocking // Read output file handle for data NSData *outputData = [[privilegedTask outputFileHandle] readDataToEndOfFile]; NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; ``` -------------------------------- ### Read task output asynchronously Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Uses NSNotificationCenter to process output data as it becomes available while the task runs in the background. ```objective-c // ... Launch task NSFileHandle *readHandle = [privilegedTask outputFileHandle]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOutputData:) name:NSFileHandleReadCompletionNotification object:readHandle]; [readHandle readInBackgroundAndNotify]; // ... - (void)getOutputData:(NSNotification *)aNotification { // Get data from notification NSData *data = [[aNotification userInfo] objectForKey:NSFileHandleNotificationDataItem]; // Make sure there's actual data if ([data length]) { // Do something with the data NSString *outputString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", outputString); // Go read more data in the background [[aNotification object] readInBackgroundAndNotify]; } else { // Do something else } } ``` -------------------------------- ### Authenticate with Apple ID for App Signing Source: https://context7.com/altstoreio/altstore/llms.txt Handles Apple ID login with two-factor authentication support for app signing operations. Stores credentials for future operations upon successful authentication. ```swift import AltStoreCore import AltSign // Authenticate with Apple ID let authContext = AuthenticatedOperationContext() AppManager.shared.authenticate( presentingViewController: viewController, context: authContext ) { result in switch result { case .success(let (team, certificate, session)): print("Authenticated!") print("Team: \(team.name) (\(team.type))") print("Certificate: \(certificate.serialNumber)") // Store credentials for future operations authContext.team = team authContext.certificate = certificate authContext.session = session case .failure(let error): if case ALTAppleAPIError.requiresTwoFactorAuthentication = error { print("Please enter your 2FA code") } else { print("Authentication failed: \(error)") } } } ``` -------------------------------- ### Check for authorization availability Source: https://github.com/altstoreio/altstore/blob/marketplace/Pods/STPrivilegedTask/README.md Methods to verify if the underlying authorization function is available on the current macOS version. ```objective-c OSStatus err = [privilegedTask launch]; if (err == errAuthorizationFnNoLongerExists) { NSLog(@"AuthorizationExecuteWithPrivileges not available"); } ``` ```objective-c BOOL works = [STPrivilegedTask authorizationFunctionAvailable]; ``` -------------------------------- ### Schedule App Expiration Warning Notification Source: https://context7.com/altstoreio/altstore/llms.txt Schedules a local notification to warn the user when an app is about to expire. The notification is set to trigger 24 hours before the expiration date. ```swift import AltStoreCore import BackgroundTasks // Schedule expiration warning notification func scheduleExpirationWarning(for app: InstalledApp) { let notificationDate = app.expirationDate.addingTimeInterval(-24 * 60 * 60) let content = UNMutableNotificationContent() content.title = "AltStore Expiring Soon" content.body = "AltStore will expire in 24 hours. Open the app to refresh." let trigger = UNTimeIntervalNotificationTrigger( timeInterval: notificationDate.timeIntervalSinceNow, repeats: false ) let request = UNNotificationRequest( identifier: "expiration-warning", content: content, trigger: trigger ) UNUserNotificationCenter.current().add(request) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.