GVKun编程网logo

Swift CoreData 使用(swiftui coredata)

1

对于SwiftCoreData使用感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解swiftuicoredata,并且为您提供关于CloudKit在连接到蜂窝网络时不会自动同步CoreDat

对于Swift CoreData 使用感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解swiftui coredata,并且为您提供关于CloudKit 在连接到蜂窝网络时不会自动同步 CoreData、cocoa touch layer下面的几个点连载之--CoreData、CoreData Model、CoreData Model 之 NSEntityDescription和NSManagedObject的宝贵知识。

本文目录一览:

Swift CoreData 使用(swiftui coredata)

Swift CoreData 使用(swiftui coredata)

使用 CoreData

1. 新建项目时选用 core data

或者在后来添加 .xcdatamodeld 文件

2. 在 AppDelegate 中 获取 persistentContainer

  1. 声明一个 lazy 变量 persistentContainer
  2. 把模型名字传递给初始化的方法
  3. 如果存在 store 返回 store
class AppDelegate: UIResponder, UIApplicationDelegate {
    ...
    lazy var persistentContainer: NSPersistentContainer = {        
        let container = NSPersistentContainer(name: "DataModel")
        container.loadPersistentStores { description, error in
            if let error = error {
                fatalError("Unable to load persistent stores: \(error)")
            }
        }
        return container
    }()
    ...
}

获取到 persistentContainer 之后,在这个 persistentContainer 中包含着:

  • model: managedObjectModel
  • context: viewContext
  • store codrdinator: persistentStoreCoordinator

3. 给 ViewController 传递 persistentContainer

1. 在 VC 中添加一个变量 container

class ViewController: UIViewController {

    var container: NSPersistentContainer!

        override func viewDidLoad() {
        super.viewDidLoad()
        guard container != nil else {
            fatalError("This view needs a persistent container.")
        }
        // The persistent container is available.
    }
}

2. 在 AppDelegate 中传递这个变量

AppDelegate 中,给应用的 rootViewController 传递

class AppDelegate: UIResponder, UIApplicationDelegate {

    ...

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        
        if let rootVC = window?.rootViewController as? ViewController {
            rootVC.container = persistentContainer
        }        
        return true
    }

    ...
}

如果想在其它 VC 中使用 container,重复上面的步骤,在目标 VC 中添加接收变量,在前一个 VC 中通过 prepare(for:sender:) 传递这个变量

class ViewController: UIViewController {

    ...

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let nextVC = segue.destination as? NextViewController {
            nextVC.container = container
        }
    }
}

或者直接在 AppDelegate 中添加两个变量 :

 static var persistentContainer: NSPersistentContainer{
        return (UIApplication.shared.delegate as! AppDelegate).persistentContainer
    }
static var viewContext: NSManagedObjectContext{
    return persistentContainer.viewContext

4. 添加数据

添加 5 张卡片

for index in 1...5 {
    let newCard = Card(context: context)
    newCard.id = Int16(index)
    newCard.idNumber = Date().timeIntervalSince1970.toString()
    newCard.name = "card-\(index)"
    newCard.type = String(CardTypes.BankCard)
    newCard.dateInit = Date()
    do {
        try context.save()
    } catch {
        print("-----save Cards CoreData error")
    }
}

5. 查询数据

var cards: Array<Card> = []

DispatchQueue.main.async { [unowned self] in
    do {
        try self.cards =  self.context.fetch(Card.fetchRequest())
    } catch {
        print("Feth Card Data fail")
    }
    self.tableView.reloadData()
}

6. 修改数据

修改数据需要先获取到你查询到的数据,查询到的每个数据都是跟 context 有关联的。
如你像下面这样修改了你查询出来的某个元素,这个元素的
hasChanges 属性就会返回 true, 此时只需要 context.save()一下即可保存

card.name = "new Name"

if currentCard.hasChanges {
    do {
        try context.save()
    } catch {
        print("CoreData: save object error")
    }
}

7. 很多错误的解决办法

很多时候在大改 CoreData 模型之后,往往会编译出各种奇怪的错误,这时候,只需要把数据结构截图,删除重新建一份即可解决

CloudKit 在连接到蜂窝网络时不会自动同步 CoreData

CloudKit 在连接到蜂窝网络时不会自动同步 CoreData

如何解决CloudKit 在连接到蜂窝网络时不会自动同步 CoreData?

我正在开发一个使用 Core Data 进行持久存储的项目,我现在正在使用 CloudKit 在不同设备之间同步用户的应用程序数据。 我已使用 https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/setting_up_core_data_with_cloudkit 帮助我进行设置。

我首先使用连接到(相同)Wifi 网络的 2 台设备对此进行了测试,并且运行良好。在两台设备上打开该应用程序并在 1 个应用程序上进行更改,稍后会看到它出现在另一台设备上。非常好,很惊讶能这么好用这么少的努力。

但是...然后我在 1 台设备上禁用了 WiFi,以便它连接到蜂窝网络,然后问题就开始了。好的实时同步不再起作用了! “强制”查看正在传播到另一台设备的更改的唯一方法是将应用程序移至后台并再次移至前台。 (我假设这会强制从 iCloud 获取数据。)

我检查过的东西:

  • 我已启用(静默)远程通知。基本上做了上面链接中提到的所有事情。
  • 我检查了我的移动数据设置中是否启用了 iCloud Drive。很明显,因为当应用程序进入前台时,会获取 (iCloud) 数据。

我的问题是,这是预期的行为吗? CloudKit 是否应该在蜂窝网络上以不同的方式工作? 在上面链接中提到的 Apple 网页上,根本没有提到不同网络上的不同行为。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

cocoa touch layer下面的几个点连载之--CoreData

cocoa touch layer下面的几个点连载之--CoreData

并非严格的说, CoreData是对sqlite数据库的一个封装. sqlite数据库操作的基本流程是,创建数据库,再通过定义一些字段来定义表格结构,可以利用sql语句向表格中插入记录,删除记录,修改记录,表格之间也可以建立联系. 这个过程出现了,表格的结构(schema),所有表格的结构和相互联系构成整个数据库的模型,数据库存放的方式(可以是文件或者在内存),数据库操作,sql语句(主要是查询),表格里面的记录 下面将上面说的文字,跟CoreData的类作个对应: 表格结构    --> NSEntityDescription 数据库中所有表格和他们的联系 -->NSManagedobjectModel 数据库存放方式 --> NSPersistentStoreCoordinator 数据库操作 --> NSManagedobjectContext 查询语句 --> NSFetchRequest 表格的记录 --> NSManagedobject 可能上面的对应关系并非十分严格,但确实可以帮助理解. 下面再看看CoreData的类 NSEntityDescription NSManagedobjectModel NSEntityDescription用来定义表格结构,所以你就可以理解NSManagedobjectModel中的setEntities:(NSArray *)entities函数大概有什么用了 . 通常,定义model,是用文件CoreData.xcdatamodel,可以图形化的操作. 这类似用nib来创建界面.  建个工程,使用coredata,模拟器运行之后,程序对应的document目录出现一个CoreData.sqlite. 可以利用sqlite3命令来查看里面的表格结构 用命令行sqlite3 CoreData.sqlite 进入 >.tables ZEVENT        Z_MetaDATA    Z_PRIMARYKEY 可以看到有表格ZEVENT,对应的CoreData.xcdatamodel文件有名字叫Event的Entity >.schema ZEVENT CREATE TABLE ZEVENT ( Z_PK INTEGER PRIMARY KEY,Z_ENT INTEGER,Z_OPT INTEGER,ZTIMESTAMP TIMESTAMP ); 对应的Event中有属性timeStamp,可以看到,相应的ZEVENT表格中有字段TIMESTAMP > select * from ZEVENT 1|1|1|306295807.974966 2|1|1|306295810.981875 3|1|1|306295811.982537 这表格有三个记录,可以用来初始化三个NSManagedobject,修改了NSManagedobject,save之后也修改了表格记录 你可以在CoreData.xcdatamodel添加新的entity,之后用sqlit3命令来查看数据库的变化 NSPersistentStoreCoordinator 这个类的对象通常用NSManagedobjectModel的对象来初始化,这个类抽象出不同的存放方式,最经常用的是NSsqliteStoreType.  NSManagedobjectContext 这个类的对象又用NSPersistentStoreCoordinator的对象来初始化,它里面有些方法来添加,删除NSManagedobject NSFetchRequest 通常用NSEntityDescription来构造查询,也就指定查询那个表格,另外可以指定排序. 在CoreData的设计中,下一层有相应的属性指向上一层,所以NSManagedobject有属性得到NSEntityDescription,NSEntityDescription有属性得到NSManagedobjectModel. 至于类 NSFetchedResultsController,只是又封了一下,和NSFetchRequest合起来使用,方便取数据,另外和NSManagedobjectContext关联,当数据库发生变化的时候收到通知. 这文章只初步梳理了一下CoreData各类的关系,各类的方法还需要一一研究. 文章最开始说CoreData是对sqlite数据库的一个封装,不是严格的, CoreData不一定用sqlit来实现,但他们之间确实有种对应关系.

CoreData Model

CoreData Model

1.NSEntityDescription和NSManagedobject

在CoreData中Model定义了数据存储的schema,包含一组data models,每一个data model对应一个NSEntityDescription对象,NSEntityDescription对象包含了Entity所拥有的属性,关系等信息,我们可以通过NSEntityDescription生成相应的NSManagedobject的实体,

 

这个时候newObject便是一个类型为ModelName的实体对象了。我们可以给对象通过kvc的接口添加属性值。
当然我们也可以写NSManagedobject的子类,然后声明属性,再通过@dynamic指令使得我们可以通过点运算符来设置属性值。

 

2.KVC

 

KVC即Key Value Coding的缩写,如果你使用过其他语言,你应该对Key-Value的结构比较了解的,如Java中的HashMap,python中的Dictionary,js中的json,这些内容都涉及到kv的知识。
在Objc里,NSkeyvalueCoding协议定义了kvc的相关内容,这个包含在NSkeyvalueCoding.h头文件中,NSObject实现了此协议。那KVC到底是什么样的呢?
我们都知道我们定义一个类,类有属性,然后我们可以通过accessor来获取属性或者设置属性的值,
比如一个老式的属性获取和设值方式:

 

当我们使用kvc的方式的话,可以写成:

 

所以说从某种意义上说,kvc使得每一个对象都可以看成一个dictionary对象。当通过kvc方式设置属性值的时候,会发送值被修改的通知,我们可以在别的地方捕获到这个通知,以便别的地方做相应的更新。Cocoa中的Binding便是这个原理,不过Cocoa中的很多控件通过绑定帮你省去了很多胶水代码。Binding在MVC的程序中显得尤为有用,M到V之间的绑定,并通过C来控制协调。

CoreData Model 之 NSEntityDescription和NSManagedObject

CoreData Model 之 NSEntityDescription和NSManagedObject

1.NSEntityDescription和NSManagedobject

在CoreData中Model定义了数据存储的schema,包含一组data models,每一个data model对应一个NSEntityDescription对象,NSEntityDescription对象包含了Entity所拥有的属性,关系等信息,我们可以通过NSEntityDescription生成相应的NSManagedobject的实体,

[c-sharp] view plain copy
  • NSManagedobject *newObject=[NSEntityDescription   
  •                insertNewObjectForEntityForName:@"ModelName"   
  •                     inManagedobjectContext:[self managedobjectContext]];  
  •  

    这个时候newObject便是一个类型为ModelName的实体对象了。我们可以给对象通过kvc的接口添加属性值。
    当然我们也可以写NSManagedobject的子类,然后声明属性,再通过@dynamic指令使得我们可以通过点运算符来设置属性值。

     

    2.KVC

     

    KVC即Key Value Coding的缩写,如果你使用过其他语言,你应该对Key-Value的结构比较了解的,如Java中的HashMap,python中的Dictionary,js中的json,这些内容都涉及到kv的知识。
    在Objc里,NSkeyvalueCoding协议定义了kvc的相关内容,这个包含在NSkeyvalueCoding.h头文件中,NSObject实现了此协议。那KVC到底是什么样的呢?
    我们都知道我们定义一个类,类有属性,然后我们可以通过accessor来获取属性或者设置属性的值,
    比如一个老式的属性获取和设值方式:

    [c-sharp] view plain copy
  • [person name]  
  • [person setName:@"Luke"]  
  •  

    当我们使用kvc的方式的话,可以写成:

    [c-sharp] view plain copy
  • [person valueForKey:@"name"]  
  • [person setValue:@"Luke"  
  • forKey:@"name"]  
  •  

    所以说从某种意义上说,kvc使得每一个对象都可以看成一个dictionary对象。 当通过kvc方式设置属性值的时候,会发送值被修改的通知,我们可以在别的地方捕获到这个通知,以便别的地方做相应的更新。Cocoa中的Binding便是这个原理,不过Cocoa中的很多控件通过绑定帮你省去了很多胶水代码。 Binding在MVC的程序中显得尤为有用,M到V之间的绑定,并通过C来控制协调。

    今天的关于Swift CoreData 使用swiftui coredata的分享已经结束,谢谢您的关注,如果想了解更多关于CloudKit 在连接到蜂窝网络时不会自动同步 CoreData、cocoa touch layer下面的几个点连载之--CoreData、CoreData Model、CoreData Model 之 NSEntityDescription和NSManagedObject的相关知识,请在本站进行查询。

    本文标签: