Skip to content

Commit

Permalink
Merge branch 'main' into fix-uikit-identifiable-dismiss
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencelis authored Nov 12, 2024
2 parents 2289a14 + a952dde commit 8e5bd5b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 11 deletions.
17 changes: 8 additions & 9 deletions Sources/ComposableArchitecture/Internal/Create.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,23 @@
// THE SOFTWARE.

@preconcurrency import Combine
import Darwin
import Foundation

final class DemandBuffer<S: Subscriber>: @unchecked Sendable {
private var buffer = [S.Input]()
private let subscriber: S
private var completion: Subscribers.Completion<S.Failure>?
private var demandState = Demand()
private let lock: os_unfair_lock_t
private let lock = NSRecursiveLock()

init(subscriber: S) {
self.subscriber = subscriber
self.lock = os_unfair_lock_t.allocate(capacity: 1)
self.lock.initialize(to: os_unfair_lock())
}

deinit {
self.lock.deinitialize(count: 1)
self.lock.deallocate()
}

func buffer(value: S.Input) -> Subscribers.Demand {
lock.lock()
defer { lock.unlock() }

precondition(
self.completion == nil, "How could a completed publisher sent values?! Beats me 🤷‍♂️")

Expand All @@ -55,6 +51,9 @@ final class DemandBuffer<S: Subscriber>: @unchecked Sendable {
}

func complete(completion: Subscribers.Completion<S.Failure>) {
lock.lock()
defer { lock.unlock() }

precondition(
self.completion == nil, "Completion have already occurred, which is quite awkward 🥺")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ final class CurrentValueRelay<Output>: Publisher {
}

func send(_ value: Output) {
self.lock.sync {
let subscriptions = self.lock.sync {
self.currentValue = value
return self.subscriptions
}
for subscription in self.lock.sync({ self.subscriptions }) {
for subscription in subscriptions {
subscription.receive(value)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ extension PersistenceReaderKey {
AppStorageKey(key)
}

/// Creates a persistence key that can read and write to a Date user default.
///
/// - Parameter key: The key to read and write the value to in the user defaults store.
/// - Returns: A user defaults persistence key.
public static func appStorage(_ key: String) -> Self
where Self == AppStorageKey<Date> {
AppStorageKey(key)
}

/// Creates a persistence key that can read and write to a user default as data.
///
/// - Parameter key: The key to read and write the value to in the user defaults store.
Expand Down Expand Up @@ -121,6 +130,15 @@ extension PersistenceReaderKey {
AppStorageKey(key)
}

/// Creates a persistence key that can read and write to an optional Date user default.
///
/// - Parameter key: The key to read and write the value to in the user defaults store.
/// - Returns: A user defaults persistence key.
public static func appStorage(_ key: String) -> Self
where Self == AppStorageKey<Date?> {
AppStorageKey(key)
}

/// Creates a persistence key that can read and write to a user default as optional data.
///
/// - Parameter key: The key to read and write the value to in the user defaults store.
Expand Down Expand Up @@ -198,6 +216,13 @@ public struct AppStorageKey<Value: Sendable>: Sendable {
self.store = UncheckedSendable(store)
}

fileprivate init(_ key: String) where Value == Date {
@Dependency(\.defaultAppStorage) var store
self.lookup = CastableLookup()
self.key = key
self.store = UncheckedSendable(store)
}

fileprivate init(_ key: String) where Value == Data {
@Dependency(\.defaultAppStorage) var store
self.lookup = CastableLookup()
Expand Down Expand Up @@ -254,6 +279,13 @@ public struct AppStorageKey<Value: Sendable>: Sendable {
self.store = UncheckedSendable(store)
}

fileprivate init(_ key: String) where Value == Date? {
@Dependency(\.defaultAppStorage) var store
self.lookup = OptionalLookup(base: CastableLookup())
self.key = key
self.store = UncheckedSendable(store)
}

fileprivate init(_ key: String) where Value == Data? {
@Dependency(\.defaultAppStorage) var store
self.lookup = OptionalLookup(base: CastableLookup())
Expand Down
39 changes: 39 additions & 0 deletions Tests/ComposableArchitectureTests/AppStorageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,38 @@ final class AppStorageTests: XCTestCase {
XCTAssertEqual(defaults.url(forKey: "url"), URL(string: "https://example.com"))
}

func testDefaultsReadDate() {
let expectedDate = Date()
@Dependency(\.defaultAppStorage) var defaults
defaults.set(expectedDate, forKey: "date")
@Shared(.appStorage("date")) var date: Date?
XCTAssertEqual(date, expectedDate)
}

func testDefaultsRegistered_Date() {
let expectedDate = Date()
@Dependency(\.defaultAppStorage) var defaults
@Shared(.appStorage("date")) var date: Date = expectedDate
XCTAssertEqual(defaults.object(forKey: "date") as? Date, expectedDate)

let newDate = Date().addingTimeInterval(60)
date = newDate
XCTAssertEqual(date, newDate)
XCTAssertEqual(defaults.object(forKey: "date") as? Date, newDate)
}

func testDefaultsRegistered_Optional_Date() {
let initialDate: Date? = Date()
@Dependency(\.defaultAppStorage) var defaults
@Shared(.appStorage("date")) var date: Date? = initialDate
XCTAssertEqual(defaults.object(forKey: "date") as? Date, initialDate)

let newDate = Date().addingTimeInterval(60)
date = newDate
XCTAssertEqual(date, newDate)
XCTAssertEqual(defaults.object(forKey: "date") as? Date, newDate)
}

func testDefaultsRegistered_Optional() {
@Dependency(\.defaultAppStorage) var defaults
@Shared(.appStorage("data")) var data: Data?
Expand Down Expand Up @@ -184,6 +216,13 @@ final class AppStorageTests: XCTestCase {
XCTAssertEqual(url2, nil)
}

func testOptionalInitializers_Date() {
@Shared(.appStorage("date1")) var date1: Date?
XCTAssertEqual(date1, nil)
@Shared(.appStorage("date2")) var date2: Date? = nil
XCTAssertEqual(date2, nil)
}

func testRemoveDuplicates() {
@Dependency(\.defaultAppStorage) var store
@Shared(.appStorage("count")) var count = 0
Expand Down

0 comments on commit 8e5bd5b

Please sign in to comment.