tgrapperon / swift-dependencies-additions Goto Github PK
View Code? Open in Web Editor NEWMore dependencies for `swift-dependencies`
License: MIT License
More dependencies for `swift-dependencies`
License: MIT License
Hi Thomas,
I'd like to suggest two additions to your dependencies library:
Thanks!
Right now, the Logger
dependency has a subscript that allows to post logs to a specific category on the spot:
@Dependency(\.logger["MyCategory"]) var logger
Sending messages to this logger will log them under the "MyCategory" category of the subsystem represented by you app's bundle identifier. In other words, it is equivalent to post on:
Logger(subsystem: "com.mycompany.myapp", category: "MyCategory")
This is the default Apple is suggesting in the documentation.
For consistency, the library uses its Bundle
dependency to fill this information. But this has the annoying side effect of forcing users to explicitly specify a bundle identifier when testing. The bundle identifier dependency indeeds defaults to unimplemented
when testing.
This is highly unintuitive. I'm exploring alternative solutions/workarounds, and also if there is something more general around the ergonomics of dependencies that embed other dependencies.
Hey! Logger does not output anything in iTerm when code is run using executableTarget, is it possible to fix that? I do see output in Xcode's console...
After we add support for CLLocationManager
, I would like to add a more ergonomic wrapper around it, allowing things like getLocation() async throws -> CLLocationCoordinate2D
.
With CLLocationManager
working with a delegate pattern, it's a bit complex to implement correctly but I did it in a simple project so I should be able to replicate it here.
I'm just not sure what features we would like to add in this dependency. Thinking about it for 1 minute, I see something like:
getLocation() async throws -> CLLocationCoordinate2D
locations() -> AsyncStream<CLLocationCoordinate2D>
Originally posted by m-housh May 19, 2023
Forgive my ignorance with CoreData
in general, but I'm playing around with the _CoreDataDependency
and trying to determine how to update a Fetched
item. I have tried several approaches, mainly the following...
struct TodoFeature: Reducer {
struct State: Equatable {
var todos: Todo.FetchedResults = .empty
}
Action: Equatable {
...
case toggleComplete(todo: Fetched<Todo>)
}
@Dependency(\.persistentContainer) var persistentContainer;
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
...
case .toggleComplete(todo: let todo):
todo.withManagedObject { update in
update.complete.toggle()
try! update.managedObjectContext!.save()
}
return .none
}
}
}
}
This does not update the view / state, however if I shut the app down and restart it, the complete value is toggled. So I'm not sure if I need to invalidate the cached items that have been fetched, but calling my task that initially loads the todo's does not seem to update the todo's state either. Once again, forgive my ignorance in working with core data in general as it seems like there's something basic that I'm missing.
Here's the repository for more complete example.
Hi,
I have a SwiftUI Form
which shows a Picker
which is driven by a @Dependency.AppStorage
backed property in my model. The corresponding user default is set when changing the picker's selection, but the view is not updated accordingly. The picker is not dismissed and the checkmark does not change.
class ViewModel: ObservableObject {
@Dependency.AppStorage("myDefault") public var myDefault = "one"
}
struct MyView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
NavigationStack {
Form {
Picker("Default value", selection: $viewModel.myDefault) {
Text("one").tag("one")
Text("two").tag("two")
Text("three").tag("three")
}
}
}
}
}
Any ideas?
Btw: I'm using watchOS.
I am using Tuist to build the project and using latest TCA v1.2.0. But when I fetch the dependencies I am getting the error:
Dependencies could not be resolved because root depends on 'swift-dependencies-additions' 0.1.0..<1.0.0 and root depends on 'swift-composable-architecture' 1.2.0..<2.0.0.
when trying to link the package.
error: Dependencies could not be resolved because root depends on 'swift-dependencies-additions' 0.1.0..<1.0.0 and root depends on 'swift-composable-architecture' 1.2.0..<2.0.0.
'swift-dependencies-additions' is incompatible with 'swift-composable-architecture' because 'swift-composable-architecture' 1.2.0 depends on 'xctest-dynamic-overlay' 1.0.0..<2.0.0 and no versions of 'swift-composable-architecture' match the requirement 1.2.1..<2.0.0.
If 'swift-dependencies-additions' 0.1.0..<1.0.0 and 'swift-composable-architecture' 1.2.0 then 'xctest-dynamic-overlay' 0.8.0..<1.0.0 because 'swift-dependencies-additions' 0.5.2 depends on 'xctest-dynamic-overlay' 0.8.0..<1.0.0 and 'swift-composable-architecture' 1.2.0 depends on 'swift-dependencies' 1.0.0..<2.0.0.
'swift-dependencies-additions' {0.1.0..<0.5.2, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 or 'xctest-dynamic-overlay' 0.8.0..<1.0.0 because 'swift-dependencies-additions' 0.5.0 depends on 'swift-dependencies' 0.4.0..<1.0.0 and 'swift-dependencies-additions' 0.5.1 depends on 'xctest-dynamic-overlay' 0.8.0..<1.0.0.
'swift-dependencies-additions' {0.1.0..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because 'swift-dependencies-additions' 0.3.2 depends on 'swift-dependencies' 0.1.0..<1.0.0 and 'swift-dependencies-additions' 0.4.0 depends on 'swift-dependencies' 0.1.0..<1.0.0.
'swift-dependencies-additions' {0.1.0..<0.3.2, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because 'swift-dependencies-additions' 0.3.0 depends on 'swift-dependencies' 0.1.0..<1.0.0 and 'swift-dependencies-additions' 0.3.1 depends on 'swift-dependencies' 0.1.0..<1.0.0.
'swift-dependencies-additions' {0.1.0..<0.3.0, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because 'swift-dependencies-additions' 0.1.3 depends on 'swift-dependencies' 0.1.0..<1.0.0 and 'swift-dependencies-additions' 0.2.0 depends on 'swift-dependencies' 0.1.0..<1.0.0.
'swift-dependencies-additions' {0.1.0..<0.1.3, 0.1.4..<0.2.0, 0.2.1..<0.3.0, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because 'swift-dependencies-additions' 0.1.1 depends on 'swift-dependencies' 0.1.0..<1.0.0 and 'swift-dependencies-additions' 0.1.2 depends on 'swift-dependencies' 0.1.0..<1.0.0.
'swift-dependencies-additions' {0.1.0..<0.1.1, 0.1.4..<0.2.0, 0.2.1..<0.3.0, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because 'swift-dependencies-additions' 0.1.0 depends on 'swift-dependencies' 0.1.0..<1.0.0.
'swift-dependencies-additions' {0.1.0, 0.1.4..<0.2.0, 0.2.1..<0.3.0, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} practically depends on 'swift-dependencies' 0.1.0..<1.0.0 because no versions of 'swift-dependencies-additions' match the requirement {0.1.4..<0.2.0, 0.2.1..<0.3.0, 0.3.3..<0.4.0, 0.4.1..<0.5.0, 0.5.3..<1.0.0} and 'swift-dependencies-additions' 0.1.0 depends on 'swift-dependencies' 0.1.0..<1.0.0.
Any help would be appreciated
At first I thought there was no documentation for this repo since it's not mentioned in the ReadMe. I see that there used to be documentation on github pages, but that looks inactive now. I did see that swift package index is hosting documentation here, however, it looks like it's missing everything except for the front page.
Finally, I built the documentation for myself in Xcode and discovered that there's already fantastic documentation. You can find it be using Product > Build Documentation
then Window > Developer Documentation
, or you can also use Xcode 15's new Documentation Preview Assistant.
To help with discoverability, could we please add a link to the documentation in the ReadMe.
Also, could we reach out to swift package index to find out why their documentation hosting is missing pages?
If you want you can assign this to me.
Hello, I've found out that UserDefaults.Dependency.previewValue
does not re-initialize and leaks to other withDependencies
's.
Here is a MWE. With the following view / model pair,
final class ContentViewModel: ObservableObject {
@Published var text1 = "nil"
@Published var text2 = "nil"
@Dependency.AppStorage("myDefault1") private var myDefault1: String?
@Dependency.AppStorage("myDefault2") private var myDefault2: String?
init() {
if let myDefault1 { text1 = myDefault1 }
if let myDefault2 { text2 = myDefault2 }
}
}
struct ContentView: View {
@ObservedObject private(set) var viewModel: ContentViewModel
var body: some View {
VStack {
Text(viewModel.text1)
Text(viewModel.text2)
}
}
}
when I setup a preview as:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(viewModel: withDependencies {
// $0.userDefaults = .previewValue
$0.userDefaults.set("v1", forKey: "myDefault1")
} operation: {
ContentViewModel()
})
ContentView(viewModel: withDependencies {
// $0.userDefaults = .previewValue
$0.userDefaults.set("v2", forKey: "myDefault2")
} operation: {
ContentViewModel()
})
}
}
the two ContentView
s display the same content, which means that the .previewValue
is not being reset. Removing either of the comments work as (I have) expected.
I'm not 100% sure if this is a bug, but it seems misleading because the documentation for withDependencies
says (emphasis mine):
updateValuesForOperation
A closure for updating the current dependency values for the duration of the operation.
I initially discovered this behavior testing a somewhat complex logic---involving asynchronous codes manipulating user default key-value pairs---, and it took quite a bit of time to locate the cause.
Should this be considered a bug, or an expected behavior?
Thanks!
Hey Thomas! Any plans on adding a lightweight persistence dependency that saves data (Codable
s) to the file system? Potentially just a wrapper around some other library? I've used Disk in the past, but it seems dead, and is iOS only (was gonna fix that, but saw PRs seem to be ignored, because not maintained). So I took a look around and potentially these are candidates more suitable than Disk?
Or are you reluctant adding a SPM dependency to implement a... dependency ๐คช, I completely understand that if that is the case. If so, any plans for implementing this yourself?
I'm not sure if it's a bug or I'm doing something wrong, but there is an equal chance to get the test passed or failed using this code:
final class ViewSpec: QuickSpec {
// MARK: Spec
override func spec() {
describe("View") {
let width = 320.0
let height = 1000.0
it("should match snapshots in dark mode") { @MainActor in
withDependencies {
$0.userDefaults = .liveValue
} operation: {
assertSnapshot(
matching: View(screenWidth: width, previousView: String())
.environment(\.colorScheme, .dark),
as: .image(layout: .fixed(width: width, height: height)),
named: "View.dark"
)
}
}
it("should match snapshots in light mode") { @MainActor in
withDependencies {
$0.userDefaults = .liveValue
} operation: {
assertSnapshot(
matching: View(screenWidth: width, previousView: String())
.environment(\.colorScheme, .light),
as: .image(layout: .fixed(width: width, height: height)),
named: "View.light"
)
}
}
}
}
}
It always passes in dark mode but has a random chance of failing in light mode. ๐ค
Uncaught Exception: Unimplemented: @Dependency(\.userDefaults)
There is no dependency for CLLocationManager
yet, I am working on adding support for it.
I don't understand the cause of this but when I put this in my test, it refuses to build:
await withDependencies {
$0.userNotificationCenter.$add = { @Sendable userNotificationRequest in
await requests.setValue([userNotificationRequest])
}
} operation: {
// ...
}
Xcode provides no error other than Command SwiftCompile failed with a nonzero exit code.
(I did also clean my build folder and clear derived data folder). After much sleuthing I found that the offending line was this:
$0.userNotificationCenter.$add = { @Sendable userNotificationRequest in
await requests.setValue([userNotificationRequest])
}
When I remove it, the test builds. When I assign it as a variable rather than inline, then it builds.
let add = { @Sendable userNotificationRequest in
await requests.setValue([userNotificationRequest])
}
$0.userNotificationCenter.$add = add // this builds
Is this a bug, or am I using something wrong?
You can see the full code at: https://github.com/DandyLyons/BrittanyArima-Steps/blob/31-add-unit-tests/StepsTests/SettingsViewTests.swift
There is a problem in the UserDefaults dependency
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.