PublishedKVO provides Apples Combine @Published
for class-types using Key-Value-Observing (KVO requires classes to be NSObject-based).
@PublishedKVO
automatically publishes objects based on one or mutliple key paths.
Attention: When using with SwiftUI unexpected results may occur since this publisher usually emits values after
they are set inside the object (and before if the variable is overwritten/re-assigned), not always before as with the
structs willSet-based @Published
- this is mostly related to SwiftUIs diffing and/or animation features, probably.
- Swift >= 5
- iOS >= 13
- macOS >= 10.15
- tvOS >= 13
- watchOS >= 6
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler.
Add the Package URL https://github.com/matis-schotte/PublishedKVO.git
in Xcodes project viewer.
Adding it to another Package as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/matis-schotte/PublishedKVO.git", from: "0.1.0")
]
class Example {
@PublishedKVO(\.completedUnitCount)
var progress = Progress(totalUnitCount: 2)
@Published
var textualRepresentation = "text"
}
let ex = Example()
// Set up the publishers
let c1 = ex.$progress.sink { print("\($0.fractionCompleted) completed") }
let c1 = ex.$textualRepresentation.sink { print("\($0)") }
// Interact with the class as usual
ex.progress.completedUnitCount += 1
// outputs "0.5 completed"
// And compare with Combines @Published (almost°) same behaviour
ex.textualRepresentation = "string"
// outputs "string"
ex.$progress.emit() // Re-emits the current value
ex.$progress.send(ex.progress) // Emits given value
° See Attention
comment from above about SwiftUI and the following example:
class Example {
@PublishedKVO(\.completedUnitCount)
var progress1 = Progress(totalUnitCount: 5)
@Published
var progress2 = Progress(totalUnitCount: 5)
@Published
var progress3 = "0.0"
}
let ex = Example()
// Class using @PublishedKVO
let c1 = ex.$progress1.sink { print("$progress1 incomming \($0.fractionCompleted) actual \(ex.progress1.fractionCompleted)") }
// Class using @Published
let c2 = ex.$progress2.sink { print("$progress2 incomming \($0.fractionCompleted) actual \(ex.progress2.fractionCompleted)") }
// Struct using @Published
let c3 = ex.$progress3.sink { print("$progress3 incomming \($0) actual \(ex.progress3)") }
ex.progress1.completedUnitCount += 1
ex.progress2.completedUnitCount += 1
ex.progress3 = "0.2"
ex.progress1.completedUnitCount += 1
ex.progress2.completedUnitCount += 1
ex.progress3 = "0.4"
/* Outputs (incomming should new value, actual should be old value):
$progress1 incomming 0.0 actual 0.0
$progress2 incomming 0.0 actual 0.0
$progress3 incomming 0.0 actual 0.0
$progress1 incomming 0.2 actual 0.2
// no output from $progress2
$progress3 incomming 0.2 actual 0.0
$progress1 incomming 0.4 actual 0.4
// no output from $progress2
$progress3 incomming 0.4 actual 0.2
*/
- Add SwiftLint (by adding xcodeproj:
swift package generate-xcodeproj
, helps support Xcode Server, too) - Add Travis CI (without xcodeproj see reddit, medium)
- Add codecov
- Add codebeat
- Add codeclimate
- Add codetriage
- Add jazzy docs
- Add CHANGELOG.md
- Add Carthage support
- Add Cocoapods support
PublishedKVO is available under the Apache-2.0 license. See the LICENSE file for more info.
Matis Schotte, dm26f1cab8aa26@ungeord.net