a neat project
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: better error handling

+36 -14
+4 -2
huntington.xcodeproj/project.pbxproj
··· 256 256 DEVELOPMENT_TEAM = M67B42LX8D; 257 257 ENABLE_PREVIEWS = YES; 258 258 GENERATE_INFOPLIST_FILE = YES; 259 - INFOPLIST_KEY_CFBundleDisplayName = "Huntington::neo"; 259 + INFOPLIST_KEY_CFBundleDisplayName = "huntington::neo"; 260 + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance"; 260 261 INFOPLIST_KEY_NSFaceIDUsageDescription = "Huntington::neo needs access to FaceID authenticate your account"; 261 262 INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 262 263 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; ··· 290 291 DEVELOPMENT_TEAM = M67B42LX8D; 291 292 ENABLE_PREVIEWS = YES; 292 293 GENERATE_INFOPLIST_FILE = YES; 293 - INFOPLIST_KEY_CFBundleDisplayName = "Huntington::neo"; 294 + INFOPLIST_KEY_CFBundleDisplayName = "huntington::neo"; 295 + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance"; 294 296 INFOPLIST_KEY_NSFaceIDUsageDescription = "Huntington::neo needs access to FaceID authenticate your account"; 295 297 INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 296 298 INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+8 -1
huntington/ContentView.swift
··· 138 138 if isLoading { 139 139 ProgressView("Loading…") 140 140 } else if let error = errorMessage { 141 - ContentUnavailableView(error, systemImage: "exclamationmark.triangle") 141 + ContentUnavailableView { 142 + Label("Unable to Load", systemImage: "exclamationmark.triangle") 143 + } description: { 144 + Text(error) 145 + } actions: { 146 + Button("Retry") { Task { await onRefresh() } } 147 + .buttonStyle(.borderedProminent) 148 + } 142 149 } else { 143 150 List { 144 151 if !accounts.isEmpty {
+4 -1
huntington/HuntingtonSession.swift
··· 19 19 @Observable 20 20 class HuntingtonSession { 21 21 var isAuthenticated = false 22 + private(set) var sessionError: String? = nil 22 23 23 24 private(set) var contextId = "" 24 25 private(set) var authReceipt = "" ··· 63 64 // Network unavailable — trust the cached session, loadData() will surface the error 64 65 isAuthenticated = true 65 66 } catch { 66 - // Auth failure (e.g. 401 expired session) — force re-login 67 67 clearState() 68 + sessionError = error.localizedDescription 68 69 } 69 70 } 70 71 ··· 118 119 self.customerId = custId 119 120 saveState() 120 121 isAuthenticated = true 122 + sessionError = nil 121 123 return .success 122 124 } else { 123 125 // New device — server requires OTP before trusting ··· 149 151 self.customerId = pendingCustId 150 152 saveState() 151 153 isAuthenticated = true 154 + sessionError = nil 152 155 Task { await registerDevice(contextId: ctx, authReceipt: receipt2, secondFactorId: sfId) } 153 156 } 154 157
+20 -10
huntington/LoginView.swift
··· 43 43 codeEntryBody 44 44 } 45 45 46 - // Error 47 - if let error = errorMessage { 48 - HStack(spacing: 6) { 49 - Image(systemName: "exclamationmark.circle.fill") 50 - Text(error).font(.footnote) 51 - } 52 - .foregroundStyle(.red) 53 - .padding(.horizontal, 24) 54 - .padding(.top, 16) 46 + if let msg = errorMessage { 47 + Label(msg, systemImage: "exclamationmark.circle.fill") 48 + .font(.footnote) 49 + .foregroundStyle(.red) 50 + .multilineTextAlignment(.center) 51 + .padding(.horizontal, 24) 52 + .padding(.top, 16) 55 53 } 56 54 57 55 if phase != .credentials { ··· 70 68 ToolbarItem(placement: .cancellationAction) { 71 69 Button("Cancel") { dismiss() } 72 70 } 73 - 74 71 } 75 72 .contentShape(Rectangle()) 76 73 .onTapGesture { hideKeyboard() } 74 + .onAppear { 75 + if let reason = session.sessionError { 76 + errorMessage = reason 77 + } 78 + } 77 79 .sheet(isPresented: $showForgotPassword) { 78 80 ForgotPasswordSheet() 81 + } 82 + .alert("Error", isPresented: Binding( 83 + get: { errorMessage != nil }, 84 + set: { if !$0 { errorMessage = nil } } 85 + )) { 86 + Button("OK", role: .cancel) {} 87 + } message: { 88 + if let msg = errorMessage { Text(msg) } 79 89 } 80 90 } 81 91 }