this repo has no description

Warnings and remove JSON view

+20 -69
+12 -6
AtProtoBackup/AccountDetailView.swift
··· 18 18 .fontWeight(.bold) 19 19 20 20 AccountInfoSection(account: account) 21 - 21 + 22 22 DownloadSection(account: account, downloadManager: downloadManager) 23 - 24 - JSONResponseSection(jsonData: account.jsonResponse) 25 - 23 + 26 24 Spacer() 27 25 } 28 26 .padding() ··· 32 30 33 31 struct AccountInfoSection: View { 34 32 let account: Account 35 - 33 + 36 34 var body: some View { 37 35 VStack(alignment: .leading, spacing: 8) { 38 36 HStack { ··· 40 38 .fontWeight(.semibold) 41 39 Text(account.handle) 42 40 } 43 - 41 + 44 42 HStack { 45 43 Text("DID:") 46 44 .fontWeight(.semibold) 47 45 Text(account.did) 48 46 .lineLimit(1) 49 47 .truncationMode(.middle) 48 + } 49 + 50 + HStack { 51 + Text("PDS:") 52 + .fontWeight(.semibold) 53 + Text(account.pds) 54 + .lineLimit(1) 55 + .truncationMode(.tail) 50 56 } 51 57 } 52 58 }
+3 -4
AtProtoBackup/AppDelegate.swift
··· 27 27 28 28 func applicationDidEnterBackground(_ application: UIApplication) { 29 29 // Request background processing time 30 - var backgroundTask: UIBackgroundTaskIdentifier = .invalid 31 - backgroundTask = application.beginBackgroundTask { 32 - application.endBackgroundTask(backgroundTask) 30 + let backgroundTask = application.beginBackgroundTask { 31 + // Expiration handler - called if we run out of time 33 32 } 34 - 33 + 35 34 // You get ~30 seconds to update Live Activities 36 35 Task { 37 36 // Note: We could update Live Activities here but we don't have
+5 -19
AtProtoBackup/BlobDownloader.swift
··· 105 105 } 106 106 } 107 107 108 - func urlSession( 109 - _ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, 110 - completionHandler: @escaping (URLSession.ResponseDisposition) -> Void 111 - ) { 112 - // Store response for download tasks 113 - if let downloadTask = dataTask as? URLSessionDownloadTask { 114 - completionQueue.sync { 115 - taskResponses[downloadTask] = response 116 - } 117 - } 118 - completionHandler(.allow) 119 - } 120 - 121 108 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 122 109 { 123 110 completionQueue.sync { ··· 169 156 170 157 // Initialize and restore any pending background downloads 171 158 public init() { 172 - // Force creation of the session to reconnect with any existing downloads 173 - _ = backgroundSession 159 + // Note: backgroundSession will be lazily created on first use 160 + // which will automatically reconnect with any existing downloads 174 161 } 175 162 176 163 // Static method to handle background session events (call from AppDelegate) ··· 255 242 // Create all download tasks immediately so they continue in background 256 243 var results: [String: URL] = [:] 257 244 var newDownloadCount = 0 258 - let resultsLock = NSLock() 259 245 260 246 // Semaphore to limit concurrent downloads 261 247 let semaphore = AsyncSemaphore(value: maxConcurrent) ··· 290 276 var downloadedCount = 0 291 277 for try await result in group { 292 278 if let (cid, url, wasNewDownload) = result { 293 - resultsLock.lock() 294 279 results[cid] = url 295 280 downloadedCount += 1 296 281 if wasNewDownload { 297 282 newDownloadCount += 1 298 283 } 299 - resultsLock.unlock() 300 284 301 285 progressHandler?(downloadedCount, cids.count) 302 286 } ··· 628 612 ) 629 613 630 614 if let fileEnumerator = fileEnumerator { 631 - for case let fileURL as URL in fileEnumerator { 615 + // Convert to array to avoid async iteration issues 616 + let files = fileEnumerator.allObjects.compactMap { $0 as? URL } 617 + for fileURL in files { 632 618 let fileName = fileURL.deletingPathExtension().lastPathComponent 633 619 if fileName == cid { 634 620 print("Blob \(cid) already exists at \(fileURL.path), skipping download")
-40
AtProtoBackup/JSONResponseSection.swift
··· 1 - // 2 - // JSONResponseSection.swift 3 - // AtProtoBackup 4 - // 5 - // Created by Corey Alexander on 8/25/25. 6 - // 7 - 8 - import SwiftUI 9 - 10 - struct JSONResponseSection: View { 11 - let jsonData: Data? 12 - 13 - var body: some View { 14 - if let jsonData = jsonData { 15 - VStack(alignment: .leading, spacing: 8) { 16 - Text("JSON Response:") 17 - .font(.headline) 18 - 19 - ScrollView { 20 - if let jsonObject = try? JSONSerialization.jsonObject(with: jsonData), 21 - let prettyData = try? JSONSerialization.data(withJSONObject: jsonObject, options: [.prettyPrinted]), 22 - let prettyString = String(data: prettyData, encoding: .utf8) { 23 - Text(prettyString) 24 - .font(.system(.body, design: .monospaced)) 25 - .textSelection(.enabled) 26 - .padding() 27 - .background(Color.gray.opacity(0.1)) 28 - .cornerRadius(8) 29 - } else { 30 - Text("Unable to decode JSON data") 31 - .foregroundColor(.secondary) 32 - } 33 - } 34 - } 35 - } else { 36 - Text("No JSON response available") 37 - .foregroundColor(.secondary) 38 - } 39 - } 40 - }