Links

01.基于iCloud构建用户体系

一、前言

这个md文档一月份就创建了,一直没填坑。
虽然应用本身不是什么成功的应用,但是自己感觉在做的过程中还是有挺多收获的。
注意: 本文不会非常详细的说明具体类的使用方法,代码具体怎么写,这些官方文档比任何人都说的清楚。
目的在于对于个人开发者提供一个思路。
大多个人开发者,比如我自己,资源时间精力有限,但是想法很多。
而iCloud是我遇到最合适用来构建起用户体系,以及拓展功能需求的工具了。
自己已经独立做了两款应用,都是基于iCloud建立起来的,欢迎体验反馈,要是再来个五星好评是对我最大的鼓励~
-
扫雷Elic 无尽天梯
梦见账本
下载
AppStore
AppStore
哎,没有设计师自己整UI终究还是不太好看啊~TAT~
下面会以扫雷项目中的例子来做一些说明

二、独立项目用户体系技术方案选型

2.1 自己开发

也不是没考虑过,但不是自己所擅长的。而且需要考虑的问题太多,技术、运维、安全都是需要考虑的。
当然如果有大佬这些都能搞定的话,这是最好的方案了。

2.2 LeanCloud

早期有用这家的服务写过Demo,所以选型的时候也有考虑他家的服务,毕竟后期拓展到不同的平台没有障碍。
但是收费限制多,具体可以自行去查看。Pass

2.3 GameCenter

很早以前有研究过一下,就如其名苹果系统内部的一套游戏用户体系。
包含了用户、排行榜、成就点之类的比较基础的功能。
虽然很多游戏都有接入,但是存在感实在不高。
就我对GameCenter浅薄的了解来说,要拓展功能业务的话,只依靠CameCenter的话是很难支撑起来的,依旧需要另一套东西来承载。
所以Pass掉了。

2.4 iCloud

大家初步对iCloud的认识可能停留在可以备份同步照片文件的基础上。
这里建立用户体系依靠的是CloudKit,建议直接阅读官方文档,想知道的都有。
官方文档:CloudKit

三、什么是CloudKit

Store structured app and user data in iCloud containers that all users of your app can share.
The CloudKit framework provides interfaces for moving data between your app and your iCloud containers. You use CloudKit to store your app’s existing data in the cloud so that the user can access it on multiple devices. You can also store data in a public area where all users can access it.
上面是官方文档中对CloudKit的说明,比较重要的一句 You can also store data in a public area where all users can access it.
数据可共享是建立起用户体系的核心。
推荐苹果的官方文章,根据自身场景,选择合适的接入方案「Determining If CloudKit Is Right for Your App」

四、CloudKit存储数据的方式

1
进入DataBase,对核心的几块内容做一下说明:

4.1 基础数据单元:CKRecord

1
所有数据都是由CKRecord承载,存储在容器中的。
值得注意的是,只要用户开启啦iCloud及iCloudDrive服务。
支持的数据类型如下,这是官方注释里面的:
/// Acceptable value object classes are:
/// - `String`
/// - `Date`
/// - `Data`
/// - `Bool`
/// - `Int`
/// - `UInt`
/// - `Float`
/// - `Double`
/// - `[U]Int8 et al`
/// - `CKReference / CKRecord.Reference`
/// - `CKAsset`
/// - `CLLocation`
/// - `NSData`
/// - `NSDate`
/// - `NSNumber`
/// - `NSString`
/// - `Array` and/or `NSArray` containing objects of any of the types above
///
/// Any other classes will result in an exception with name `NSInvalidArgumentException`.
///
/// Field keys starting with `_` are reserved. Attempting to set a key prefixed with a `_` will result in an error.
///
/// Key names roughly match C variable name restrictions. They must begin with an ASCII letter and can contain ASCII letters and numbers and the underscore character.
/// The maximum key length is 255 characters.
CKRecord本身包含了一些基础字段比如创建者id创建时间修改时间记录id等。
当然我们也可以自定义字段,读写起来就和使用字典类似。具体可以点进CKRecord文件查看,这里就不再多说了。

4.2 数据存储空间:Zone

1
这里就是三个不同访问权限的数据库,通过CKContainer访问。
1

a.Public

  • 默认所有用户可读,所有者可修改
  • 可设置权限,只能在后台进行调整,不可通过API修改
  • 开发者可以通过后台查看
  • 不占用所有者的iCloud储存空间
  • 占用App的iCloud存储空间
扫雷用的是这个数据库,因为包含了排行榜,需要所有用户都可以访问。
下面是相关的两段官方说明:
* Records in a public database
* - By default are world readable, owner writable.
* - Can be locked down by Roles, a process done in the Developer Portal, a web interface. Roles are not present in the client API.
* - Are visible to the application developer via the Developer Portal.
* - Do not contribute to the owner's iCloud account storage quota.
This database is available regardless of whether the user’s device has an iCloud account. The contents of the public database are readable by all users of the app, and users have write access to the records, and other objects, they create. The public database’s contents are visible in the developer portal, where you can assign roles to users and restrict access as necessary. Data in the public database counts toward your app’s iCloud storage quota.

b.Private

  • 默认只有所有者可读写
  • 开发者在后台也无法访问
  • 占用所有者的iCloud存储空间
这个适合做一些私密性较强的应用,比如密码管理应用。
* Records in a private database
* - By default are only owner readable and owner writable.
* - Are not visible to the application developer via the Developer Portal.
* - Are counted towards the owner's iCloud account storage quota.

c.Shared

  • 只对通过CKShare授权的合作者可见
  • 开发者在后台也无法访问
  • 占用组织者的iCloud储存空间
这个没具体用过,先不深入探讨。
* Records in a shared database
* - Are available to share participants based on the permissions of the enclosing CKShare
* - Are not visible to the application developer via the Developer Portal.
* - Are counted towards the originating owner's iCloud account storage quota.

4.3 数据表结构:RecordTypes

1
User是默认就存在的一张表,无须自己创建。如果用户安装了你的应用,你去获取用户对象的时候CloudKit后台会自动生成一条记录。是不是很方便?
根据扫雷Elic的需求场景,我创建了这些表
1
  • User(default):用户
  • AvatarSpace:头像
  • EndLessRank:无尽模式排行榜
  • GameHistory:游戏记录
  • AppConfig:应用配置
  • ZenRank:“禅”模式排行榜

添加自定义字段

1
点进对应Type后就可以看到表结构了,上面一半是默认的数据结构。在下方点+可以添加自定义的字段,并选择数据类型。
需要注意的是:在测试环境下,新增的字段可以删除掉。一旦发布线上后,就不能删除了。只能新增。

4.4 数据索引:Indexs

1
  • QUERYABLE
    • 可查询
  • SORTABLE
    • 可排序
  • SEARCHABLE
    • 可搜索
根据需求进行设置,不设置的话会读不到数据的。
  • 比如无尽模式排行榜,需要根据时间和等级进行的排序,就把level & duration 设置了SORTABLE
1
效果:
1

五、QA

5.1 存在iCloud安全么?

虽然没有绝对的安全,但对比市面上的云存储服务。苹果的还是相对让我放心的。
关键是便宜啊!

5.2 要是用户抓包改数据呢?

我试过抓包,直接连不上容器了。感兴趣的可以尝试一下。

5.3 破解?

写到这里了我掏出了我的越狱机。。。说干就干,砸一个出来重签。
想了解砸壳请移步:应用砸壳
好家伙,直接崩了,挺安全的了吧?
当然我并没有深究能不能跳过系统这一步的验证,等萨尔有下了再来研究下。
我也还没做防Hook,有兴趣破解一下的也可以找我交流哈,十分欢迎。
1

5.4 访问速度

说不上非常快,但是够用。主要还是要合理设计表结构,要是在列表的数据结构里直接包含资源文件的话,那请求速度和用户体验就惨不忍睹了。

5.5 运维成本

几乎谈不上运维,咱也做不了什么。作为开发者能做的就是把应用逻辑和数据结构设计得合理一些。
一些基础的运维数据在后台也是可以看到的。

5.6 跨平台

只做iOS平台还好,要是以后想拓展到不同平台的话,是不是就用不成了?难道还要单独搞一套,甚至迁移用户?
放心,苹果贴心的提供了APICloudKit JS
具体没研究,看起来是可以做跨平台的。

5.7 容量

1PB够用不?
抱歉,我刚看到这个单位的第一时间没反应过来。
就是1024TB,真没想到。
不是一下子就有1P,随着你用户的量级来的。
开发者需要关心的只有Public database所占用的大小。

5.8 资源存储 CKAsset

CloudKit提供了CKAsset这个数据类型用来保存一些资源文件,可以放在CKRecord中进行保存。
看起来挺方便。

问题

如扫雷的排行榜功能,是需要显示头像的。
这里如果将头像直接添加为User表中,那么实际拉取用户的时候会很慢,因为这里会把图片资源一起带下来。而不是我们平时的Url的形式。
如果将图片传到图床上然后添加图片Url的字段也是ok的,但近年来感觉图床限制越来越多了,不方便使用。
这里我后面单独键了张表用来存头像资源,然后封装了一个加载、缓存CKAsset图片资源的工具,方便在排行版中使用。

七、总结

iCloud对于个人开发者来说是个好东西,可以低成本的构建用户体系。
只要发挥想象力,很多功能都是可以可以做的。
这里我用到的只是CloudKit的一部分,还有很多没用过。也许还存在很多的发掘空间。

八、参考