前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Core Data with CloudKit(三)——CloudKit仪表台

Core Data with CloudKit(三)——CloudKit仪表台

作者头像
东坡肘子
发布2022-07-28 12:50:04
7060
发布2022-07-28 12:50:04
举报

Core Data with CloudKit(三)——CloudKit仪表台

本系列文章一共六篇,如果想获得更好的阅读体验可以访问我的博客 www.fatbobman.com[1]

本篇文章中,我们将一起研究CloudKit仪表台。

初识仪表台

使用CloudKit Dashboard需要开发者拥有Apple Developer Program[2]账号,访问https://icloud.developer.apple.com即可使用。

image-20210808161150623

最近两年苹果对CloudKit仪表台的布局做过较大的调整,上面的截图是2021年中时的样子。

仪表台主要分为三个部分:

•数据库(CloudKit Database)数据库Web客户端。涵盖管理SchemaRecordZone、用户权限、容器环境等功能。•遥测(Telemetry)使用直观的可视化效果,深入了解应用程序的服务器端性能以及跨数据库和推送事件的利用率。•日志(Logs)CloudKit 服务器生成实时和历史日志,记录并显示应用程序和服务器之间的交互。

在绝大多数使用Core Data with CloudKit的场景下,我们仅需要使用仪表板中极少数的功能(环境部署),但利用CloudKit Dashboard,我们可以更清楚的了解Core Data数据同步背后运作的一些机制。

数据库(CloudKit Database)

image-20210808163319683

在Core Data with CloudKit (一) —— 基础[3]中已经对CKContainerCKDababaseCKZoneCKSubscriptionCKRecord等基础对象做了简单的说明,本文还将介绍CloudKit的其他一些对象和功能。

环境

CloudKit为你的应用程序网络数据分别提供了开发环境(Develpment)和生产环境(Production)。

•开发环境当你的项目仍处于开发阶段时,所有通过CloudKit产生的数据都只被保存开发环境中,只有开发团队的成员才能访问该环境中的数据。在开发环境中,你可以随时进行Schema结构调整、对Record Type的属性进行删除修改等操作。即使这些操作可能会引起不同版本之间数据冲突都没有问题(可以随时重置开发环境)。非常类似Core Data的应用程序上线前的状态,即使数据无法正常迁移,只需要删除重装app即可。通过开发环境,开发者可以在向用户提供CloudKit服务之前对应用程序进行充分的测试。•生产环境当应用程序完成开发并准备提交应用商店时,需要将开发环境的结构部署到生产环境(Deploy Schema Changes)。Schema一旦部署到生产环境,则意味着开发者不可以像在开发环境中那样随意对Schema进行修改,所有的修改都必须以向前兼容的方式进行。原因非常简单,一旦应用程序上线,我们无法控制客户端的更新频率,也就是客户端可能存在任何的结构版本,为了能够让低版本的客户端一样可以访问数据,任何对数据模型的更改都需要向下兼容。在App Store上销售的应用程序只能访问生产环境。

即使开发者的开发者账户同个人iCloud账户一致,开发环境和生产环境也是两个不同的沙盒,数据是互不影响的。当使用Xcode调试程序时,应用只能访问开发环境,而通过TestflightApp Store下载的应用则只能访问生产环境。

在开发环境下,点击Deploy Schema Changes将开发环境的Schema部署到生产环境。

image-20210808180259192

部署时,会显示自上次部署后开发环境做出的修改。

即使Schema已经部署到生产环境后,我们仍可继续改动开发环境并部署到生产环境,如果模型无法满足兼容条件,CloudKit仪表台将会禁止你的部署行为。

image-20210808175543219

在容器名称下方会显示Schema是否已经部署到生产环境。上图是尚未部署的状态,下图是已经部署的状态。

image-20210808180421055

image-20210808180014216

在做任何操作之前,要首先确认是否处于正确的环境设定中。

鉴于CloudKit的环境部署规则,在采用Core Data with CloudKit的项目中设计Core Data数据模型时一定要特别小心!。我个人的原则是可加、可减、尽量不改。我将在下篇文章详细讨论该如何对Core Data with CloudKit数据模型做版本迁移。

安全角色(Security Roles)

安全角色仅适用于公共数据库。

CloudKit使用基于角色的访问控制(RBAC)来管理权限和控制对公共数据库中数据的访问(私有数据库对于应用程序的用户是唯一的)。通过CloudKit,你可以为一个角色设置权限级别,然后将该角色分配给一个给定的记录类型(Record Type)。

权限包括读、写、创建。读权限只允许读取记录,写权限允许读取和写入记录,而创建权限允许读取和写入记录以及创建新记录。

CloudKit包含3个预设角色,分别为World(_world)、Authenticated(_icloud)和 Creator(_creator)。World表示任何人,无论其是否为iCloud用户。Authenticated适用于任何经过验证的iCloud用户。Creator则是作为记录(Record)的创建者。

image-20210808210401070

默认的设置为,任何人都可以读取数据,只有经过验证的iCloud用户才可以创建新记录,记录的创建者可以更新自己的记录。

image-20210809062640040

我们可以创建自定义安全角色,但是不能创建用户记录(User Record),当用户第一次对容器进行身份验证时时系统会为该用户创建用户记录。我们可以查找现有用户并将其分配给任意的自定义的角色。

安全角色是数据模型(Schema)的一部分,每当开发者修改了安全设置后,需要将其部署到生产环境才能在生产环境生效。部署后无法删除安全角色。

大多数Core Data with CloudKit应用场合,直接使用系统的默认配置即可。

索引(Indexes)

CloudKit的索引分为三种类型:

•可查询(queryable)•可搜索(searchable)•可排序(sortable

当我们通过CloudKit创建Recored Type后,可以根据需要为每个字段创建所需的索引(只有NSString支持可搜索)。索引类型选项是独立的,如果你希望该字段既可查询又可排序,则需要分别创建两个索引。

image-20210809064449042

只有为Record TyperecordName创建了queryable索引后,才可以在Records中浏览该Type的数据。

image-20210809065509228

image-20210809064743215

Core Data with CloudKit会自动为Core Data数据模型的每个属性在CloudKit上创建需要的索引(不包含recordName)。除非你需要在CloudKit仪表台上浏览数据,否则我们不需要对索引做任何添加。

Record Types

Record Type是开发人员为CKRecord指定的类型标识符。你可以直接在代码中创建它,也可以在CloudKit仪表盘上对其进行创建、修改。

image-20210809073043092

在基础篇[4]中曾提到Entity相较Record Type拥有更多的配置信息,但Record Type也有一个Enitity没有的特性——元数据。

image-20210809075124786

CloudKit为每一个Record Type预设了若干元数据字段(即使开发者没有创建任何其他字段),每条数据记录(CKRecord)都会包含这些信息,其中绝大多数都是系统自动设定的。

•createdTimestamp CloudKit首次将记录保存到服务器的时间•createUserRecordName_creator的用户记录,该记录保存在Users(系统创建)中,每当用户第一次对容器进行身份验证时时系统会为该用户创建用户记录•_etag版本令牌。每次CloudKit保存记录时,都会将该记录更新为新值。用于比较网络和本地数据的版本•modifiedTimestampCloudKit更新记录的最近时间•modifiedUserRecordName最后更新数据的用户记录•recordName记录的唯一 ID。在创建CKRcord时创建,通常会设置为UUID字符串

对于一些特殊类型的Record Type,系统还会增加一些针对性的元数据,比如role,cloud.shared

本文的主题为Core Data with CloudKit,因此让我们来看一下NSPersistentCloudKitContainer是如何将Core Data托管对象的属性转换成CloudKitRecore Type字段的。

image-20210809104558352

image-20210809104402659

上图是我们在同步本地数据库到iCloud私有数据库[5]中模版项目ItemCloudKit对应的Record TypeCloudKit会自动为托管对象实体的每个属性创字段,将属性名称映射到了具有CD_[attribute.name]键名的字段。该字段的类型在Core DataCloudKit之间可能也会有所不同。Record Type名称为CD_[entity]。一切的操作都是由系统自动完成的,我们无需干预。另外,还会为Enitity生成一个CD_entityName的字段,内容为Entity的类映射名。 这些以CD_为前缀的字符串,在数据同步过程中将不断出现在控制台上,了解了它的构成对调试代码有一定帮助。 Record Type部署到生产环境后,字段不可以删除,字段名称也不可以修改。因此一些Core Data中的操作在Core Data with CloudKit中是不允许的。 不要对已经上线的应用程序数据模型的Entity进行更名,也不要对Attribute更名,即使使用Mapping Model、Renaming ID都是不行的。在开发阶段如果需要更名的话,可能需要删除app重装并重置CloudKit的开发环境。 即使已经在Core Data中删除了Entity的某个Attribute,该字段仍然会存在于Record Type中(并不会影响同步)。

Zones

每个种类的数据库都有默认Zone,只有私有数据库可以自定义Zone

image-20210809143010363

对于私有数据库中的数据,在创建CKRecord时可以为数据指定Zone

代码语言:javascript
复制
let zone = CKRecordZone(zoneName: "myZone")let newStudent = CKRecord(recordType: "Student",                          recordID: CKRecord.ID(recordName: UUID().uuidString,                                                zoneID: zone.zoneID))

NSPersistentCloudKitContainer在将托管对象转换成CKRecord时,将ZoneID统一设置为com.apple.coredata.cloudkit.zone。必须切换到正确的Zone才能浏览到数据。

image-20210809143648531

•OWNER RECORD NAME用户记录,对应Zone_creator•CHANGE TOKEN比对令牌•ATOMIC当CloudKit无法更新Zone中的一个或多个记录时,如果值为true则整个操作失败

Records

用于数据记录的浏览、创建、删除、更改、查询。

image-20210809150327144

在浏览数据时,需注意以下几点:

•选择正确的环境(开发环境和生产环境的数据完全不同)•选择正确的DatabaseZone•确认需要浏览的Record Type元数据recordName已经添加了queryable索引•如果需要对字段进行排序或过滤,请给该字段创建对应的索引•索引只有在部署后才会在生产环境下起作用

CloudKit仪表台中修改Core Data的镜像数据,客户端会立即收到远程通知并进行更新。不过并不推荐此种做法。

你也可以在代码中获取到Core Data托管对象对应的CKRecord

代码语言:javascript
复制
func getLastUserID(_ object:Item?) -> CKRecord.ID? {    guard let item = object else {return nil}    guard let ckRecord = PersistenceController.shared.container.record(for: item.objectID) else {return nil}    guard let userID = ckRecord.lastModifiedUserRecordID else {        print("can't get userID")        return nil    }    return userID}

上面的代码,将获取托管对象记录对应的CKRecord的最后修改用户

Subscriptions

浏览在容器上注册的CKSubscription

CKSubscription是通过代码创建的,在仪表盘上只可以查看或删除。

比如下面的代码将创建一个CKQuerySubscription

代码语言:javascript
复制
        let predicate = NSPredicate(format: "name = 'bob'")        let subscription = CKQuerySubscription(recordType: "Student",                                               predicate: predicate,                                               options: [.firesOnRecordCreation])        let info = CKSubscription.NotificationInfo()        info.alertLocalizationKey = "create a new bob"        info.soundName = "NewAlert.aiff"        info.shouldBadge = true        info.alertBody = "hello world"        subscription.notificationInfo = info        publicDB.save(subscription) { subscription, error in            if let error = error {                print("error:\(error)")            }            guard let subscription = subscription else { return }            print("save subscription successes:\(subscription)")        }

image-20210809154503445

NSPersistentCloudKitContainer会为Core Data镜像的私有数据库注册一个CKDatabaseSubscription。当com.apple.coredata.cloudkit.zone数据更新时,会推送远程通知。

image-20210809154946576

Tokens&Keys

设置容器的API令牌。

image-20210809152554058

除了可以通过代码和CloudKit仪表台对数据进行操作外,苹果还提供了从网络或其他平台访问iCloud数据的手段。在获取令牌后,开发者还可以通过使用 CloudKit JS [6]或 CloudKit Web 服务[7]与数据进行交互。

已有开发者利用以上服务,开发出可在其他平台访问iCloud数据的第三方库,比如DroidNubeKit[8](在安卓上访问CloudKit)。

对于Core Data的网络镜像数据,除非你的数据模型足够简单,否则不推荐做这种尝试。CloudKit Web服务更适合直接通过Cloudkit创建的数据记录。

Sharing Fallbackd

为低版本操作系统(低于iOS 10、macOS Sierra)提供数据记录共享回调支持。

遥测(Telemetry)

image-20210809161022705

通过查看Telemetry的指标,方便你在开发或更新应用程序时可视化性能。包括请求数量、错误数量、推送数量、服务器延迟以及平均请求大小等等。通过设定范围,仅显示与你相关的数据,帮助你更好地了解应用程序的流量配置及使用趋势。

日志(Logs)

image-20210809162346212

在历史日志中,你可以查看包括时间、客户端平台版本、用户(匿名)、事件、组织、细节等信息。

在提供详尽信息的基础上,CloudKit尽可能地保持用户数据的隐秘性。日志显示每个用户记录的服务器事件,但不暴露任何个人身份信息。仅显示匿名的、特定于容器的CloudKit用户。

AppStoreConnect的分析信息仅来自已同意与 App 开发者共享诊断和使用信息的用户,CloudKit日志信息则来自于你的应用程序中所有使用了CloudKit服务的用户。两者结合使用,可以获得更好的效果。

总结

大多数使用Core Data with CloudKit的场景,开发者基本无需使用CloudKit仪表盘。不过偶尔研究一下仪表盘上的数据,也是一种不错的乐趣。

比如:从2021年7月末开始,健康笔记[9]的CloudKit日志中频繁出现了iphone13设备的身影。

image-20210809164417427

下一篇文章,我们将聊一下开发Core Data with CloudKit项目经常会碰到的一些情况,比如调试、测试、数据迁移等。

引用链接

[1] www.fatbobman.com: http://www.fatbobman.com [2] Apple Developer Program: https://developer.apple.com/programs/ [3] Core Data with CloudKit (一) —— 基础: https://www.fatbobman.com/posts/coreDataWithCloudKit-1/ [4] 基础篇: https://www.fatbobman.com/posts/coreDataWithCloudKit-1/ [5] 同步本地数据库到iCloud私有数据库: https://www.fatbobman.com/posts/coreDataWithCloudKit-2/ [6] CloudKit JS : https://developer.apple.com/documentation/cloudkitjs [7] CloudKit Web 服务: https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/ [8] DroidNubeKit: https://github.com/jaumecornado/DroidNubeKit [9] 健康笔记: https://www.fatbobman.com/project/healthnotes/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 肘子的Swift记事本 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Core Data with CloudKit(三)——CloudKit仪表台
    • 初识仪表台
      • 数据库(CloudKit Database)
        • 环境
        • 安全角色(Security Roles)
        • 索引(Indexes)
        • Record Types
        • Zones
        • Records
        • Subscriptions
        • Tokens&Keys
        • Sharing Fallbackd
      • 遥测(Telemetry)
        • 日志(Logs)
          • 总结
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档