Safe and easy wrappers for RealmSwift

Overview

RealmWrapper

Cocoapods Carthage compatible Swift GitHub license Build Status

RealmWrapper is wrapper library for RealmSwift in realm-cocoa

If you use RealmWrapper, you can easily use UI update through Notification and Transaction processing. Also, you do not have to worry about the retain cycle when using self in the Notification block.

At a Glance

If you use RealmSwift, you have to be careful about try statement and thread processing every transaction. However, In RealmManageable which manages one realm file, transaction processing is performed using Realm-only DispatchQueue. RealmProxiable, which owns RealmManageable, can easily add, modify or delete models without having to worry about try statement and thread processing.

User Model

@objcMembers
class User: Object {
    dynamic var id: String?
    dynamic var name: String?

    override static func primaryKey() -> String? {
        return "id"
    }
}

var user = User()
user.id = UUID().uuidString
user.name = "Kevin"

Using RealmSwift

let realm = try! Realm(configuration: Realm.Configuration(fileURL: URL(fileURLWithPath: RLMRealmPathForFile("user.realm")), schemaVersion: 1, objectTypes: [User.self]))
try! realm.write {
    realm.add(user)
}

Using RealmWrapper

UserRealmManager().transaction(writeHandler: { (realm) in
    realm.add(user)
})
UserRealmProxy().append(user)

Threading

  • By default, you can use the transaction function to process a Realm Transaction in MainThread
UserRealmManager().transaction(writeHandler: { (realm) in
    realm.add(user)
})
  • It can be implemented by a background thread using DispatchQueue and isSync parameters.
UserRealmManager().transaction(isSync: false, writeHandler: { (realm) in
    realm.add(user)
})
UserRealmManager().transaction(writeQueue: DispatchQueue(label: "background"), isSync: false, writeHandler: { (realm) in
    realm.add(user)
})
  • You can add completion closure.
UserRealmManager().transaction(isSync: false, writeHandler: { (realm) in
    realm.add(user)
}) { (realm, error) in
    self.tableView.reloadData()
}

Getting Started

  1. Create a RealmManager that manages one realm file.
final class UserRealmManager: RealmManageable {

    var isUseInMemory: Bool {
        return false
    }
    var schemaVersion: UInt64 {
        return 1
    }
    var fileName: String {
        return "user"
    }
    var objectTypes: [Object.Type]? {
        return [User.self]
    }

}
  1. Create a RealmProxy that is responsible for the CRUD function to be accessed by the Controller.
struct UserRealmProxy<RealmManager: UserRealmManager>: RealmProxiable {

    var users: RealmQuery<User> {
        return query(sortProperty: "date", ordering: .ascending)
    }

    func append(_ user: User) {
        rm.transaction(writeHandler: { (realm) in
            realm.add(user, update: .all)
        })
    }

    func delete(_ user: User) {
        rm.transaction(writeHandler: { (realm) in
            realm.delete(user)
        })
    }

    func updateName(id: String, name: String, age: Int) {
        guard let user = userFromId(id) else {return}

        rm.transaction(writeHandler: { (realm) in
            user.name = name
            user.age = age
            realm.add(user, update: .all)
        })
    }

    func userFromId(_ id: String) -> User? {
        return query(filter: "id == '\(id)'").results.first
    }

}

var user = User()
user.id = UUID().uuidString
user.name = "Kevin"

UserRealmProxy().append(user)
UserRealmProxy().delete(user)
UserRealmProxy().updateName(id: user.id, name: "Kris")
  1. If you want to register the notification of the status of the Realm object in the controller, you can register the notification in RealmQuery.
let users: RealmQuery<User> = UserRealmProxy().users

users.setSection(0)
    .addInsertNotificationBlock(self) { (self, insertions) in
        self.tableView.reloadData()
    }
    .addModificateNotificationBlock(self) { (self, modifications) in
        self.tableView.reloadRows(at: modifications, with: .fade)
    }
    .addDeleteNotificationBlock(self) { (self, deletions) in
        self.tableView.deleteRows(at: deletions, with: .fade)
    }
    .registerNotification()

Also, since RealmQuery is doing weak handling to prevent the retain cycle, you can use closures without worrying about the retain cycle if you pass only self.

public func addDeleteNotificationBlock<Object: AnyObject>(_ object: Object, block: @escaping (Object, [IndexPath]) -> Void) -> Self {
    deleteNotificationBlock = { [weak object] (deletions) in
        guard let weakObject = object else {return}

        block(weakObject, deletions)
    }
    
    return self
}

Usage

RealmManageable Property

Property Type Default Description
isUseInMemory Bool required Use InMemory Realm
fileName Bool required Realm File Name
appGroupIdentifier String? nil Value for Realm file directory for App Extension

Example

  1. run carthage update
$ carthage update --platform iOS
  1. open RealmWrapper.xcodeproj
$ open RealmWrapper.xcodeproj
  1. run RealmWrapperExample

Installation

CocoaPods (iOS 9+)

platform :ios, '9.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'RealmWrapper'
end

Carthage (iOS 9+)

github "k-lpmg/RealmWrapper"

Swift Package Manager (Swift 5.2+, iOS 11+)

.package(url: "https://github.com/k-lpmg/RealmWrapper.git", .upToNextMajor(from: "1.4.4")),

LICENSE

These works are available under the MIT license. See the LICENSE file for more info.

Comments
  • Occurring UI lag while insertion process

    Occurring UI lag while insertion process

    Hi @k-lpmg!

    I'm trying to insert a batch of data (~10k, 15k). UI gets laggy while insertion process, and i'm using the different thread instead of main thread.

    Some details about getting lag of UI:

    Bad scroll experience of sliding table / collection view. UI is not freezing entirely. It's happening for a second, really short time but affects UI experience.

    You can see in below;

    ekran resmi 2019-02-20 02 42 12 ekran resmi 2019-02-20 02 39 25

    and last one;

    i'm calling that method like that;

    ekran resmi 2019-02-20 02 43 23 bug 
    opened by batuhansk 6
  • Completion block is firing in proper way.

    Completion block is firing in proper way.

    This commit allows the completion block to run after the transaction is finished. The current version of the lines are firing the completion block immediately.

    opened by batuhansk 4
  • Object property is unreachable in the realm result

    Object property is unreachable in the realm result

    Hi. I have some question about the realm result property, this is my first time to use realm

    struct UserRealmProxy<RealmManager: UserRealmManager>: RealmProxiable {
       func getUser(_ userId: Int) -> User? {
            let result: RealmQuery<User> = query(filter: "id == \(userId)", sortProperty: "id", ordering: .ascending)
            return result.results.first
        }
    }
        
    

    When my service code want to fetch user from realm, the result is not nil, but the property from this realm object is still unreachable(empty) in the view render process. it's so weird.

    opened by waltcow 4
  • There are three compiler warnings.

    There are three compiler warnings.

    Every waring happens in RealmManageable.swift and same warning.

    It says

    'public' modifier is redundant for instance method declared in a public extension

    It's not a big issue, but if fixed, appreciated.

    opened by MasaruKitajima 2
  • RealmSwift 3.17.1 has changed UpdatePolicy

    RealmSwift 3.17.1 has changed UpdatePolicy

    In the previous versions, realm.add(users, update: true) was right, but for the 3.17.1, we must choose options update from

    • error
    • modified
    • all

    So, it's like realm.add(users, update: .all) for an instance.

    Please refer further details at RealmSwift Doc

    opened by MasaruKitajima 2
  • Support for Realm 10

    Support for Realm 10

    firstly thanks for your great framework! Since Realm is now on version up to 10, I wanted to ask if you think about supporting the new 10 version?

    Thank you in advance

    opened by Yetispapa 2
Releases(1.4.3)
Owner
DongHee Kang
iOS Developer 
DongHee Kang
A protocol-centric, type and queue safe key-value workflow.

Light-weight, strict protocol-first styled PropertyKit helps you to easily and safely handle guaranteed values, keys or types on various situations of

gitmerge 12 Feb 26, 2021
SQLite.swift - A type-safe, Swift-language layer over SQLite3.

SQLite.swift provides compile-time confidence in SQL statement syntax and intent.

Stephen Celis 8.7k Jan 3, 2023
💾 Safe, statically-typed, store-agnostic key-value storage written in Swift!

Storez ?? Safe, statically-typed, store-agnostic key-value storage Highlights Fully Customizable: Customize the persistence store, the KeyType class,

Kitz 67 Aug 7, 2022
A type-safe, protocol-based, pure Swift database offering effortless persistence of any object

There are many libraries out there that aims to help developers easily create and use SQLite databases. Unfortunately developers still have to get bogged down in simple tasks such as writing table definitions and SQL queries. SwiftyDB automatically handles everything you don't want to spend your time doing.

Øyvind Grimnes 489 Sep 9, 2022
An elegant, fast, thread-safe, multipurpose key-value storage, compatible with all Apple platforms.

KeyValueStorage An elegant, fast, thread-safe, multipurpose key-value storage, compatible with all Apple platforms. Supported Platforms iOS macOS watc

null 3 Aug 21, 2022
Swift APIs for SQLite: Type-safe down to the schema. Very, very, fast. Dependency free.

Lighter Lighter is a set of technologies applying code generation to access SQLite3 databases from Swift, e.g. in iOS applications or on the server. L

Lighter.swift 330 Dec 26, 2022
Easy and beautiful way for a user to pick content, files or images. Written in Objective C

##JVTImageFilePicker Description ImageFilesPicker Is a butifuly designed UICompenent for uploading content Preview from recent camera roll Live Camera

Matan Abravanel 60 Jun 19, 2022
Realm GeoQueries made easy

RealmGeoQueries simplifies spatial queries with Realm Cocoa. In the absence of and official functions, this library provide the possibility to do prox

Marc Hervera 142 Jul 21, 2022
Easy direct access to your database 🎯

OHMySQL ★★ Every star is appreciated! ★★ The library supports Objective-C and Swift, iOS and macOS. You can connect to your remote MySQL database usin

Oleg 210 Dec 28, 2022
Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, configurations and app-state. UserDefaults

Prephirences - Preϕrences Prephirences is a Swift library that provides useful protocols and convenience methods to manage application preferences, co

Eric Marchand 557 Nov 22, 2022
Classes-and-structures-in-swift - This source files show what is the difference between class and structure

This source files show what is the difference between class and structure You ca

null 0 Jan 4, 2022
Elegant library to manage the interactions between view and model in Swift

An assistant to manage the interactions between view and model ModelAssistant is a mediator between the view and model. This framework is tailored to

Seyed Samad Gholamzadeh 28 Jan 29, 2022
Store and retrieve Codable objects to various persistence layers, in a couple lines of code!

tl;dr You love Swift's Codable protocol and use it everywhere, who doesn't! Here is an easy and very light way to store and retrieve Codable objects t

null 149 Dec 15, 2022
🛶Shallows is a generic abstraction layer over lightweight data storage and persistence.

Shallows Shallows is a generic abstraction layer over lightweight data storage and persistence. It provides a Storage<Key, Value> type, instances of w

Oleg Dreyman 620 Dec 3, 2022
Disk is a powerful and simple file management library built with Apple's iOS Data Storage Guidelines in mind

Disk is a powerful and simple file management library built with Apple's iOS Data Storage Guidelines in mind

Saoud Rizwan 3k Jan 3, 2023
KeyPathKit is a library that provides the standard functions to manipulate data along with a call-syntax that relies on typed keypaths to make the call sites as short and clean as possible.

KeyPathKit Context Swift 4 has introduced a new type called KeyPath, with allows to access the properties of an object with a very nice syntax. For in

Vincent Pradeilles 406 Dec 25, 2022
StorageManager - FileManager framework that handels Store, fetch, delete and update files in local storage

StorageManager - FileManager framework that handels Store, fetch, delete and update files in local storage. Requirements iOS 8.0+ / macOS 10.10+ / tvOS

Amr Salman 47 Nov 3, 2022
Listens to changes in a PostgreSQL Database and via websockets.

realtime-swift Listens to changes in a PostgreSQL Database and via websockets. A Swift client for Supabase Realtime server. Usage Creating a Socket co

Supabase 35 Dec 1, 2022
An Objective-C wrapper for RocksDB - A Persistent Key-Value Store for Flash and RAM Storage.

ObjectiveRocks ObjectiveRocks is an Objective-C wrapper of Facebook's RocksDB - A Persistent Key-Value Store for Flash and RAM Storage. Current RocksD

Iskandar Abudiab 56 Nov 5, 2022