/DITranquillity

Dependency injection for iOS (Swift)

Primary LanguageSwiftMIT LicenseMIT

Travis CI Carthage compatible CocoaPods Version License Platform Swift Version Dependency Status

DITranquillity

The small library for dependency injection in applications written on pure Swift for iOS/OSX/tvOS. Despite its size, it solves a large enough range of tasks, including Storyboard support. Its main advantage - modularity of support, detailed errors description and lots of opportunities.

Features

Tranquillity

  • Pure Swift Type Support
  • Initializer injections ru
  • Property, Method injections ru
  • Named, Tags definitions and Many ru
  • Type forwarding ru
  • Lifetimes: single, perRun(weak/strong), perContainer(weak/strong), objectGraph, prototype ru
  • iOS/macOS Storyboard and StoryboardReference ru
  • Circular dependencies ru
  • Three level hierarchy: types, part, framework ru
  • Short resolve syntax ru
  • keyPath injection (since swift4.0) ru
  • Delayed injection ru
  • Very detail logs ru
  • Validation at the run app ru
  • Injection into Subviews and cells ru
  • Scan Parts/Frameworks ru
  • Support Delayed injection ru
  • Thread safe

Usage

// container - for register and resolve your types
let container = DIContainer()

container.register{ Cat(name: "Felix") }
  .as(Animal.self) // register Cat with name felix by protocol Animal
  .lifetime(.prototype) // set lifetime

container.register(PetOwner.init) // register PetOwner

// you can validate you registrations graph
if !container.validate() {
  fatalError("...")
}

.................................................

// get instance of a types from the container
let owner: PetOwner = container.resolve()
let animal: Animal = *container // short syntax

print(owner.pet.name) // "Felix"
print(animal.name) // "Felix"

.................................................

// where
protocol Animal {
  var name: String { get }
}

class Cat: Animal {
  let name: String
  init(name: String) {
    self.name = name
  }
}

class PetOwner {
  let pet: Animal
  init(pet: Animal) {
    self.pet = pet
  }
}
See More
let container = DIContainer()

container.register{ Cat(name: "Felix") }
  .as(Animal.self)
  
container.register{ Dog(name: "Rex") }
  .as(Animal.self)
  .default()

container.register{ PetOwner(pets: many($0)) }
  .injection(\.home) // since swift4.0 and 3.2.0 lib

container.register(Home.init)
  .postInit{ $0.address = "City, Street, Number" }

.................................................

let owner: PetOwner = *container

print(owner.pets.map{ $0.name }) // ["Felix", "Rex"]
print(onwer.home.address) // "City, Street, Number"

.................................................

// where
protocol Animal {
  var name: String { get }
}

class Cat: Animal {
  let name: String
  init(name: String) {
    self.name = name
  }
}

class Dog: Animal {
  let name: String
  init(name: String) {
    self.name = name
  }
}

class PetOwner {
  let pets: [Animal]
  init(pets: [Animal]) {
    self.pets = pets
  }
  
  private(set) var home: Home!
}

class Home {
  var address: String!
}

Storyboard (iOS/OS X)

See code

Create your ViewController:

class ViewController: UIViewController/NSViewController {
  private(set) var inject: Inject?

  override func viewDidLoad() {
    super.viewDidLoad()
    print("Inject: \(inject)")
  }
}

Create container:

let container = DIContainer()
container.register(ViewController.self)
  .injection(\.inject)

Create Storyboard:

/// for iOS
func applicationDidFinishLaunching(_ application: UIApplication) {
  let storyboard = DIStoryboard.create(name: "Main", bundle: nil, container: container)

  window = UIWindow(frame: UIScreen.main.bounds)
  window!.rootViewController = storyboard.instantiateInitialViewController()
  window!.makeKeyAndVisible()
}
/// for OS X
func applicationDidFinishLaunching(_ aNotification: Notification) {
  let storyboard = DIStoryboard.create(name: "Main", bundle: nil, container: container)

  let viewController = storyboard.instantiateInitialController() as! NSViewController
  let window = NSApplication.shared.windows.first
  window?.contentViewController = viewController
}

For more details

Install

Via CocoaPods.

To install DITranquillity with CocoaPods, add the following lines to your Podfile: pod 'DITranquillity'

Via Carthage.

github "ivlevAstef/DITranquillity" Swift (iOS8+,macOS10.10+,tvOS9+)

Requirements

iOS 8.0+,macOS 10.10+,tvOS 9.0+; ARC

  • Swift 4.1: Xcode 9.3; version >= 3.2.3
  • Swift 4.0: Xcode 9.0; version >= 3.0.5
  • Swift 3.0-3.2: Xcode 8.0-9.0; version >= 0.9.5
  • Swift 2.3: Xcode 7.0; version < 0.9.5

Migration

  • v1.x.x -> v2.x.x ru
  • v2.x.x -> v3.x.x ru

Changelog

See CHANGELOG.md file.

Alternative

Feedback

I've found a bug, or have a feature request

Please raise a GitHub issue.

I've found a defect in documentation, or thought up how to improve it

Please help library development and create pull requests

Question?

You can feel free to ask the question at e-mail: ivlev.stef@gmail.com.