Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xtro/swiftusecase
SwiftUseCase is library for creating independent & test coverable use-cases with a powerful execution API.
https://github.com/xtro/swiftusecase
blocks combine concurrent-programming swift swift-packages unit-testing usecase
Last synced: 2 days ago
JSON representation
SwiftUseCase is library for creating independent & test coverable use-cases with a powerful execution API.
- Host: GitHub
- URL: https://github.com/xtro/swiftusecase
- Owner: xtro
- License: mit
- Created: 2022-12-25T09:25:46.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-02T06:10:23.000Z (5 months ago)
- Last Synced: 2025-01-30T23:41:13.559Z (3 days ago)
- Topics: blocks, combine, concurrent-programming, swift, swift-packages, unit-testing, usecase
- Language: Swift
- Homepage:
- Size: 137 KB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# SwiftUseCase
[![Swift](https://github.com/xtro/SwiftUseCase/actions/workflows/swift.yml/badge.svg?branch=main)](https://github.com/xtro/SwiftUseCase/actions/workflows/swift.yml) ![platforms](https://img.shields.io/badge/platform-iOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20macOS-333333) [![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) ![GitHub](https://img.shields.io/github/license/xtro/SwiftUseCase) ![Current version](https://img.shields.io/github/v/tag/xtro/SwiftUseCase)
**SwiftUseCase** is library for creating independent & test coverable usecases with a powerfull execution api.
## Installation
You can use Swift Package Manager to integrate the library by adding the following dependency in your Package.swift file or by adding directly within Xcode:```swift
.package(url: "https://github.com/xtro/SwiftUseCase.git", .upToNextMajor(from: "0.0.1"))
```## Definitions
A UseCase is a simple container that contains a ``Parameter`` and ``Result`` type and executing an ``Execution``.
```swift
public protocol UseCaseable {
associatedtype Parameter: Sendable
associatedtype Result: Sendable
associatedtype Execution: Sendable
var execute: Execution { get }
}
```There are four types of executions:
```swift
public typealias Executable = @Sendable (Parameter) -> Result
public typealias AsyncExecutable = @Sendable (Parameter) async -> Result
public typealias ThrowingExecutable = @Sendable (Parameter) throws -> Result
public typealias AsyncThrowingExecutable = @Sendable (Parameter) async throws -> Result
```![](./Documentation/SwiftUseCase.docc/Resources/usecase_map.png)
## Getting started
In this example we implement a data task using swift concurrency. The parameters are an URLRequest and an URLSession:
```swift
import SwiftUseCasepublic enum Network {
public struct DataTask: AsyncThrowingUseCase {
public struct Parameter {
let request: URLRequest
let session: URLSession
}
public typealias Result = (response: HTTPURLResponse, data: Data)
public var execute: AsyncThrowingExecutable = { parameter in
class CancellableWrapper {
var dataTask: URLSessionDataTask?
}
let urlSessionTask = CancellableWrapper()
return try await withTaskCancellationHandler {
return try await withUnsafeThrowingContinuation { continuation in
urlSessionTask.dataTask = parameter.session.dataTask(with: parameter.request) { data, response, error in
if let error = error {
continuation.resume(throwing: error)
}
if let data = data {
let result = (response as! HTTPURLResponse, data)
continuation.resume(returning: result)
}
}
urlSessionTask.dataTask?.resume()
}
} onCancel: {
urlSessionTask.dataTask?.cancel()
}
}
}
}
```After that we can use the implemented code in many ways.
Use as a combine publisher:
```swift
let usecase = Network.DataTask()
usecase.publisher(
.init(
request: URLRequest(url: URL(string: path)!),
session: session ?? .shared
)
)
```It looks nice, but the parameter and initialization is too complex in this case, we can reduce it by writing an extension like this:
```swift
extension Network.DataTask.Parameter {
static func get(_ path: String, session: URLSession? = nil) -> Self {
.init(
request: URLRequest(url: URL(string: path)!),
session: session ?? .shared
)
}
}
extension Network {
static var dataTask: DataTask {
DataTask()
}
}
```much better, now we can use as a Combine publisher:
```swift
Network.dataTask
.publisher( .get("https://api.coincap.io/v2/assets") )
...
```
or using blocks:
```swift
Network.dataTask( .get("https://api.coincap.io/v2/assets") ) { result in
...
}
```or in swift concurrency:
```swift
let result = try await Network.dataTask( .get("https://api.coincap.io/v2/assets") )
```finally every UseCase is convertable to ``AnyUseCase`` a type-erased representation of a usecase:
```swift
let usecase = MyUseCase().eraseToAnyUseCase
usecase.onComplete = {
print("Result: \($0)")
}
usecase.onFailure = {
print("Failure: \($0)")
}
usecase(parameter)
```## Sponsors
SwiftUseCase is an MIT-licensed open source project with its ongoing development made possible entirely by the support of awesome backers. If you'd like to join them, please consider sponsoring this development.## Contributing
Pull requests are welcome. For major changes, please open an issue first
to discuss what you would like to change.Please make sure to update tests as appropriate.
## License
This library is released under the [MIT](https://choosealicense.com/licenses/mit/) license. See LICENSE for details.