SwinjectStoryboard 2.2.2

SwinjectStoryboard 2.2.2

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2021年9月
SPM支持 SPM

由以下人员维护:Jakub VanoMark DiFrancoTomas KohoutYoichi TagayaMaxim Chipeev



  • Swinject 贡献者编写

SwinjectStoryboard

Build Status Carthage compatible CocoaPods Version License Platform Swift Version Swift Package Manager compatible

SwinjectStoryboard 是 Swinject 的扩展,可以自动向由 storyboard 实例化的视图控制器注入依赖项。

需求

  • iOS 8.0+ / Mac OS X 10.10+ / tvOS 9.0+
  • Xcode 8+

安装

Swinject 可通过 CarthageCocoaPods 获得。

Carthage

要在 Carthage 中安装 Swinject,请将以下行添加到您的 Cartfile

github "Swinject/Swinject"
github "Swinject/SwinjectStoryboard"

然后运行 carthage update --no-use-binaries 命令或只是 carthage update。有关 Carthage 的安装和使用细节,请访问 其项目页面

MacPods

要使用MacPods安装Swinject,请将以下几行添加到您的Podfile文件中。

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0' # or platform :osx, '10.10' if your target is OS X.
use_frameworks!

pod 'Swinject'
pod 'SwinjectStoryboard'

然后运行pod install命令。有关MacPods的安装和使用详情,请访问其官方网站

Swift包管理器

要使用Apple的Swift包管理器集成,请在您的Package.swift文件中将以下内容添加为依赖项。

.package(url: "https://github.com/Swinject/SwinjectStoryboard.git", .upToNextMajor(from: "2.2.0"))

然后指定"SwinjectStoryboard"作为您希望使用SwinjectStoryboard的目标的依赖项。

使用方法

Swinject支持自动依赖注入,用于由SwinjectStoryboard实例化的视图控制器。此类继承自UIStoryboard(或OS X中的NSStoryboard)。为注册视图控制器的依赖项,请使用storyboardInitCompleted方法。就像注册服务类型一样,视图控制器可以带有或不带有名称进行注册。

注意:请不要显式解析由storyboardInitCompleted方法注册的视图控制器。视图控制器将隐式由SwinjectStoryboard解析。

注册

不带名称的注册

以下是一个注册视图控制器依赖项且不带注册名称的简单示例。

let container = Container()
container.storyboardInitCompleted(AnimalViewController.self) { r, c in
    c.animal = r.resolve(Animal.self)
}
container.register(Animal.self) { _ in Cat(name: "Mimi") }

接下来,我们创建一个指定容器的SwinjectStoryboard实例。如果没有指定容器,则使用SwinjectStoryboard.defaultContainerinstantiateViewControllerWithIdentifier方法会创建一个带有注入依赖项的视图控制器实例。

let sb = SwinjectStoryboard.create(
    name: "Animals", bundle: nil, container: container)
let controller = sb.instantiateViewControllerWithIdentifier("Animal")
    as! AnimalViewController
print(controller.animal! is Cat) // prints "true"
print(controller.animal!.name) // prints "Mimi"

类和协议所在的位置

class AnimalViewController: UIViewController {
    var animal: Animal?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

protocol Animal {
    var name: String { get set }
}

class Cat: Animal {
    var name: String

    init(name: String) {
        self.name = name
    }
}

同时,具有名称Animals.storyboard的故事板包含具有故事板ID AnimalAnimalViewController

AnimalViewController in Animals.storyboard

通过名称注册

如果故事板中存在多个相同类型的视图控制器,则应使用注册名称注册依赖项。

let container = Container()
container.storyboardInitCompleted(AnimalViewController.self, name: "cat") {
    r, c in c.animal = r.resolve(Animal.self, name: "mimi")
}
container.storyboardInitCompleted(AnimalViewController.self, name: "dog") {
    r, c in c.animal = r.resolve(Animal.self, name: "hachi")
}
container.register(Animal.self, name: "mimi") {
    _ in Cat(name: "Mimi")
}
container.register(Animal.self, name: "hachi") {
    _ in Dog(name: "Hachi")
}

然后,以类似不带注册名称的情况创建视图控制器实例。

let sb = SwinjectStoryboard.create(
    name: "Animals", bundle: nil, container: container)
let catController = sb.instantiateViewControllerWithIdentifier("Cat")
    as! AnimalViewController
let dogController = sb.instantiateViewControllerWithIdentifier("Dog")
    as! AnimalViewController
print(catController.animal!.name) // prints "Mimi"
print(dogController.animal!.name) // prints "Hachi"

Dog类所在的位置

class Dog: Animal {
    var name: String

    init(name: String) {
        self.name = name
    }
}

,同时,名为Animals.storyboard的故事板包含具有故事板ID CatDogAnimalViewController。除了故事板ID外,用户自定义的运行时属性也指定为键 swinjectRegistrationNamecatdog

AnimalViewControllers with user defined runtime attribute in Animals.storyboard

UIWindow和根视图控制器创建

从“主”故事板隐式创建

如果您隐式地从“Main”故事板创建UIWindow及其根视图控制器,请将setup类方法作为SwinjectStoryboard的扩展实现以向defaultContainer注册依赖项。当运行时实例化根视图控制器(初始视图控制器)时,将向注册到defaultContainer的依赖项注入。

注意,Swift 4中这里强制要求使用@objc属性。

extension SwinjectStoryboard {
    @objc class func setup() {
        defaultContainer.storyboardInitCompleted(AnimalViewController.self) { r, c in
            c.animal = r.resolve(Animal.self)
        }
        defaultContainer.register(Animal.self) { _ in Cat(name: "Mimi") }
    }
}

在AppDelegate中显式创建

如果您喜欢显式地创建UIWindow及其根视图控制器,请在application:didFinishLaunchingWithOptions:方法中使用具有容器的SwinjectStoryboard创建实例。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    var container: Container = {
        let container = Container()
        container.storyboardInitCompleted(AnimalViewController.self) { r, c in
            c.animal = r.resolve(Animal.self)
        }
        container.register(Animal.self) { _ in Cat(name: "Mimi") }
        return container
    }()

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

        let window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window.makeKeyAndVisible()
        self.window = window

        let storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil, container: container)
        window.rootViewController = storyboard.instantiateInitialViewController()

        return true
    }
}

请注意,您应该删除应用程序的Info.plist中的Main storyboard file base name项(或如果您正在显示原始键/值,则是UIMainStoryboardFile项)。

故事板参考

Xcode 7引人的故事板参考由SwinjectStoryboard支持。为了使在从引用的故事板创建实例时启用依赖注入,请将依赖注册到SwinjectStoryboard的静态属性defaultContainer

let container = SwinjectStoryboard.defaultContainer
container.storyboardInitCompleted(AnimalViewController.self) { r, c in
    c.animal = r.resolve(Animal.self)
}
container.register(Animal.self) { _ in Cat(name: "Mimi") }

如果你隐式实例化UIWindow及其根视图控制器,由于在setup方法中配置了defaultContainer,可以共享为“主”故事板设置注册。

面向维护者

创建新发布版本

我们的发布流程在Makefile中描述。运行make help命令以获取更多信息。

致谢

SwinjectStoryboard受到以下灵感的启发

许可

MIT许可。请参阅LICENSE文件以获取详细信息。