codebendr-product-designer / swift-dependencies

A dependency management library inspired by SwiftUI's "environment."

Home Page:https://www.pointfree.co/collections/composable-architecture/reducer-protocol/ep205-reducer-protocol-dependencies-part-1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dependencies

A dependency management library inspired by SwiftUI's "environment."

CI

Learn More

This library was motivated and designed over the course of many episodes on Point-Free, a video series exploring functional programming and the Swift language, hosted by Brandon Williams and Stephen Celis.

video poster image

Overview

Dependencies are the types and functions in your application that need to interact with outside systems that you do not control. Classic examples of this are API clients that make network requests to servers, but also seemingly innocuous things such as UUID and Date initializers, file access, user defaults, and even clocks and timers, can all be thought of as dependencies.

You can get really far in application development without ever thinking about dependency management (or, as some like to call it, "dependency injection”), but eventually uncontrolled dependencies can cause many problems in your code base and development cycle:

  • Uncontrolled dependencies make it difficult to write fast, deterministic tests because you are susceptible to the vagaries of the outside world, such as file systems, network connectivity, internet speed, server uptime, and more.

  • Many dependencies do not work well in SwiftUI previews, such as location managers and speech recognizers, and some do not work even in simulators, such as motion managers, and more. This prevents you from being able to easily iterate on the design of features if you make use of those frameworks.

  • Dependencies that interact with 3rd party, non-Apple libraries (such as Firebase, web socket libraries, network libraries, etc.) tend to be heavyweight and take a long time to compile. This can slow down your development cycle.

For these reasons, and a lot more, it is highly encouraged for you to take control of your dependencies rather than letting them control you.

But, controlling a dependency is only the beginning. Once you have controlled your dependencies, you are faced with a whole set of new problems:

  • How can you propagate dependencies throughout your entire application that is more ergonomic than explicitly passing them around everywhere, but safer than having a global dependency?

  • How can you override dependencies for just one portion of your application? This can be handy for overriding dependencies for tests and SwiftUI previews, as well as specific user flows such as onboarding experiences.

  • How can you be sure you overrode all dependencies a feature uses in tests? It would be incorrect for a test to mock out some dependencies but leave others as interacting with the outside world.

This library addresses all of the points above, and much, much more. Explore all of the tools this library comes with by checking out the documentation, and reading these articles:

Getting started

  • Quick start: Learn the basics of getting started with the library before diving deep into all of its features.

  • What are dependencies?: Learn what dependencies are, how they complicate your code, and why you want to control them.

Essentials

  • Using dependencies: Learn how to use the dependencies that are registered with the library.

  • Registering dependencies: Learn how to register your own dependencies with the library so that they immediately become available from any part of your code base.

  • Live, preview, and test dependencies: Learn how to provide different implementations of your dependencies for use in the live application, as well as in Xcode previews, and even in tests.

Advanced

  • Designing dependencies: Learn techniques on designing your dependencies so that they are most flexible for injecting into features and overriding for tests.

  • Overriding dependencies: Learn how dependencies can be changed at runtime so that certain parts of your application can use different dependencies.

  • Dependency lifetimes: Learn about the lifetimes of dependencies, how to prolong the lifetime of a dependency, and how dependencies are inherited.

  • Single entry point systems: Learn about "single entry point" systems, and why they are best suited for this dependencies library, although it is possible to use the library with non-single entry point systems.

Miscellaneous

  • Concurrency support: Learn about the concurrency tools that come with the library that make writing tests and implementing dependencies easy.

Examples

We rebuilt Apple's Scrumdinger demo application using modern, best practices for SwiftUI development, including using this library to control dependencies on file system access, timers and speech recognition APIs. That demo can be found in our SwiftUINavigation library.

Documentation

The latest documentation for the Dependencies APIs is available here.

Installation

You can add Dependencies to an Xcode project by adding it to your project as a package.

https://github.com/pointfreeco/swift-dependencies

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/pointfreeco/swift-dependencies", from: "0.1.0")
]

And then adding the product to any target that needs access to the library:

.product(name: "Dependencies", package: "swift-dependencies"),

License

This library is released under the MIT license. See LICENSE for details.

About

A dependency management library inspired by SwiftUI's "environment."

https://www.pointfree.co/collections/composable-architecture/reducer-protocol/ep205-reducer-protocol-dependencies-part-1

License:MIT License


Languages

Language:Swift 99.2%Language:Makefile 0.8%