Libraries that make swift-dependencies even more useful
Xcode's support for protocol-oriented declarations and implementations is very strong. However, as we understood in the Point-Free episode, we pay a price for this in exchange for some flexibility. So is there a way to move things forward while getting the benefits of both? Yes, that is macros! Macros allow us to automatically convert protocol-based to struct-based. This is an approach that works very well. By depositing the implementation in the macro, the protocol becomes an entity to be assisted by Xcode, and is internally converted into a function call of the implementation.
Look at this first. Swift The power of Macro makes it possible to cut out and rewrite a single function, even if it is implemented in a protocol.
import DependenciesExtrasMacros
import Foundation
extension DependencyValues {
#DependencyValueRegister(of: GreatTool.self, into: "great")
}
@DependencyProtocolClient(implemented: Implements.self)
public protocol GreatTool {
func move() async
func play(name: String) async -> String
func stop(_ b: Double) async throws -> Double
func yes(_ what: inout String) async -> Bool
}
public actor Implements: GreatTool {
var inState = 1
public func yes(_ what: inout String) async -> Bool {
what += "!"
return true
}
public func move() async {
inState += 1
print("moving \(inState)")
}
public func play(name: String) async -> String {
name + "playing"
}
public func stop(_ b: Double) async throws -> Double {
return b
}
}
The first step is to give the already existing protocol a macro that informs the world that this will be used for dependency resolution.
+ @DependencyProtocolClient(implemented: Implements.self)
public protocol GreatTool {
...
}
Next, register a structure in DependencyValues that conforms to the DependencyKey generated by the macro
+ extension DependencyValues {
+ #DependencyValueRegister(of: GreatTool.self, into: "great")
+ }
This ends the need for us to be hands on! This is the only way things will start to work. If it doesn't work or has behavior you don't expect, please give us feedback. We welcome your contribution!
The latest documentation for the Dependencies APIs is available here.
You can add Dependencies to an Xcode project by adding it to your project as a package.
If you want to use Dependencies in a SwiftPM project, it's as
simple as adding it to your Package.swift
:
dependencies: [
.package(url: "https://github.com/arasan01/swift-dependencies-extras", from: "0.1.0")
]
And then adding the product to any target that needs access to the library:
.product(name: "DependenciesExtrasMacros", package: "swift-dependencies-extras"),
Automatically rewrite the conventional design consisting of Protocol, Class, and Struct based on swift-dependencies in PointFree style, allowing rewriting of each implemented function one by one.
This library is released under the MIT license. See LICENSE for details.