Safe alternatives and similar libraries
Based on the "Events" category.
Alternatively, view Safe alternatives based on common mentions on social networks and blogs.
-
ReactiveCocoa
Cocoa framework and Obj-C dynamism bindings for ReactiveSwift. -
OpenCombine
Open source implementation of Apple's Combine framework for processing values over time. -
Katana
Swift Apps in a Swoosh! A modern framework for creating iOS apps, inspired by Redux. -
BrightFutures
Write great asynchronous code in Swift using futures and promises -
PMKVObserver
Modern thread-safe and type-safe key-value observing for Swift and Objective-C -
VueFlux
:recycle: Unidirectional State Management Architecture for Swift - Inspired by Vuex and Flux -
SignalKit
SignalKit is a reactive Swift framework with focus on clean and readable API. -
NoticeObserveKit
NoticeObserveKit is type-safe NotificationCenter wrapper. -
RxReduce
Reactive implementation of the state container pattern (like Redux). It is based on the simple concepts of state immutability and unidirectionnal data flow. -
LightweightObservable
📬 A lightweight implementation of an observable sequence that you can subscribe to. -
Aftermath
:crystal_ball: Stateless message-driven micro-framework in Swift. -
TopicEventBus
Publish–subscribe design pattern implementation framework, with an ability to publish events by topic. -
SSEventFlow
SSEventFlow is a type safe alternative to NotificationCenter, inspired by Flux -
Causality
A simple thread-safe, in-memory bus for Swift that supports fully-typed Events and States.
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Safe or a related project?
Popular Comparisons
README
Features
- Simple
Atomic<T>
class for numbers and strings. - Uncomplicated
dispatch
keyword for firing off background routines. - Awesome
Chan<T>
for concurrent communication. - Useful sync APIs.
Mutex
,Cond
,Once
,WaitGroup
Atomic
Types
Int
, Int8
, Int16
, Int32
, Int64
, UInt
, UInt8
, UInt16
, UInt32
, UInt64
, Float
, Double
, Bool
, String
Operators
==
, !=
, &&
, ||
, <=
, >=
, >
, <
, !
+
, -
, *
, /
, %
, <<
, >>
, ^
, &
, &+
, &-
, &*
, ++
, --
, +=
, -=
, *=
, /=
, %=
, +=
, <<=
, >>=
, ^=
, &=
var anum = IntA(100) // IntA is an alias for Atomic<Int>.
anum += 15 // Adds a value atomically.
let res = anum % 4 // Modulo operation atomically.
print("\(anum) \(res)") // prints '115 3'.
Dispatch
Safe adds an uncomplicated method for dispatching routines.
dispatch {
print("Background")
}
print("Foreground")
Channels
A new Chan<T>
class provides a clean and simple model for concurrently sharing objects. Chan<T>
is modeled after Go channels.
Sharing Memory by Communicating
Example
let jobs = Chan<Int>(5) // buffered channel
let done = Chan<Bool>() // unbuffered channel
dispatch {
for ;; {
if let j = <-jobs {
print("received job \(j)")
} else {
print("received all jobs")
done <- true
return
}
}
}
for var j = 1; j <= 3; j++ {
jobs <- j
print("sent job \(j)")
}
jobs.close()
print("sent all jobs")
<-done
Iterate
A channel can also be iterated through.
while let j = <-jobs {
print("received job \(j)")
}
print("received all jobs")
Select
The _select
keyword is a multiway communications multiplexer that works on multiple channels. _select
, _case
, and _default
start with underscores so that they do not conflict with the select
, case
, and default
syscall and keywords. When a _select
encounters multiple channels with data, the chosen _case
is selected at random
let jobs1 = Chan<Int>()
let jobs2 = Chan<Int>()
dispatch {
for ;; {
_select {
_case(jobs1){ j in
print("received 1: \(j)")
}
_case(jobs2){ j in
print("received 2: \(j)")
}
}
}
}
for var j = 1; ; j++ {
jobs1 <- (j * 1000)
jobs2 <- (j * 2000)
NSThread.sleepForTimeInterval(1)
}
Select with Default
A _select
can contain a single _default
for non-blocking operations.
_select {
_case(jobs1){ j in
print("received 1: \(j)")
}
_case(jobs2){ j in
print("received 2: \(j)")
}
_default {
print("channels not ready")
}
}
Mutex, Cond, Once, WaitGroup
Incredibly useful sync APIs.
Mutex
let m = Mutex()
m.lock()
m.unlock()
m.lock {
// this block is locked
}
Cond
let c = Cond(Mutex())
c.wait() // wait for signal.
c.wait(0.25) // wait for signal or 250ms to pass.
c.signal() // signal to one wait.
c.broadcast() // signal to all waits.
Once
func f(){
print("hey there")
}
let o = Once()
o.doit(f) // runs once
o.doit(f) // noop: cannot run twice
WaitGroup
let dosomething : (NSTimeInterval, WaitGroup)->() = { (delay, wg) in
NSThread.sleepForTimeInterval(delay)
print("Function in background, duration: \(delay)")
wg.done()
}
let wg = WaitGroup()
wg.add(1)
dispatch { dosomething(0.40, wg) }
wg.add(1)
dispatch { dosomething(0.30, wg) }
wg.add(1)
dispatch { dosomething(0.15, wg) }
wg.add(1)
dispatch { dosomething(0.60, wg) }
wg.wait()
print("done")
Installation (iOS and OS X)
Carthage
Add the following to your Cartfile:
github "tidwall/Safe"
Then run carthage update
.
Follow the current instructions in Carthage's README for up to date installation instructions.
The import Safe
directive is required in order to access Safe features.
CocoaPods
Add the following to your Podfile:
use_frameworks!
pod 'Safe'
Then run pod install
with CocoaPods 0.36 or newer.
The import Safe
directive is required in order to access Safe features.
SPM
Add the following to your Package.swift
dependencies: [
...
.Package(url: "https://github.com/tidwall/Safe", majorVersion: 1, minor: 2)
]
Then run swift build
.
The import Safe
directive is required in order to access Safe features.
Manually
Copy the Source/*.swift
file into your project.
There is no need for import Safe
when manually installing.
Contact
Josh Baker @tidwall
License
The Safe source code is available under the MIT License.
*Note that all licence references and agreements mentioned in the Safe README section above
are relevant to that project's source code only.