From 118483ec1748b24903a4a027d1a7bff9e0fd5e61 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Wed, 15 Jan 2025 18:31:59 -0800 Subject: [PATCH 1/5] Document recommendations for root object selection --- Documentation/Manual.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/Manual.md b/Documentation/Manual.md index 65a15748..e9bdfd2c 100644 --- a/Documentation/Manual.md +++ b/Documentation/Manual.md @@ -404,7 +404,15 @@ In a manual DI system it is simple for superclasses to receive injected dependen It is strongly recommended that projects adopting SafeDI start their migration by identifying the root of their dependency tree and making it `@Instantiable(isRoot: true)`. Once your root object has adopted SafeDI, continue migrating dependencies to SafeDI in either a breadth-first or depth-first manner. As your adoption of SafeDI progresses, you’ll find that you are removing more code than you are adding: many of your dependencies are likely being passed through intermediary objects that do not utilize the dependency except to instantiate a dependency deeper in the tree. Once types further down the dependency tree have adopted SafeDI, you will be able to avoid receiving dependencies in intermediary types. -## Example Application +### Selecting a root in SwiftUI applications + +SwiftUI applications have a natural root: the `App`-conforming type that is initialized when the binary is launched. + +### Selecting a root in UIKit applications + +UIKit applications’ natural root is the `UIApplicationDelegate`-conforming app delegate, however, this type inherits from the Objective-C `NSObject` which already has a no-argument `init()`. As such, it is best to create a custom `@Instantiable(isRoot: true) public final class Root: Instantiable` type that is initialized and stored by the application’s app delegate. + +## Example application We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in Xcode in the included [ExampleProjectIntegration](../Examples/ExampleProjectIntegration) project. From ee3e34789408ea25c76a6de72e33fae297526c4d Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Thu, 16 Jan 2025 13:23:44 -0800 Subject: [PATCH 2/5] Mention every example --- Documentation/Manual.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Manual.md b/Documentation/Manual.md index e9bdfd2c..7031b9cf 100644 --- a/Documentation/Manual.md +++ b/Documentation/Manual.md @@ -414,7 +414,7 @@ UIKit applications’ natural root is the `UIApplicationDelegate`-conforming app ## Example application -We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in Xcode in the included [ExampleProjectIntegration](../Examples/ExampleProjectIntegration) project. +We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in Xcode in the included [ExampleProjectIntegration](../Examples/ExampleProjectIntegration) project. This same multi-user notes app also exists in [an example Xcode project with multiple modules](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/ExamplePackageIntegration). ## Under the hood From d7dd2da7eeca791e499d850f57da72a28a549b09 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Thu, 16 Jan 2025 14:10:01 -0800 Subject: [PATCH 3/5] More parallelism --- Documentation/Manual.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Manual.md b/Documentation/Manual.md index 7031b9cf..a0b72c1c 100644 --- a/Documentation/Manual.md +++ b/Documentation/Manual.md @@ -412,9 +412,9 @@ SwiftUI applications have a natural root: the `App`-conforming type that is init UIKit applications’ natural root is the `UIApplicationDelegate`-conforming app delegate, however, this type inherits from the Objective-C `NSObject` which already has a no-argument `init()`. As such, it is best to create a custom `@Instantiable(isRoot: true) public final class Root: Instantiable` type that is initialized and stored by the application’s app delegate. -## Example application +## Example applications -We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in Xcode in the included [ExampleProjectIntegration](../Examples/ExampleProjectIntegration) project. This same multi-user notes app also exists in [an example Xcode project with multiple modules](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/ExamplePackageIntegration). +We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in [an example single-module Xcode project](../Examples/ExampleProjectIntegration) project. This same multi-user notes app also exists in [an example multi-module Xcode project](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/ExamplePackageIntegration). ## Under the hood From 4221f0c0b43ee766351353e6073440eb89c52d43 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Thu, 16 Jan 2025 14:14:06 -0800 Subject: [PATCH 4/5] cleanup --- Documentation/Manual.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Manual.md b/Documentation/Manual.md index a0b72c1c..73e28b99 100644 --- a/Documentation/Manual.md +++ b/Documentation/Manual.md @@ -414,7 +414,7 @@ UIKit applications’ natural root is the `UIApplicationDelegate`-conforming app ## Example applications -We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in [an example single-module Xcode project](../Examples/ExampleProjectIntegration) project. This same multi-user notes app also exists in [an example multi-module Xcode project](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/ExamplePackageIntegration). +We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in [an example single-module Xcode project](../Examples/ExampleProjectIntegration). This same multi-user notes app also exists in [an example multi-module Xcode project](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/ExamplePackageIntegration). ## Under the hood diff --git a/README.md b/README.md index 3aa30fb9..3918ac0c 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ You can see this integration in practice in the [ExamplePackageIntegration](Exam #### CocoaPods -Use a pre-build script ([example](Examples/ExampleCocoaPodsIntegration/safeditool.sh)) to download the `SafeDITool` binary and generate your SafeDI dependency tree. Make sure to set `ENABLE_USER_SCRIPT_SANDBOXING` to `NO` in the target running the pre-build script. +Use a pre-build script to download the `SafeDITool` binary and generate your SafeDI dependency tree ([example](Examples/ExampleCocoaPodsIntegration/safeditool.sh)). Make sure to set `ENABLE_USER_SCRIPT_SANDBOXING` to `NO` in the target running the pre-build script. You can see this integration in practice in the [ExampleCocoaPodsIntegration](Examples/ExampleCocoaPodsIntegration) package. Run `bundle exec pod install --project-directory=Examples/ExampleCocoaPodsIntegration` to create the `ExampleCocoaPodsIntegration.xcworkspace`. From a6bdb70b42da1d0a6d7c0b266cf6bf54ce7d70b4 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Thu, 16 Jan 2025 14:15:36 -0800 Subject: [PATCH 5/5] simplify --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 3918ac0c..905a9d5a 100644 --- a/README.md +++ b/README.md @@ -122,11 +122,7 @@ You can see this integration in practice in the [ExampleCocoaPodsIntegration](Ex #### Additional configurations -If your first-party code comprises multiple modules in Xcode, or a mix of Xcode Projects and Swift Packages, or some other configuration, once your Xcode project depends on the SafeDI package you will need to utilize the `SafeDITool` command-line executable directly in a pre-build script similar to the CocoaPods integration described above. - -You can see this integration in practice in the [ExampleMultiProjectIntegration](Examples/ExampleMultiProjectIntegration) package. - -`SafeDITool` is designed to integrate into projects of any size or shape. +`SafeDITool` is designed to integrate into projects of any size or shape. If your first-party code comprises multiple modules in Xcode, or a mix of Xcode Projects and Swift Packages, or some other configuration, once your Xcode project depends on the SafeDI package you will need to utilize the `SafeDITool` command-line executable directly in a pre-build script similar to the CocoaPods integration described above. `SafeDITool` can parse all of your Swift files at once, or for even better performance, the tool can be run on each dependent module as part of the build. Run `swift run SafeDITool --help` to see documentation of the tool’s supported arguments.