Stabilize beta release with warning cleanup and edge-case fixes
This commit is contained in:
@@ -16,6 +16,7 @@ enum PollError: Error, LocalizedError {
|
||||
case pollNotFound
|
||||
case alreadyVoted
|
||||
case notPollOwner
|
||||
case notVoteOwner
|
||||
case networkUnavailable
|
||||
case encodingError
|
||||
case unknown(Error)
|
||||
@@ -30,6 +31,8 @@ enum PollError: Error, LocalizedError {
|
||||
return "You have already voted on this poll."
|
||||
case .notPollOwner:
|
||||
return "Only the poll owner can perform this action."
|
||||
case .notVoteOwner:
|
||||
return "Only the vote owner can update this vote."
|
||||
case .networkUnavailable:
|
||||
return "Unable to connect. Please check your internet connection."
|
||||
case .encodingError:
|
||||
@@ -49,7 +52,7 @@ actor PollService {
|
||||
private let publicDatabase: CKDatabase
|
||||
|
||||
private var currentUserRecordID: String?
|
||||
private var pollSubscriptionID: CKSubscription.ID?
|
||||
private var pollSubscriptionIDs: Set<CKSubscription.ID> = []
|
||||
|
||||
private init() {
|
||||
self.container = CloudKitContainerConfig.makeContainer()
|
||||
@@ -231,7 +234,7 @@ actor PollService {
|
||||
func updateVote(_ vote: PollVote) async throws -> PollVote {
|
||||
let userId = try await getCurrentUserRecordID()
|
||||
guard vote.odg == userId else {
|
||||
throw PollError.notPollOwner // Using this error for now - voter can only update own vote
|
||||
throw PollError.notVoteOwner
|
||||
}
|
||||
|
||||
// Fetch the existing record to get the server's changeTag
|
||||
@@ -245,6 +248,13 @@ actor PollService {
|
||||
throw PollError.unknown(error)
|
||||
}
|
||||
|
||||
guard let existingVoterId = existingRecord[CKPollVote.voterIdKey] as? String else {
|
||||
throw PollError.encodingError
|
||||
}
|
||||
guard existingVoterId == userId else {
|
||||
throw PollError.notVoteOwner
|
||||
}
|
||||
|
||||
// Update the fields on the fetched record
|
||||
let now = Date()
|
||||
existingRecord[CKPollVote.rankingsKey] = vote.rankings
|
||||
@@ -320,11 +330,12 @@ actor PollService {
|
||||
// MARK: - Subscriptions
|
||||
|
||||
func subscribeToVoteUpdates(forPollId pollId: UUID) async throws {
|
||||
let subscriptionId = "poll-votes-\(pollId.uuidString)"
|
||||
let predicate = NSPredicate(format: "%K == %@", CKPollVote.pollIdKey, pollId.uuidString)
|
||||
let subscription = CKQuerySubscription(
|
||||
recordType: CKRecordType.pollVote,
|
||||
predicate: predicate,
|
||||
subscriptionID: "poll-votes-\(pollId.uuidString)",
|
||||
subscriptionID: subscriptionId,
|
||||
options: [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
|
||||
)
|
||||
|
||||
@@ -334,10 +345,12 @@ actor PollService {
|
||||
|
||||
do {
|
||||
try await publicDatabase.save(subscription)
|
||||
pollSubscriptionID = subscription.subscriptionID
|
||||
pollSubscriptionIDs.insert(subscription.subscriptionID)
|
||||
} catch let error as CKError {
|
||||
// Subscription already exists is OK
|
||||
if error.code != .serverRejectedRequest {
|
||||
if error.code == .serverRejectedRequest {
|
||||
pollSubscriptionIDs.insert(subscriptionId)
|
||||
} else {
|
||||
throw mapCloudKitError(error)
|
||||
}
|
||||
} catch {
|
||||
@@ -345,14 +358,23 @@ actor PollService {
|
||||
}
|
||||
}
|
||||
|
||||
func unsubscribeFromVoteUpdates() async throws {
|
||||
guard let subscriptionID = pollSubscriptionID else { return }
|
||||
func unsubscribeFromVoteUpdates(forPollId pollId: UUID? = nil) async throws {
|
||||
let subscriptionIds: [CKSubscription.ID]
|
||||
if let pollId {
|
||||
subscriptionIds = ["poll-votes-\(pollId.uuidString)"]
|
||||
} else {
|
||||
subscriptionIds = Array(pollSubscriptionIDs)
|
||||
}
|
||||
|
||||
do {
|
||||
try await publicDatabase.deleteSubscription(withID: subscriptionID)
|
||||
pollSubscriptionID = nil
|
||||
} catch {
|
||||
// Ignore errors - subscription may not exist
|
||||
guard !subscriptionIds.isEmpty else { return }
|
||||
|
||||
for subscriptionID in subscriptionIds {
|
||||
do {
|
||||
try await publicDatabase.deleteSubscription(withID: subscriptionID)
|
||||
} catch {
|
||||
// Ignore errors - subscription may not exist
|
||||
}
|
||||
pollSubscriptionIDs.remove(subscriptionID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user