From eff4acca134450949b913d9494f723441a311d7b Mon Sep 17 00:00:00 2001 From: nab138 Date: Sat, 9 Aug 2025 22:41:58 -0400 Subject: [PATCH] Update README --- README.md | 60 +++++++++++++++++++++++++++++++++++- examples/minimal/src/main.rs | 1 + isideload/README.md | 1 + 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 isideload/README.md diff --git a/README.md b/README.md index 2552990..dd4da74 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,65 @@ To use isideload, add the following to your `Cargo.toml`: isideload = { version = "0.1.0", features = ["vendored-openssl", "vendored-botan" ] } # Optionally, both vendored features can be enabled to avoid needing OpenSSL and Botan installed on your system. ``` -See [examples/minimal/src/main.rs](examples/minimal/src/main.rs) for usage examples. +Then, you can use it like so: + +```rs +use std::{env, path::PathBuf, sync::Arc}; +use isideload::{ + AnisetteConfiguration, AppleAccount, DefaultLogger, DeveloperSession, device::list_devices, + sideload::sideload_app, +}; + +#[tokio::main] +async fn main() { + let args: Vec = env::args().collect(); + let app_path = PathBuf::from( + args.get(1) + .expect("Please provide the path to the app to install"), + ); + let apple_id = args + .get(2) + .expect("Please provide the Apple ID to use for installation"); + let apple_password = args.get(3).expect("Please provide the Apple ID password"); + + // You don't have to use the builtin list_devices method if you don't want to use usbmuxd + // You can use idevice to get the device info however you want + // This is just easier + let device = list_devices().await.unwrap().into_iter().next().unwrap(); + println!("Target device: {}", device.name); + + // Change the anisette url and such here + // Note that right now only remote anisette servers are supported + let anisette_config = AnisetteConfiguration::default(); + + let get_2fa_code = || { + let mut code = String::new(); + println!("Enter 2FA code:"); + std::io::stdin().read_line(&mut code).unwrap(); + Ok(code.trim().to_string()) + }; + + let account = AppleAccount::login( + || Ok((apple_id.to_string(), apple_password.to_string())), + get_2fa_code, + anisette_config, + ) + .await + .unwrap(); + + let dev_session = DeveloperSession::new(Arc::new(account)); + + // This is where certificates, mobileprovision, and anisette data will be stored + let store_dir = std::env::current_dir().unwrap(); + + // DefaultLogger just prints to the stdout/stderr, but you can provide your own implementation + sideload_app(DefaultLogger {}, &dev_session, &device, app_path, store_dir) + .await + .unwrap() +} +``` + +See [examples/minimal/src/main.rs](examples/minimal/src/main.rs). ## Licensing diff --git a/examples/minimal/src/main.rs b/examples/minimal/src/main.rs index 0c733ce..013c566 100644 --- a/examples/minimal/src/main.rs +++ b/examples/minimal/src/main.rs @@ -47,6 +47,7 @@ async fn main() { // This is where certificates, mobileprovision, and anisette data will be stored let store_dir = std::env::current_dir().unwrap(); + // DefaultLogger just prints to the stdout/stderr, but you can provide your own implementation sideload_app(DefaultLogger {}, &dev_session, &device, app_path, store_dir) .await .unwrap() diff --git a/isideload/README.md b/isideload/README.md new file mode 100644 index 0000000..94389ae --- /dev/null +++ b/isideload/README.md @@ -0,0 +1 @@ +../README.md