Skip to content

Commit

Permalink
VIT-7468: Workaround iOS 18 CheckedContinuation crash (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
andersio authored Sep 18, 2024
1 parent aa3b42b commit df78aa5
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 20 deletions.
6 changes: 3 additions & 3 deletions Sources/VitalCore/Core/Client/ProtectedBox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public final class ProtectedBox<T>: @unchecked Sendable {

/// Get the current value, or wait until it is set.
public func get() async -> T {
return await withCheckedContinuation { continuation in
return await withUnsafeContinuation { continuation in
lock.withLock {
switch self.state {
case let .awaiting(continuations):
Expand All @@ -50,7 +50,7 @@ public final class ProtectedBox<T>: @unchecked Sendable {
}

public func set(value: T) {
let continuationsToCall: [CheckedContinuation<T, Never>] = lock.withLock {
let continuationsToCall: [UnsafeContinuation<T, Never>] = lock.withLock {
defer {
self.state = .ready(value)
}
Expand Down Expand Up @@ -84,7 +84,7 @@ public final class ProtectedBox<T>: @unchecked Sendable {

private enum BoxState<T> {
case ready(T)
case awaiting([CheckedContinuation<T, Never>])
case awaiting([UnsafeContinuation<T, Never>])

var isReady: Bool {
switch self {
Expand Down
6 changes: 3 additions & 3 deletions Sources/VitalCore/JWT/VitalJWTAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ internal struct VitalSignInTokenClaims: Decodable {
@_spi(VitalSDKInternals)
public final class ParkingLot: @unchecked Sendable {
enum State: Sendable {
case mustPark([UUID: CheckedContinuation<Void, any Error>] = [:])
case mustPark([UUID: UnsafeContinuation<Void, any Error>] = [:])
case disabled
}

Expand All @@ -495,7 +495,7 @@ public final class ParkingLot: @unchecked Sendable {
public init() {}

public func tryTo(_ action: Action) -> Bool {
let (callersToRelease, hasTransitioned): ([CheckedContinuation<Void, any Error>], Bool) = lock.withLock {
let (callersToRelease, hasTransitioned): ([UnsafeContinuation<Void, any Error>], Bool) = lock.withLock {
switch (self.state, action) {
case (.disabled, .enable):
self.state = .mustPark()
Expand Down Expand Up @@ -525,7 +525,7 @@ public final class ParkingLot: @unchecked Sendable {
return try await withTaskCancellationHandler {
try Task.checkCancellation()

return try await withCheckedThrowingContinuation { continuation in
return try await withUnsafeThrowingContinuation { continuation in
let mustPark = lock.withLock {
switch self.state {
case let .mustPark(parked):
Expand Down
4 changes: 2 additions & 2 deletions Sources/VitalDevices/DeviceReading/Libre1Reader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public class Libre1Reader {
}

public func read() async throws -> (Libre1Read) {
/// We need to retain the NFC object, otherwise it's released inside `withCheckedThrowingContinuation`
/// We need to retain the NFC object, otherwise it's released inside `withUnsafeThrowingContinuation`
var nfc: NFC!

let payload: (Sensor, [Glucose]) = try await withCheckedThrowingContinuation { continuation in
let payload: (Sensor, [Glucose]) = try await withUnsafeThrowingContinuation { continuation in
nfc = NFC(
readingMessage: readingMessage,
errorMessage: errorMessage,
Expand Down
4 changes: 2 additions & 2 deletions Sources/VitalDevices/NFC/NFC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class NFC: NSObject, NFCTagReaderSessionDelegate {
let readingMessage: String
let errorMessage: String
let completionMessage: String
private var continuation: CheckedContinuation<(Sensor, [Glucose]), Error>?
private var continuation: UnsafeContinuation<(Sensor, [Glucose]), Error>?
private let queue: DispatchQueue

var taskRequest: TaskRequest? {
Expand All @@ -139,7 +139,7 @@ class NFC: NSObject, NFCTagReaderSessionDelegate {
readingMessage: String,
errorMessage: String,
completionMessage: String,
continuation: CheckedContinuation<(Sensor, [Glucose]), Error>?,
continuation: UnsafeContinuation<(Sensor, [Glucose]), Error>?,
queue: DispatchQueue
) {
self.readingMessage = readingMessage
Expand Down
8 changes: 4 additions & 4 deletions Sources/VitalHealthKit/HealthKit/Abstractions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ final class CancellableQueryHandle<Result>: @unchecked Sendable {
case idle
case cancelled
case completed
case running(HKHealthStore, HKQuery, CheckedContinuation<Result, any Error>)
case running(HKHealthStore, HKQuery, UnsafeContinuation<Result, any Error>)
}

private var state: State = .idle
Expand All @@ -589,7 +589,7 @@ final class CancellableQueryHandle<Result>: @unchecked Sendable {
try await withTaskCancellationHandler {
try Task.checkCancellation()

let result = try await withCheckedThrowingContinuation { continuation in
let result = try await withUnsafeThrowingContinuation { continuation in
let query = queryFactory(Continuation(query: self))
transition(to: .running(store, query, continuation))
}
Expand All @@ -608,8 +608,8 @@ final class CancellableQueryHandle<Result>: @unchecked Sendable {
}

@discardableResult
private func transition(to newState: State) -> CheckedContinuation<Result, any Error>? {
let (doWork, continuation): ((() -> Void)?, CheckedContinuation<Result, any Error>?) = lock.withLock {
private func transition(to newState: State) -> UnsafeContinuation<Result, any Error>? {
let (doWork, continuation): ((() -> Void)?, UnsafeContinuation<Result, any Error>?) = lock.withLock {
switch (state, newState) {
case let (.idle, .running(store, query, _)):

Expand Down
12 changes: 6 additions & 6 deletions Tests/VitalCoreTests/VitalClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class VitalClientTests: XCTestCase {
}

func testAutomaticConfiguration_autoMigrateFromLegacyAPIMode() async throws {
let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand Down Expand Up @@ -98,7 +98,7 @@ class VitalClientTests: XCTestCase {
let newClient = VitalClient(secureStorage: secureStorage)
VitalClient.setClient(newClient)

let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand All @@ -115,7 +115,7 @@ class VitalClientTests: XCTestCase {
}

func testAutomaticConfiguration_userJWTMode() async throws {
let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand All @@ -142,7 +142,7 @@ class VitalClientTests: XCTestCase {
let newClient = VitalClient(secureStorage: secureStorage)
VitalClient.setClient(newClient)

let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand All @@ -159,7 +159,7 @@ class VitalClientTests: XCTestCase {
}

func testAutoConfigurationDoesNotFailWithUserIdWithoutConfiguration() async {
let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand All @@ -176,7 +176,7 @@ class VitalClientTests: XCTestCase {
let newClient = VitalClient(secureStorage: secureStorage)
VitalClient.setClient(newClient)

let _: Void = await withCheckedContinuation { continuation in
let _: Void = await withUnsafeContinuation { continuation in
VitalClient.automaticConfiguration {
continuation.resume(returning: ())
}
Expand Down

0 comments on commit df78aa5

Please sign in to comment.