Latest 0.65
License MIT
Platforms ios 10.0

CI Status


This should be a lightweight set of swift language patters to make development easy and make powerful constructs without bloated abstractions.

  • No singletons
  • No resources
  • Work in progress

Mutable protocol

There is a protocol for mutating objects with default implementation, so you can extend any object.
Useful for fetch requests, operationqueue init…

let queue = OperationQueue().mutate { $0.maxConcurrentOperationCount = 1 }


There is a simple Debug.execute {...} method.

NSPredicate logical operators for building complex predicates


let predicate1 = !predicate2 || predicate3

PredicateKey with arithmetic operators for building NSPredicate

This is a simple aproach to make operators on the predicate keys that give NSPredicate as a result, and then you can mix predicates using predicate operators.
You can use both swift3 and swift4 Key Paths, but swift4 works only for @objc exposed properties because it is using _kvcKeyPathString property to get keypath string.
For core data objects swift4 works perfectly. Operator === is used for IN predicate and collection of values.

//swift3 keypaths:
let predicate1 = PredicateKey(#keyPath(TestEntity.value)) < 3
let predicate2 = PredicateKey(#keyPath( == "Zola"

//swift4 keypaths:
let predicate3 = TestEntity.value >= 4
let predicate4 = != "Sisoje"
let predicate5 = TestEntity.value === [3,4,5]

Deinitialisation management

Similar like defer but on instance level. You can make DeinitManager instance as a property and no need to implement deinit for that instance.
Can be used for anything that requires resource releasing, for example observer removal from the notification center.

var i = 0
if i == 0 {
  let m = DeinitManager()
  m.add { i += 1 }
  XCTAssert(i == 0)
XCTAssert(i == 1)

BlockOperation blocks

Added operation as a parameter for execution block
Useful for long running code to check cancellation

let operation = BlockOperation().withExecutionBlockInside {
  while !$0.isCancelled {...}

Managed context perform blocks

All core data related stuff is done in blocks of type (NSManagedObjectContext) -> Void
For this to work performAndWait is modified so it accepts blocks with context.

//create entity
persistentContainer?.newBackgroundContext().performAndWaitInside { context in
  let _ = TestEntity(context: context)

And wraped up for usage in operation queue:

//delete items in background
operationQueue.addCoreDataOperation(persistentContainer) { context in
  try! context.fetch(TestEntity.fetchRequest()).forEach { context.delete($0) }

Notification center adding & removing

Adding observer will return a closure for releasing observer, and not the observer itself. One can keep that closure as deiniter.
Example shows how to remove observer inside the block, so observing happens only once:

var removeObserver: (() -> Void)?
removeObserver = NotificationCenter.default.addRemovableObserver(.UIApplicationWillEnterForeground) { _ in
  removeObserver = nil

Application settings with return block

This is removable observer wrapped up for opening settings, where return block is called at most once:

UIApplication.shared.openSettings {
  printf("back from settings, something maybe changed")


Swift 4.0
iOS 10.0 (iOS 8.0 Foundation only)


RHBKit is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod "RHBKit"


Lazar Otasevic, [email protected]


RHBKit is available under the MIT license. See the LICENSE file for more info.

Latest podspec

    "name": "RHBKit",
    "version": "0.65",
    "summary": "Closures & predicates operators. Object Mutations. Deinit manager. Cancellable operations. Debug. CoreData extensions. Removable obsevrvers.",
    "description": "Swift patterns for Foundation and CoreData. Cancellable BlockOperation. Smart obsevrvers. Operators for closures, predicates and more... Goal was to reduce overabstractions and keep it low level.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Lazar Otasevic": "[email protected]"
    "source": {
        "git": "",
        "tag": "0.65"
    "social_media_url": "",
    "platforms": {
        "ios": "10.0"
    "pod_target_xcconfig": {
        "SWIFT_VERSION": "4.0"
    "pushed_with_swift_version": "4.0",
    "subspecs": [
            "name": "Foundation",
            "source_files": "Sources/Foundation/**/*",
            "frameworks": "Foundation",
            "platforms": {
                "ios": "8.0"
            "name": "CoreData",
            "source_files": "Sources/CoreData/**/*",
            "frameworks": "CoreData",
            "dependencies": {
                "RHBKit/Foundation": []
            "platforms": {
                "ios": "10.0"
            "name": "UIKit",
            "source_files": "Sources/UIKit/**/*",
            "frameworks": "UIKit",
            "dependencies": {
                "RHBKit/Foundation": []
            "platforms": {
                "ios": "10.0"

Pin It on Pinterest

Share This