diff --git a/Decide-Tests/Container/KeyedState_Tests.swift b/Decide-Tests/Container/KeyedState_Tests.swift index 0b63436..7bd8c7b 100644 --- a/Decide-Tests/Container/KeyedState_Tests.swift +++ b/Decide-Tests/Container/KeyedState_Tests.swift @@ -93,7 +93,7 @@ import DecideTesting XCTAssertEqual(sut.updatesCount, 3) XCTAssertEqual(sut.str[id], newValue) XCTAssertEqual(sut.strMutableObserve[id], newValue) - XCTAssertEqual(sut.strMutable[id].wrappedValue, newValue) + XCTAssertEqual(sut.strMutable[id], newValue) } func test_Observation_BindSet() async { @@ -107,12 +107,12 @@ import DecideTesting let newValue = "\(#function)-modified" - sut2.strMutable[id].wrappedValue = newValue + sut2.strMutable[id] = newValue env.setValue(newValue, \State.$str, at: id) XCTAssertEqual(sut.updatesCount, 2) - XCTAssertEqual(sut.strMutable[id].wrappedValue, newValue) + XCTAssertEqual(sut.strMutable[id], newValue) XCTAssertEqual(sut.str[id], newValue) XCTAssertEqual(sut.strMutableObserve[id], newValue) } diff --git a/Decide-Tests/SwiftUI_Tests.swift b/Decide-Tests/SwiftUI_Tests.swift new file mode 100644 index 0000000..08b39f3 --- /dev/null +++ b/Decide-Tests/SwiftUI_Tests.swift @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Decide package open source project +// +// Copyright (c) 2020-2023 Maxim Bazarov and the Decide package +// open source project authors +// Licensed under MIT +// +// See LICENSE.txt for license information +// +// SPDX-License-Identifier: MIT +// +//===----------------------------------------------------------------------===// + +import SwiftUI +import Decide +import XCTest +import DecideTesting + +@MainActor final class SwiftUI_Tests: XCTestCase { + + final class State: KeyedState { + @Property var str = "str-default" + @Mutable @Property var strMutable = "strMutable-default" + } + + struct ViewUnderTest: View { + @BindKeyed(\State.$strMutable) var strMutable + @ObserveKeyed(\State.$str) var str + @ObserveKeyed(\State.$strMutable) var strMutableObserved + + var body: some View { + TextField("", text: strMutable[1]) + Text(str[1]) + Text(strMutableObserved[1]) + } + } + +} + diff --git a/Decide/Accessor/Default/DefaultBindKeyed.swift b/Decide/Accessor/Default/DefaultBindKeyed.swift index 1356fc2..f676ac7 100644 --- a/Decide/Accessor/Default/DefaultBindKeyed.swift +++ b/Decide/Accessor/Default/DefaultBindKeyed.swift @@ -59,3 +59,30 @@ import Foundation set { fatalError() } } } + +@MainActor public struct KeyedValueBinding, Value> { + unowned var environment: ApplicationEnvironment + + let observer: Observer + let propertyKeyPath: KeyPath> + + init( + bind propertyKeyPath: KeyPath>, + observer: Observer, + environment: ApplicationEnvironment + ) { + self.propertyKeyPath = propertyKeyPath + self.observer = observer + self.environment = environment + } + + public subscript(_ identifier: I) -> Value { + get { + environment.subscribe(observer, on: propertyKeyPath, at: identifier) + return environment.getValue(propertyKeyPath, at: identifier) + } + set { + environment.setValue(newValue, propertyKeyPath, at: identifier) + } + } +} diff --git a/Decide/Accessor/Default/DefaultObserveKeyed.swift b/Decide/Accessor/Default/DefaultObserveKeyed.swift index 842b913..555e894 100644 --- a/Decide/Accessor/Default/DefaultObserveKeyed.swift +++ b/Decide/Accessor/Default/DefaultObserveKeyed.swift @@ -69,3 +69,27 @@ import Foundation set { fatalError() } } } + +@MainActor public struct KeyedValueObserve, Value> { + unowned var environment: ApplicationEnvironment + + let observer: Observer + let propertyKeyPath: KeyPath> + + init( + bind propertyKeyPath: KeyPath>, + observer: Observer, + environment: ApplicationEnvironment + ) { + self.propertyKeyPath = propertyKeyPath + self.observer = observer + self.environment = environment + } + + public subscript(_ identifier: I) -> Value { + get { + environment.subscribe(observer, on: propertyKeyPath, at: identifier) + return environment.getValue(propertyKeyPath, at: identifier) + } + } +} diff --git a/Decide/Accessor/KeyValueBinding.swift b/Decide/Accessor/KeyValueBinding.swift deleted file mode 100644 index 8ebb9e3..0000000 --- a/Decide/Accessor/KeyValueBinding.swift +++ /dev/null @@ -1,44 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Decide package open source project -// -// Copyright (c) 2020-2023 Maxim Bazarov and the Decide package -// open source project authors -// Licensed under MIT -// -// See LICENSE.txt for license information -// -// SPDX-License-Identifier: MIT -// -//===----------------------------------------------------------------------===// - -import SwiftUI - -@MainActor public struct KeyedValueBinding, Value> { - unowned var environment: ApplicationEnvironment - - let observer: Observer - let propertyKeyPath: KeyPath> - - init( - bind propertyKeyPath: KeyPath>, - observer: Observer, - environment: ApplicationEnvironment - ) { - self.propertyKeyPath = propertyKeyPath - self.observer = observer - self.environment = environment - } - - public subscript(_ identifier: I) -> Binding { - Binding( - get: { - environment.subscribe(observer, on: propertyKeyPath, at: identifier) - return environment.getValue(propertyKeyPath, at: identifier) - }, - set: { - return environment.setValue($0, propertyKeyPath, at: identifier) - } - ) - } -} diff --git a/Decide/Accessor/KeyValueObserve.swift b/Decide/Accessor/KeyValueObserve.swift deleted file mode 100644 index 032aa36..0000000 --- a/Decide/Accessor/KeyValueObserve.swift +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Decide package open source project -// -// Copyright (c) 2020-2023 Maxim Bazarov and the Decide package -// open source project authors -// Licensed under MIT -// -// See LICENSE.txt for license information -// -// SPDX-License-Identifier: MIT -// -//===----------------------------------------------------------------------===// - -import Foundation - -@MainActor public struct KeyedValueObserve, Value> { - unowned var environment: ApplicationEnvironment - - let observer: Observer - let propertyKeyPath: KeyPath> - - init( - bind propertyKeyPath: KeyPath>, - observer: Observer, - environment: ApplicationEnvironment - ) { - self.propertyKeyPath = propertyKeyPath - self.observer = observer - self.environment = environment - } - - public subscript(_ identifier: I) -> Value { - get { - environment.subscribe(observer, on: propertyKeyPath, at: identifier) - return environment.getValue(propertyKeyPath, at: identifier) - } - } - - -} diff --git a/Decide/Accessor/SwiftUI/BindKeyed.swift b/Decide/Accessor/SwiftUI/BindKeyed.swift index a98e029..ef1a277 100644 --- a/Decide/Accessor/SwiftUI/BindKeyed.swift +++ b/Decide/Accessor/SwiftUI/BindKeyed.swift @@ -27,19 +27,29 @@ import SwiftUI self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) } - public lazy var wrappedValue: KeyedValueObserve = { - return KeyedValueObserve( - bind: propertyKeyPath, - observer: Observer(observer), - environment: environment + public subscript(_ identifier: I) -> Binding { + Binding( + get: { + environment.subscribe( + Observer(observer), + on: propertyKeyPath, + at: identifier) + return environment.getValue(propertyKeyPath, at: identifier) + }, + set: { + return environment.setValue($0, propertyKeyPath, at: identifier) + } ) - }() + } - public lazy var projectedValue: KeyedValueBinding = { - return KeyedValueBinding( - bind: propertyKeyPath, - observer: Observer(observer), - environment: environment - ) - }() + public subscript(_ identifier: I) -> Value { + get { + environment.subscribe(Observer(observer), on: propertyKeyPath, at: identifier) + return environment.getValue(propertyKeyPath, at: identifier) + } + } + + public var wrappedValue: Self { + self + } } diff --git a/Decide/Accessor/SwiftUI/ObserveKeyed.swift b/Decide/Accessor/SwiftUI/ObserveKeyed.swift index d65c454..34e9fc9 100644 --- a/Decide/Accessor/SwiftUI/ObserveKeyed.swift +++ b/Decide/Accessor/SwiftUI/ObserveKeyed.swift @@ -37,11 +37,14 @@ import SwiftUI self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) } - public lazy var wrappedValue: KeyedValueObserve = { - return KeyedValueObserve( - bind: propertyKeyPath, - observer: Observer(observer), - environment: environment - ) - }() + public subscript(_ identifier: I) -> Value { + get { + environment.subscribe(Observer(observer), on: propertyKeyPath, at: identifier) + return environment.getValue(propertyKeyPath, at: identifier) + } + } + + public var wrappedValue: Self { + self + } }