Swiftpack.co - GalenRhodes/Rubicon as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
GalenRhodes/Rubicon 0.8.0
A Swift library with tools, classes, and extensions to make life easier.
⭐️ 1
🕓 1 week ago
iOS macOS watchOS tvOS linux android wasi
.package(url: "https://github.com/GalenRhodes/Rubicon.git", from: "0.8.0")

RUBICON

Rubicon is a set of classes, structures, enums, extensions, tools, and utilities to make Swift development easier, cleaner, and less verbose.

API Documentation

Documentation of the API can be found here: Rubion API

Why the name Rubicon?

To cross the Rubicon is a metaphor which means to take an irrevocable step that commits one to a specific course. When Julius Caesar was about to cross the tiny Rubicon River in 49 B.C.E., he quoted from a play by Menander to say "anerriphtho kybos!" or "let the die be cast" in Greek.

Gill, N.S. "Meaning Behind the Phrase to Cross the Rubicon." ThoughtCo, Aug. 27, 2020, thoughtco.com/meaning-cross-the-rubicon-117548.

Swifty Stuff

Here's just a few of the places where I've taken advantage of Swift's features.

NSRecursiveLock -> RecursiveLock

Even though they've included a version of NSRecursiveLock in the open source version of Swift I still get nervous that one day all the NS* classes will suddenly disappear. So I created a wrapper around NSRecursiveLock called simply "RecursiveLock". That way if I suddenly have to recreate it at least I won't have to rename it.

Also as part of RecursiveLock I've create a method called:

func withLock<T>(_ lambda: () throws -> T) rethrows -> T

So that rather than the standard design pattern of:

do {
    lock.lock()
    defer { lock.unlock() }
    /* Do something here. */
}

We can now just do this:

lock.withLock {
    /* Do something here. */
}

It will even allow returned values and throws.

let val = try lock.withLock {
    try iReturnAValueOrThrowAnError()
}

NSCondition -> Conditional

For the same reasons as above I created a wrapper around NSCondition called simply "Conditional".

Also, along with the withLock(_:) method above, I've also included a new method called:

public func withLockWait<T>(broadcastBeforeWait: Bool = false, _ cond: () -> Bool, do block: () throws -> T) rethrows -> T

This method takes two enclosures. One to test the condition and the other to execute once the condition is met.

So instead of saying:

do {
    lock.lock()
    defer {
        lock.broadcast()
        lock.unlock()
    }
    while !someCondition() {
        lock.wait()
    }
    /* Do something here! */
}

You can now simply say this:

lock.withLockWait {
    someCondition()
} do: {
    /* Do something here! */
}

So much more clear!

If you need to call broadcast() before calling wait() then simply pass true to broadcastBeforeWait: like so:

lock.withLockWait(broadcastBeforeWait: true) {
    someCondition()
} do: {
    /* Do something here! */
}

That would be the same as:

do {
    lock.lock()
    defer {
        lock.broadcast()
        lock.unlock()
    }
    while !someCondition() {
        lock.broadcast()
        lock.wait()
    }
    /* Do something here! */
}

Also, the version of withLock(_:) in Conditional calls broadcast() right before it calls unlock().

GitHub

link
Stars: 1
Last commit: 4 days ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics