Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/luoxiu/Once

Minimalist library to manage one-off operations.
https://github.com/luoxiu/Once

once one-off swift

Last synced: 3 months ago
JSON representation

Minimalist library to manage one-off operations.

Awesome Lists containing this project

README

        

# Once([简体中文](README.zh_cn.md))

[![Build Status](https://travis-ci.org/luoxiu/Once.svg?branch=master)](https://travis-ci.org/luoxiu/Once)
![release](https://img.shields.io/github/v/release/luoxiu/Once?include_prereleases)
![install](https://img.shields.io/badge/install-spm%20%7C%20cocoapods%20%7C%20carthage-ff69b4)
![platform](https://img.shields.io/badge/platform-ios%20%7C%20macos%20%7C%20watchos%20%7C%20tvos%20%7C%20linux-lightgrey)
![license](https://img.shields.io/github/license/luoxiu/combinex?color=black)

Once allows you to manage the number of executions of a task using an intuitive API.

## Highlight

- [x] Safe
- [x] Efficient
- [x] Persistent

## Usage

### Token

`Token` records the number of times the task is executed in memory, which allows the task to be executed only once during the entire lifetime of the app.

You can think of it as an alternative to `dispatch_once` in OC:

```objectivec
static dispatch_once_t token;
dispatch_once(&token, ^{
// do something only once
});
```

The swift code using `Token` is as follows:

```swift
let token = Token.makeStatic()
token.do {
// do something only once
}
```

Or, more simple:

```swift
Token.do {
// do something only once
}
```

You can also don't use `static`:

```swift
class Manager {
let loadToken = Token.make()

func ensureLoad() {
loadToken.do {
// do something only once per manager.
}
}
}
```

#### PersistentToken

Unlike `run`, `do` will persist the execution history of the task (using `UserDefault`).

`PersistentToken` determines whether this task should be executed based on `Scope` and `TimesPredicate`.

#### Scope

`Scope` represents a time range, it is an enum:

- `.install`: from app installation
- `.version`: from app update
- `.session`: from app launch
- `.since(let since)`: from `since(Date)`
- `.until(let until)`: to `until(Date)`

#### TimesPredicate

`TimesPredicate` represents a range of times.

```swift
let p0 = TimesPredicate.equalTo(1)
let p1 = TimesPredicate.lessThan(1)
let p2 = TimesPredicate.moreThan(1)
let p3 = TimesPredicate.lessThanOrEqualTo(1)
let p4 = TimesPredicate.moreThanOrEqualTo(1)
```

#### do

You can use `Scope` and `TimesPredicate` to make any plan you want, and, yes, it is thread-safe.

```swift
let token = PersistentToken.make("showTutorial")
token.do(in: .version, if: .equalTo(0)) {
app.showTutorial()
}

// or
let later = 2.days.later
token.do(in: .until(later), if: .lessThan(5)) {
app.showTutorial()
}
```

#### done

Sometimes your asynchronous task may fail. You don't want to mark the failed task as done. You can:

```swift
let token = PersistentToken.make("showAD")
token.do(in: .install, if: .equalTo(0)) { task in
networkService.fetchAD { result in
if result.isSuccess {
showAD(result)
task.done()
}
}
}
```

But at this time, the judgment is no longer absolutely safe - if there are multiple threads checking the token at the same time, but it should rarely happen, 😉.

#### reset

You can also clear the execution history of a task:

```swift
token.reset()
```

It is also permissible to clear the execution history of all tasks, but at your own risk:

```swift
PersistentToken.resetAll()
```

## Installation

### CocoaPods

```ruby
pod 'Once', '~> 1.0.0'
```

### Carthage

```ruby
github "luoxiu/Once" ~> 1.0.0
```

### Swift Package Manager

```swift
dependencies: [
.package(url: "https://github.com/luoxiu/Once", .upToNextMinor(from: "1.0.0"))
]
```

## Contributing

Encounter a bug? want more features? Feel free to open an issue or submit a pr directly!