feat: add complete Mayday iOS Xcode project
- Swift 6, SwiftUI, MVVM + async/await architecture - iOS 17.0 minimum deployment target - Two targets: Mayday app + MaydayLiveActivity widget extension - Models: UserResponse, TokenPair, AppNotification, SessionResponse, AlertAttributes - Services: HTTPClient (actor), AuthService, KeychainService, NotificationsAPIService, PushNotificationService - ViewModels: AuthViewModel, NotificationsViewModel, SettingsViewModel - Views: Login/Register/VerifyEmail, NotificationsList/Detail, Settings/ChangePassword/Sessions - APNs push notifications with UIApplicationDelegate - ActivityKit Live Activities for Dynamic Island + Lock Screen - Keychain (Security framework) token storage - 30-second polling with pagination for notifications - Xcode project file (project.pbxproj) with correct build phases for both targets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
actor NotificationsAPIService {
|
||||
static let shared = NotificationsAPIService()
|
||||
private let client = HTTPClient.shared
|
||||
|
||||
private init() {}
|
||||
|
||||
func getNotifications(page: Int = 1, perPage: Int = 20) async throws -> NotificationsPage {
|
||||
try await client.request(.getNotifications(page: page, perPage: perPage))
|
||||
}
|
||||
|
||||
func markAsRead(id: UUID) async throws {
|
||||
let _: AppNotification = try await client.request(.markAsRead(id: id))
|
||||
}
|
||||
|
||||
func getSessions() async throws -> [SessionResponse] {
|
||||
try await client.request(.getSessions)
|
||||
}
|
||||
|
||||
func deleteSession(id: UUID) async throws {
|
||||
let _: EmptyResponse = try await client.request(.deleteSession(id: id))
|
||||
}
|
||||
|
||||
func logoutAll() async throws -> Int {
|
||||
let response: LogoutAllResponse = try await client.request(.logoutAll)
|
||||
return response.revokedSessions
|
||||
}
|
||||
|
||||
func changePassword(current: String, new: String) async throws -> UserResponse {
|
||||
try await client.request(.changePassword(current: current, new: new))
|
||||
}
|
||||
|
||||
func updateAppBadge(_ count: Int) async {
|
||||
await UIApplication.shared.setApplicationIconBadgeNumber(count)
|
||||
}
|
||||
}
|
||||
|
||||
struct LogoutAllResponse: Decodable {
|
||||
let revokedSessions: Int
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case revokedSessions = "revoked_sessions"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user