Use atproto actions with ease in iOS shortcuts
at main 4.0 kB view raw
1// 2// PersistentUserSessionRegistry.swift 3// shortcut 4// 5// Created by Bailey Townsend on 6/25/25. 6// 7 8import ATProtoKit 9import Foundation 10import SwiftData 11 12@MainActor 13public struct PersistentUserSessionRegistry: UserSessionRegistry { 14 15 private var modelContext: ModelContext 16 17 init(modelContext: ModelContext) { 18 self.modelContext = modelContext 19 } 20 21 public func register(_ id: UUID, session: UserSession) async { 22 let model = UserSessionToModel(id, session: session) 23 self.modelContext.insert(model) 24 do { 25 try self.modelContext.save() 26 } catch { 27 print("Error saving user session: \(error)") 28 } 29 30 } 31 32 public func getSession(for id: UUID) async -> UserSession? { 33 let descriptor = FetchDescriptor<UserSessionModel>( 34 predicate: #Predicate { $0.id == id } 35 ) 36 37 do { 38 let models = try self.modelContext.fetch(descriptor) 39 guard let model = models.first else { return nil } 40 return ModelToUserSession(model) 41 } catch { 42 return nil 43 } 44 } 45 46 public func containsSession(for id: UUID) async -> Bool { 47 let descriptor = FetchDescriptor<UserSessionModel>( 48 predicate: #Predicate { $0.id == id } 49 ) 50 51 do { 52 let count = try self.modelContext.fetchCount(descriptor) 53 return count > 0 54 } catch { 55 return false 56 } 57 } 58 59 public func removeSession(for id: UUID) async { 60 let descriptor = FetchDescriptor<UserSessionModel>( 61 predicate: #Predicate { $0.id == id } 62 ) 63 64 do { 65 let models = try self.modelContext.fetch(descriptor) 66 for model in models { 67 self.modelContext.delete(model) 68 } 69 try self.modelContext.save() 70 } catch { 71 // Handle error silently or log as needed 72 } 73 } 74 75 public func removeAllSessions() async { 76 let descriptor = FetchDescriptor<UserSessionModel>() 77 78 do { 79 let models = try self.modelContext.fetch(descriptor) 80 for model in models { 81 self.modelContext.delete(model) 82 } 83 try self.modelContext.save() 84 } catch { 85 // Handle error silently or log as needed 86 } 87 } 88 89 public func getAllSessions() async -> [UUID: UserSession] { 90 let descriptor = FetchDescriptor<UserSessionModel>() 91 92 do { 93 let models = try self.modelContext.fetch(descriptor) 94 var sessions: [UUID: UserSession] = [:] 95 96 for model in models { 97 let session = ModelToUserSession(model) 98 sessions[model.id] = session 99 } 100 101 return sessions 102 } catch { 103 return [:] 104 } 105 } 106 107} 108 109private func ModelToUserSession(_ model: UserSessionModel) -> UserSession { 110 return UserSession( 111 handle: model.handle, 112 sessionDID: model.sessionDID, 113 email: model.email, 114 isEmailConfirmed: model.isEmailConfirmed, 115 isEmailAuthenticationFactorEnabled: model.isEmailAuthenticationFactorEnabled, 116 // didDocument: model.didDocument, 117 isActive: model.isActive, 118 status: model.status, 119 serviceEndpoint: model.serviceEndpoint, 120 pdsURL: model.pdsURL 121 ) 122} 123 124private func UserSessionToModel(_ id: UUID, session: UserSession) -> UserSessionModel { 125 return UserSessionModel( 126 sessionId: id, 127 handle: session.handle, 128 sessionDID: session.sessionDID, 129 email: session.email, 130 isEmailConfirmed: session.isEmailConfirmed, 131 isEmailAuthenticationFactorEnabled: session.isEmailAuthenticationFactorEnabled, 132 // didDocument: session.didDocument, 133 isActive: session.isActive, 134 status: session.status, 135 serviceEndpoint: session.serviceEndpoint, 136 pdsURL: session.pdsURL) 137}