资讯专栏INFORMATION COLUMN

SugarRecord For CoreData

ZweiZhao / 541人阅读

摘要:而且它支持各种编程范式你可以选择你所需要的如果你使用过的话会发现维护多个是一个挺麻烦的事情。给我们提供了插入和删除的操作,你可以直接的使用它。又致力于使用这个方法来对操作。如果谁知道的话告诉我,可能是我这里理解的不太对。

SugarRecord For CoreData

What is SugarRecord?

SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData/Realm/... in a much easier way. Thanks to SugarRecord you"ll be able to use CoreData with just a few lines of code: Just choose your stack and start playing with your data.

SugarRecord给我们简化了使用CoreData的步骤(同时他也可以用来操作Realm),可以让我们用更少的代码来使用CoreData,而且还提供了对iCloud的存储。

而且它支持各种编程范式, 你可以选择你所需要的

pod "SugarRecord/CoreData"
pod "SugarRecord/CoreData+iCloud"
pod "SugarRecord/CoreData+RX"
pod "SugarRecord/CoreData+RX+iCloud"
pod "SugarRecord/CoreData+RAC"
pod "SugarRecord/CoreData+RAC+iCloud"
pod "SugarRecord/Ream"
pod "SugarRecord/Realm+RX"
pod "SugarRecord/Realm+RAC"
Contexts

如果你使用过CoreData的话会发现维护多个NSManagedObjectContext 是一个挺麻烦的事情。SugarRecord给我们提供了三种Context

•    MainContext: Use it for main thread operations, for example fetches whose data will be presented in the UI.
这个用在主线成中的操作,例如我们获取到数据在UI上边显示

•    SaveContext: Use this context for background operations. The context is initialized when the storage instance is created. That context is used for storage operations.

这个用在后台线程中的操作

•    MemoryContext: Use this context when you want to do some tests and you don"t want your changes to be persisted.
Creating your Storage

A storage represents your database, Realm, or CoreData. The first step to start
using SugarRecord is initializing the storage. SugarRecord provides two default
storages, one for CoreData, CoreDataDefaultStorage and another one for Realm,
RealmDefaultStorage.

一个 storage 就代表着你的一个 database、realm 或者是 CoreData,首先第一步呢就是去使用SugarRecord 去初始化一个 storageSugarRecord提供了两种默认的方法,一个是创建一个CoreDataDefaultStorage 另一个是用来创建 RealmDefaultStorage

// Initializing CoreDataDefaultStorage
func coreDataStorage() -> CoreDataDefaultStorage {
    let store = CoreData.Store.Named("db")
    let bundle = NSBundle(forClass: self.classForCoder())
    let model = CoreData.ObjectModel.Merged([bundle])
    let defaultStorage = try! CoreDataDefaultStorage(store: store, model: model)
    return defaultStorage
}
Fetching data
let pedros: [Person] = try! db.fetch(Request().filteredWith("name", equalTo: "Pedro"))
let tasks: [Task] = try! db.fetch(Request())
let citiesByName: [City] = try! db.fetch(Request().sortedWith("name", ascending: true))
let predicate: NSPredicate = NSPredicate(format: "id == %@", "AAAA")
let john: User? = try! db.fetch(Request().filteredWith(predicate: predicate)).first

在这里呢我们的筛选条件可以使用NSPredicate这意味着,如果你是从CoreData转过来的话是很方便的。

当你执行db.fetch的时候SugarRecord就使用的是mainContext,你可以去查看fetch的对应实现

public class CoreDataDefaultStorage: Storage {
.....
}

// CoreDataDefaultStorage 继承了 Storage这个协议 
//Storage 协议对  fetch 有了默认的实现
//我们可以看到在默认的实现中 使用的是 mainContext
public extension Storage {

    func fetch(request: Request) throws -> [T] {
        return try self.mainContext.fetch(request)
    }
    
}
Request

Request 是一个结构体,他用来构成起获取数据时的约束。我们可以使用它的工厂方法来生成一个Request 来提供给Storagefetch使用

    // MARK: - Public Builder Methods
    
    public func filteredWith(predicate predicate: NSPredicate) -> Request {
        return self
            .request(withPredicate: predicate)
    }
    
    public func filteredWith(key: String, equalTo value: String) -> Request {
        return self
            .request(withPredicate: NSPredicate(format: "(key) == %@", value))
    }
    
    public func sortedWith(sortDescriptor sortDescriptor: NSSortDescriptor) -> Request {
        return self
            .request(withSortDescriptor: sortDescriptor)
    }
    
    public func sortedWith(key: String?, ascending: Bool, comparator cmptr: NSComparator) -> Request {
        return self
            .request(withSortDescriptor: NSSortDescriptor(key: key, ascending: ascending, comparator: cmptr))
    }
    
    public func sortedWith(key: String?, ascending: Bool) -> Request {
        return self
            .request(withSortDescriptor: NSSortDescriptor(key: key, ascending: ascending))
    }
    
    public func sortedWith(key: String?, ascending: Bool, selector: Selector) -> Request {
        return self
            .request(withSortDescriptor: NSSortDescriptor(key: key, ascending: ascending, selector: selector))
    }
Remove/Insert/Update operations

我们对数据库的最常用的操作无非就是增删查改了。

Although Contexts offer insertion and deletion methods that you can use it directly SugarRecords aims at using the operation method method provided by the storage for operations that imply modifications of the database models:

Contexts给我们提供了插入和删除的操作,你可以直接的使用它。SugarRecords 又致力于使用operation 这个方法来 对storage 操作。

•    Context: You can use it for fetching, inserting, deleting. Whatever you need to do with your data.

通过 context 你可以进行增删查改的操作

•    Save: All the changes you apply to that context are in a memory state unless you call the save() method. That method will persist the changes to your store and propagate them across all the available contexts.

你所有对context的改变都是在内存中的,直到你使用了 save() 这个方法之后才会吧它持久化。

do {
  db.operation { (context, save) throws -> Void in
    // Do your operations here
    save()
  }
}
catch {
  // There was an error in the operation
}

当我们在执行上边的方法的时候默认使用的就是saveContext,

    public func operation(operation: (context: Context, save: () -> Void) throws -> Void) throws {
        let context: NSManagedObjectContext = self.saveContext as! NSManagedObjectContext
        var _error: ErrorType!
        context.performBlockAndWait {
            do {
                try operation(context: context, save: { () -> Void  in
                    do {
                        try context.save()
                    }
                    catch {
                        _error = error
                    }
                    if self.rootSavingContext.hasChanges {
                        self.rootSavingContext.performBlockAndWait({
                            do {
                                try self.rootSavingContext.save()
                            }
                            catch {
                                _error = error
                            }
                        })
                    }
                })
            } catch {
                _error = error
            }
        }
        if let error = _error {
            throw error
        }
    }
Insert/Update

SugarRecord的事例中给了两种不同的例子

You can use the context new() method to initialize a model without inserting it in the context:
In order to insert the model into the context you use the insert() method.

do {
 db.operation { (context, save) throws -> Void in
   let newTask: Track = try! context.new()
   newTask.name = "Make CoreData easier!"
   try! context.insert(newTask)
   save()
 }
}
catch {
 // There was an error in the operation
}

You can use the create() for initializing and inserting in the context in the same operation:

do {
  db.operation { (context, save) throws -> Void in
    let newTask: Track = try! context.create()
    newTask.name = "Make CoreData easier!"
    save()
  }
}
catch {
  // There was an error in the operation
}

从字面上的理解来看的话,使用new()方法的话你需要调用 context.insert()这个方法去把你的Entity 插入到 cotext

create 的话,已经存在了context,去看create的实现的时候会发现,它调用了new()insert()

    public func create() throws -> T {
        let instance: T = try self.new()
        try self.insert(instance)
        return instance
    }

可是我测试了new() 不去执行 context.insert()方法,也能通过save() 去把它持久化了。所以不太理解这里的区别,现在这里挖个坑。如果谁知道的话告诉我,可能是我这里理解的不太对。

Delete a model

In a similar way you can use the remove() method from the context passing the objects you want to remove from the database:

更多的细节你可以去看这个文档。

SugarRecord 文档

这里给上我自己在使用时做的一个小例子Github地址

同时我还做了一个对Realm操作的demoGithub地址

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/16265.html

相关文章

  • QueryKit 和 DATAStack For CoreData

    摘要:和这两个库没有什么关系我们可以非常简单的初始化一个通过你的对的,你没有看错。以上基本上是给我们带来的便利性,可以很方便的维护一个拥有两个上下文的。好在帮我们处理好了这一切,起码我认为还是不错的处理方式。 其实我在segmentfault 上已经写过好几篇关于CoreData 的一些介绍了。大家好像一直都对 CoreData 没有什么好感,我一开始接触它呢仅仅是因为我什么都不懂,只知道有...

    gaara 评论0 收藏0
  • 使用SugarORM来操作SQLite

    摘要:版权声明本账号发布文章均来自公众号,承香墨影,版权归承香墨影所有。一前言之前在线上产品中,一直使用的下文简称,使用起来还是非常有好感的。使用标签标记类。为了考虑这方面的因素,同时也增加了一些查询的构造器,来避免使用语句进行操作。 版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。 允许有条件转载,转载请附带底部二维码。 一、前言 之前在线上产品...

    Render 评论0 收藏0
  • CoreData整理(二)——多线程方案

    摘要:如果多线程共用的话会出现数据混乱,甚至更严重的会导致程序崩溃。对于类型,之后过期,在实例化时并不会自动创建队列,需要自己管理多线程实现并发。方案二将使用三层的去实现多线程,。 CoreData整理(二)——多线程方案 目录 为何使用多线程 如何使用多线程 多线程方案 为何使用多线程     到了这里你一定会问,增删改查功能已经实现了,用的好好的为什么要使用多线程呢?其实想一想,...

    qc1iu 评论0 收藏0
  • CoreData整理(二)——多线程方案

    摘要:如果多线程共用的话会出现数据混乱,甚至更严重的会导致程序崩溃。对于类型,之后过期,在实例化时并不会自动创建队列,需要自己管理多线程实现并发。方案二将使用三层的去实现多线程,。 CoreData整理(二)——多线程方案 目录 为何使用多线程 如何使用多线程 多线程方案 为何使用多线程     到了这里你一定会问,增删改查功能已经实现了,用的好好的为什么要使用多线程呢?其实想一想,...

    inapt 评论0 收藏0
  • 认识CoreData - 初识CoreData

    摘要:由于项目比较大,还要兼顾之前项目的迭代和其他项目,目前为止只写完第一阶段。所以正如这系列文章的名字一样认识,打算写这系列文章来认识一下。文章中如有疏漏或错误,还请各位及时提出,谢谢 该文章属于原创,转载请注明: http://www.jianshu.com/p/c0e12a897971 `这段时间公司一直比较忙,和组里小伙伴一起把公司项目按照之前逻辑重写了一下。由于项目比较大,还要...

    _ivan 评论0 收藏0

发表评论

0条评论

阅读需要支付1元查看
<