Once(简体中文)
Once allows you to manage the number of executions of a task using an intuitive API.
- Safe
- Efficient
- Persistent
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:
static dispatch_once_t token;
dispatch_once(&token, ^{
// do something only once
});
The swift code using Token
is as follows:
let token = Token.makeStatic()
token.do {
// do something only once
}
Or, more simple:
Token.do {
// do something only once
}
You can also don't use static
:
class Manager {
let loadToken = Token.make()
func ensureLoad() {
loadToken.do {
// do something only once per manager.
}
}
}
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
represents a time range, it is an enum:
.install
: from app installation.version
: from app update.session
: from app launch.since(let since)
: fromsince(Date)
.until(let until)
: tountil(Date)
TimesPredicate
represents a range of times.
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)
You can use Scope
and TimesPredicate
to make any plan you want, and, yes, it is thread-safe.
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()
}
Sometimes your asynchronous task may fail. You don't want to mark the failed task as done. You can:
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, 😉.
You can also clear the execution history of a task:
token.reset()
It is also permissible to clear the execution history of all tasks, but at your own risk:
PersistentToken.resetAll()
pod 'Once', '~> 1.0.0'
github "luoxiu/Once" ~> 1.0.0
dependencies: [
.package(url: "https://github.com/luoxiu/Once", .upToNextMinor(from: "1.0.0"))
]
Encounter a bug? want more features? Feel free to open an issue or submit a pr directly!