https://github.com/incetro/lagoon
The beautiful way to chain your services logic
https://github.com/incetro/lagoon
ios lagoon macos nsoperation nsoperationqueue operations swift
Last synced: 2 months ago
JSON representation
The beautiful way to chain your services logic
- Host: GitHub
- URL: https://github.com/incetro/lagoon
- Owner: Incetro
- License: mit
- Created: 2017-07-12T10:02:40.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2023-11-01T16:35:00.000Z (almost 2 years ago)
- Last Synced: 2025-07-04T22:49:00.853Z (3 months ago)
- Topics: ios, lagoon, macos, nsoperation, nsoperationqueue, operations, swift
- Language: Swift
- Homepage:
- Size: 290 KB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

[](https://travis-ci.org/incetro/Lagoon)
[](https://img.shields.io/cocoapods/v/Lagoon.svg)
[](https://github.com/Carthage/Carthage)
[](https://raw.githubusercontent.com/incetro/Lagoon/master/LICENSE.md)
[](https://cocoapods.org/pods/Lagoon)Lagoon is a framework written in Swift that makes it easy for you to organize your service layer
- [Features](#features)
- [Usage](#usage)
- [Requirements](#requirements)
- [Communication](#communication)
- [Installation](#installation)
- [Author](#author)
- [License](#license)## Features
- [x] Asynchronous operations
- [x] SOLID out of the box
- [x] Very simple writing unit tests
- [x] Reusable business logic
- [x] Generics## Usage
### Look at the simple example
Here we convert our string to number, increment and decrement it, multiply and divide by digits.
Let's create example operations:
```swift/// Convert String to Int
class ConvertOperation: ChainableOperationBase {
override func process(inputData: String, success: (Int) -> (), failure: (Error) -> ()) {
if let result = Int(inputData) {
success(result)
} else {
failure(NSError(domain: "com.incetro.Lagoon.Example", code: 1, userInfo: nil))
}
}
}/// Increment the given number
class IncrementOperation: ChainableOperationBase {
override func process(inputData: Int, success: (Int) -> (), failure: (Error) -> ()) {
success(inputData + 1)
}
}/// Decrement the given number
class DecrementOperation: ChainableOperationBase {
override func process(inputData: Int, success: (Int) -> (), failure: (Error) -> ()) {
success(inputData - 1)
}
}/// Multiply the given number
class MultiplicationOperation: ChainableOperationBase {
let mult: Int
init(with mult: Int) {
self.mult = mult
}
override func process(inputData: Int, success: (Int) -> (), failure: (Error) -> ()) {
success(inputData * self.mult)
}
}/// Make array of digits from the given number
class ArrayOperation: ChainableOperationBase {
override func process(inputData: Int, success: ([Int]) -> (), failure: (Error) -> ()) {
var result: [Int] = []
var number = inputData
while number > 0 {
result.append(number % 10)
number = number / 10
}
success(result.reversed())
}
}
```
And make chain ```convert -> increment -> decrement -> multiplication -> array```
```swift
let strings = ["123", "4", "56a", "a", ""]
for string in strings {
let convert = ConvertOperation()
let increment = IncrementOperation()
let decrement = DecrementOperation()
let mult = MultiplicationOperation(with: 125)
let array = ArrayOperation()
/// Create chain
let operations = [convert, increment, decrement, mult, array]
/// We expect Int array as output type
let compoundOperation = CompoundOperation.default(withOutputDataType: [Int].self)
/// Setup compound operation
compoundOperation.configure(withChainableOperations: operations, inputData: string, success: { result in
print(result)
}, failure: { error in
print(error.localizedDescription)
})
/// Start it!
Lagoon.add(operation: compoundOperation)
}
```
## Advanced usage
Okay, how can you use it in the real projects? Look at this.
```swift
// MARK: - RequestDataSigningOperation
class RequestDataSigningOperation: ChainableOperationBase {
private let requestSigner: RequestDataSigner
init(withRequestSigner requestSigner: RequestDataSigner) {
self.requestSigner = requestSigner
}
override func process(inputData: RequestDataModel, success: (RequestDataModel) -> (), failure: (Error) -> ()) {
let signedRequestDataModel = requestSigner.signRequestDataModel(inputData)
success(signedRequestDataModel)
}
}// MARK: - RequestConfigurationOperation
class RequestConfigurationOperation: ChainableOperationBase {
private let requestConfigurator: RequestConfigurator
private let method: HTTPMethod
private let serviceName: String?
private let urlParameters: [String]
private let queryType: QueryType
init(configurator: RequestConfigurator, method: HTTPMethod, type: QueryType, serviceName: String?, urlParameters: [String]) {
self.method = method
self.queryType = type
self.serviceName = serviceName
self.urlParameters = urlParameters
self.requestConfigurator = configurator
}
// MARK: - ChainableOperationBase
override func process(inputData: RequestDataModel, success: (URLRequest) -> (), failure: (Error) -> ()) {
let request = requestConfigurator.createRequest(withMethod: self.method,
type: self.queryType,
serviceName: self.serviceName,
urlParameters: self.urlParameters,
requestDataModel: inputData)
success(request)
}
}/// And other operations...
/// Then use it to make network chainlet operations = [
requestDataSigningOperation,
requestConfigurationOperation,
networkRequestOperation,
deserializationOperation,
validationOperation,
responseCachingOperation,
responseMappingOperation
]let compoundOperation = CompoundOperation.default(withOutputDataType: User.self)
compoundOperation.maxConcurrentOperationCount = 1
compoundOperation.configure(withChainableOperations: operations, inputData: inputData, success: success, failure: failure)
Lagoon.add(operation: compoundOperation)
```
## Requirements
- iOS 8.0+ / macOS 10.9+
- Xcode 8.1, 8.2, 8.3, and 9.0
- Swift 3.0, 3.1, 3.2, and 4.0## Communication
- If you **found a bug**, open an issue.
- If you **have a feature request**, open an issue.
- If you **want to contribute**, submit a pull request.## Installation
### CocoaPods
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
```bash
$ gem install cocoapods
```To integrate Lagoon into your Xcode project using CocoaPods, specify it in your `Podfile`:
```ruby
use_frameworks!target "" do
pod "Lagoon"
end
```Then, run the following command:
```bash
$ pod install
```### Manually
If you prefer not to use any dependency managers, you can integrate Lagoon into your project manually.
#### Embedded Framework
- Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:
```bash
$ git init
```- Add Lagoon as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following command:
```bash
$ git submodule add https://github.com/incetro/Lagoon.git
```- Open the new `Lagoon` folder, and drag the `Lagoon.xcodeproj` into the Project Navigator of your application's Xcode project.
> It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.
- Select the `Lagoon.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target.
- Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.
- In the tab bar at the top of that window, open the "General" panel.
- Click on the `+` button under the "Embedded Binaries" section.
- You will see two different `Lagoon.xcodeproj` folders each with two different versions of the `Lagoon.framework` nested inside a `Products` folder.> It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `Lagoon.framework`.
- Select the top `Lagoon.framework` for iOS and the bottom one for OS X.
> You can verify which one you selected by inspecting the build log for your project. The build target for `Lagoon` will be listed as either `Lagoon iOS`, `Lagoon macOS`.
- And that's it!
> The `Lagoon.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.
## Authorincetro, incetro@ya.ru. Inspired by [COOperation](https://github.com/strongself/COOperation)
## License
Lagoon is available under the MIT license. See the LICENSE file for more info.