Skip to content

Commit c6d8a1e

Browse files
committed
Smoother progress updates for installation
1 parent 8c3ee54 commit c6d8a1e

3 files changed

Lines changed: 55 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

isideload/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "isideload"
33
description = "Sideload iOS/iPadOS applications"
44
license = "MIT"
55
authors = ["Nicholas Sharp <nab@nabdev.me>"]
6-
version = "0.3.8"
6+
version = "0.3.9"
77
edition = "2024"
88
repository = "https://github.com/nab138/isideload"
99
documentation = "https://docs.rs/isideload"

isideload/src/sideload/install.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::{future::Future, path::Path};
1818
pub async fn install_app(
1919
provider: &impl IdeviceProvider,
2020
app_path: &Path,
21-
progress_callback: impl Fn(u64),
21+
progress_callback: impl Fn(u64) + Send + Sync,
2222
) -> Result<(), Report> {
2323
let mut afc_client = AfcClient::connect(provider)
2424
.await
@@ -28,7 +28,20 @@ pub async fn install_app(
2828
"PublicStaging/{}",
2929
app_path.file_name().ok_or_report()?.to_string_lossy()
3030
);
31-
afc_upload_dir(&mut afc_client, app_path, &dir).await?;
31+
let total_size = get_dir_size(app_path).unwrap_or(1) as f64;
32+
let mut uploaded = 0;
33+
let cb = |progress: f64| {
34+
progress_callback((progress * 70.0) as u64);
35+
};
36+
afc_upload_dir(
37+
&mut afc_client,
38+
app_path,
39+
&dir,
40+
&cb,
41+
&mut uploaded,
42+
total_size,
43+
)
44+
.await?;
3245

3346
let mut instproxy_client = InstallationProxyClient::connect(provider)
3447
.await
@@ -43,7 +56,7 @@ pub async fn install_app(
4356
dir,
4457
Some(plist::Value::Dictionary(options)),
4558
async |(percentage, _)| {
46-
progress_callback(percentage);
59+
progress_callback((70.0 + 0.3 * percentage as f64) as u64);
4760
},
4861
(),
4962
)
@@ -59,7 +72,7 @@ pub async fn install_app_rsd(
5972
provider: &mut impl RsdProvider,
6073
handshake: &mut RsdHandshake,
6174
app_path: &Path,
62-
progress_callback: impl Fn(u64),
75+
progress_callback: impl Fn(u64) + Send + Sync,
6376
) -> Result<(), Report> {
6477
let mut afc_client = AfcClient::connect_rsd(provider, handshake)
6578
.await
@@ -69,7 +82,20 @@ pub async fn install_app_rsd(
6982
"PublicStaging/{}",
7083
app_path.file_name().ok_or_report()?.to_string_lossy()
7184
);
72-
afc_upload_dir(&mut afc_client, app_path, &dir).await?;
85+
let total_size = get_dir_size(app_path).unwrap_or(1) as f64;
86+
let mut uploaded = 0;
87+
let cb = |pct: f64| {
88+
progress_callback((pct * 70.0) as u64);
89+
};
90+
afc_upload_dir(
91+
&mut afc_client,
92+
app_path,
93+
&dir,
94+
&cb,
95+
&mut uploaded,
96+
total_size,
97+
)
98+
.await?;
7399

74100
let mut instproxy_client = InstallationProxyClient::connect_rsd(provider, handshake)
75101
.await
@@ -84,7 +110,7 @@ pub async fn install_app_rsd(
84110
dir,
85111
Some(plist::Value::Dictionary(options)),
86112
async |(percentage, _)| {
87-
progress_callback(percentage);
113+
progress_callback((70.0 + 0.3 * percentage as f64) as u64);
88114
},
89115
(),
90116
)
@@ -94,10 +120,28 @@ pub async fn install_app_rsd(
94120
Ok(())
95121
}
96122

123+
fn get_dir_size(path: &Path) -> Result<u64, Report> {
124+
let mut size = 0;
125+
for entry in isideload_vfs::fs::read_dir(path)? {
126+
let entry = entry?;
127+
let path = entry.path();
128+
let meta = isideload_vfs::fs::metadata(&path)?;
129+
if meta.is_dir() {
130+
size += get_dir_size(&path)?;
131+
} else {
132+
size += meta.len();
133+
}
134+
}
135+
Ok(size)
136+
}
137+
97138
fn afc_upload_dir<'a>(
98139
afc_client: &'a mut AfcClient,
99140
path: &'a Path,
100141
afc_path: &'a str,
142+
cb: &'a (dyn Fn(f64) + Send + Sync),
143+
uploaded: &'a mut u64,
144+
total: f64,
101145
) -> Pin<Box<dyn Future<Output = Result<(), Report>> + Send + 'a>> {
102146
Box::pin(async move {
103147
let entries = isideload_vfs::fs::read_dir(path)?;
@@ -115,7 +159,7 @@ fn afc_upload_dir<'a>(
115159
afc_path,
116160
path.file_name().ok_or_report()?.to_string_lossy()
117161
);
118-
afc_upload_dir(afc_client, &path, &new_afc_path).await?;
162+
afc_upload_dir(afc_client, &path, &new_afc_path, cb, uploaded, total).await?;
119163
} else {
120164
let mut file_handle = afc_client
121165
.open(
@@ -135,6 +179,8 @@ fn afc_upload_dir<'a>(
135179
.write_entire(chunk)
136180
.await
137181
.map_err(Error::IdeviceError)?;
182+
*uploaded += chunk.len() as u64;
183+
cb(*uploaded as f64 / total);
138184
}
139185
file_handle.close().await.map_err(Error::IdeviceError)?;
140186
}

0 commit comments

Comments
 (0)