@@ -153,13 +153,19 @@ class DownloadSignManager: ObservableObject {
153153 }
154154 }
155155
156- private func signAndInstallIPA( ipaURL: URL , p12URL: URL , provURL: URL , password: String , appName: String ) {
156+ private func signAndInstallIPA(
157+ ipaURL: URL ,
158+ p12URL: URL ,
159+ provURL: URL ,
160+ password: String ,
161+ appName: String
162+ ) {
157163 DispatchQueue . main. async {
158164 self . status = " Starting signing process... "
159165 self . progress = 0.5
160166 self . isProcessing = true
161167 }
162-
168+
163169 signer. sign (
164170 ipaURL: ipaURL,
165171 p12URL: p12URL,
@@ -175,39 +181,59 @@ private func signAndInstallIPA(ipaURL: URL, p12URL: URL, provURL: URL, password:
175181 } ,
176182 completion: { [ weak self] result in
177183 guard let self else { return }
178-
184+
179185 switch result {
180186 case . success( let signedIPAURL) :
181187 DispatchQueue . main. async {
182188 self . progress = 1.0
183189 self . status = " ✅ Successfully signed IPA! Installing app now... "
184190 self . showSuccess = true
185191 }
186-
192+
193+ // Create a view model for installation progress
194+ let installerViewModel = InstallerStatusViewModel ( )
195+
187196 Task {
188197 do {
189- // Show install status while installing
190- try await installAppWithStatus ( from: signedIPAURL)
191-
192- // Hide the bar 3 seconds AFTER install is complete
198+ // Install with status updates using the viewModel
199+ try await installAppWithStatus ( from: signedIPAURL, viewModel: installerViewModel)
200+
201+ // Observe the viewModel status to update your UI
202+ installerViewModel. $status
203+ . receive ( on: DispatchQueue . main)
204+ . sink { status in
205+ switch status {
206+ case . idle: break
207+ case . uploading( let percent) , . installing( let percent) :
208+ self . progress = Double ( percent) / 100.0
209+ self . status = " \( status) "
210+ case . success:
211+ self . status = " ✅ Installation complete! "
212+ case . failure( let error) :
213+ self . status = " ❌ Install failed: \( error) "
214+ }
215+ }
216+ . store ( in: & self . cancellables)
217+
218+ // Hide the bar 3 seconds after install is complete
193219 DispatchQueue . main. asyncAfter ( deadline: . now( ) + 3 ) {
194220 self . isProcessing = false
195221 self . showSuccess = false
196222 self . progress = 0.0
197223 self . status = " "
198224 }
199-
225+
200226 } catch {
201227 DispatchQueue . main. async {
202228 self . status = " ❌ Install failed: \( error. localizedDescription) "
203229 self . isProcessing = false
204230 }
205231 }
206232 }
207-
233+
208234 // Clean up original downloaded IPA
209235 try ? FileManager . default. removeItem ( at: ipaURL)
210-
236+
211237 case . failure( let error) :
212238 DispatchQueue . main. async {
213239 self . status = " ❌ Signing failed: \( error. localizedDescription) "
0 commit comments