Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ladeiko/ViperServices

Simple dependency injection container for services written for iOS in swift supporting boot order
https://github.com/ladeiko/ViperServices

dependency-injection ios service-container swift

Last synced: 5 days ago
JSON representation

Simple dependency injection container for services written for iOS in swift supporting boot order

Awesome Lists containing this project

README

        

# ViperServices

[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg?colorA=28a745&colorB=4E4E4E)](https://img.shields.io/badge/Platform-iOS-lightgrey.svg?colorA=28a745&colorB=4E4E4E)
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/ViperServices.svg?style=flat&label=CocoaPods&colorA=28a745&&colorB=4E4E4E)](https://cocoapods.org/pods/ViperServices)
[![Swift support](https://img.shields.io/badge/Swift-4.0%20%7C%204.1%20%7C%204.2%20%7C%205.0-lightgrey.svg?colorA=28a745&colorB=4E4E4E)](#swift-versions-support)
[![Build Status](https://travis-ci.org/ladeiko/ViperServices.svg?branch=master)](https://travis-ci.org/ladeiko/ViperServices)

## Introduction
ViperServices is dependency injection container for iOS applications written in Swift.
It is more lightweight and simple in use than:

* [Kraken](https://github.com/sabirvirtuoso/Kraken)
* [Guise](https://github.com/prosumma/Guise)
* etc.

Also it introduces 'bootable' concept of service. Also services can define units they depends on.

## Changelog

See [CHANGELOG](CHANGELOG.md)

## Installation

### Cocoapods
> This is the recommended way of installing this package.

* Add the following line to your Podfile

``` ruby
pod 'ViperServices'
```
* Run the following command to fetch and build your dependencies

``` bash
pod install
```

### Manually
If you prefer to install this package manually, just follow these steps:

* Make sure your project is a git repository. If it isn't, just run this command from your project root folder:

``` bash
git init
```

* Add ViperServices as a git submodule by running the following command.

``` bash
git submodules add https://github.com/ladeiko/ViperServices.git
```
* Add files from *'submodules/ViperServices/Sources'* folder to your project.

## Usage

* Define your viper services:

``` swift
import ViperServices

protocol Service1: AnyObject {
func foo()
}

class Service1Impl: Service1, ViperService {

func setupDependencies(_ container: ViperServicesContainer) -> [AnyObject]? {
return [ // depends on
container.resolve() as Service2
]
}

func boot(launchOptions: [UIApplication.LaunchOptionsKey : Any]?, completion: @escaping ViperServiceBootCompletion) {
print("boot 1 called")
completion(.succeeded) // sync completion
}

func foo() {
print("foo 1 called")
}

}

protocol Service2: AnyObject {
func foo()
}

enum Service2Error: Error {
case SomeError
}

class Service2Impl: Service2, ViperService {

private weak var container: ViperServicesContainer!

func setupDependencies(_ container: ViperServicesContainer) -> [AnyObject]? {
self.container = container
return nil
}

func boot(launchOptions: [UIApplication.LaunchOptionsKey : Any]?, completion: @escaping ViperServiceBootCompletion) {
print("boot 2 called")
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { // async completion
switch arc4random() % 2 { // emulate random result
case 0:
completion(.failed(error: Service2Error.SomeError))
default:
completion(.succeeded)
}

}
}

func foo() {
print("foo 2 called")
}

}
```

* Add following code to application delegate:

``` swift
var window: UIWindow?

// use DefaultViperServicesContainer or implement your own container
let services = DefaultViperServicesContainer()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

try! services.register(Service1Impl() as Service1)
try! services.register(Service2Impl() as Service2)

services.boot(launchOptions: launchOptions) { (result) in
switch result {
case .succeeded:
// All ok, now it is safe to use any service!
(self.services.resolve() as Service1).foo()
(self.services.resolve() as Service2).foo()

case let .failed(failedServices):
// Boot failed, show error to user
let alert = UIAlertController(title: "Error",
message: failedServices.first!.error.localizedDescription,
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.window!.rootViewController?.present(alert, animated: false, completion: nil)
}
}

return true
}
```

## LICENSE
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details