【iOS独立开发】纯客户端基于iCloud构建排行榜功能

1,223 阅读4分钟

Hi 👋

我的个人项目扫雷Elic 无尽天梯梦见账本隐私访问记录
类型游戏财务工具
AppStoreElicUmemi隐私访问记录

前言

昨天晚上打开我的扫雷Elic,发现排行榜出Bug了:无尽榜单显示不出来了😱。

虽然很快改好发版了。觉得有必要整理一下我的排行榜的实现思路。以为后续优化提供方向。

也希望给大家带来使用 CloudKit 的灵感。

推荐阅读:

如果你对独立开发感兴趣欢迎关注我的专栏:Lawliet的独立开发碎碎念

一、 榜单基础内容

排序逻辑:

  • 游戏等级:越高越靠前
  • 完成时间:越短越靠前

显示元素:

  • 等级
  • 时间
  • 用户昵称
  • 头像

CloudKit09.png

二、 数据流

ElicRankDataFlow.png

基础数据中除了 游戏等级 完成时间 是在 Rank record 中,Nickname Avatar 都是要二次查找的。

由于不存在服务端,所以这些数据处理都要客户端自行处理。

2.1 Rank Table 无尽游戏记录表

ElicRankTable.png

2.2 User Table 用户表

ElicUserTable.png

2.3 数据逻辑

下面描述一下榜单的数据逻辑吧。

  • 玩家成功完成一场无尽模式游戏
    • 前提是 CloudKit 可用
  • 如果 Rank table 中已有该用户创建的记录
    • 如果成绩更好:更新最新游戏记录
    • 否则丢弃本次游戏记录
  • 如果 Rank table 中没有该用户创建的记录
    • 创建一条记录,保存到 Rank table
  • 用户进入榜单列表拉取数据 Rank record 数组
    • 由于并不存在后端,所以数据关联的逻辑需要自己处理
  • 遍历榜单数据获取用户ID数组
    • 遍历用户ID数组,从UserTable中批量查询出对应的 User record 数组。
  • 合并 Rank record & User recordRank item data
    • Rank item dataCell 展示的数据
  • Cell 展示数据

三、 用户头像

3.1 Avatar Table

ElicAvatarTable.png

3.2 图片资源加载

虽然 CloudKit 提供了保存资源的能力,但我们去请求资源的时候,它就是直接完整的返回整个数据了。

所以如果将头像数据直接保存在 User record 中的话,列表的请求速度就很恶心了。(虽然一开始我就是这么做的😂)

在上一步的图中可以看到,Avatar 是独立有一张表来存的。这样就为我的 异步加载图片 创造了可能。

参考主流图片缓存框架的思路简单封装了一下。在 Cell 复用的时候异步加载图片资源。

由于不存在URL这种唯一标识,我采用了 User record id + Avatar modificationDate 为图片的唯一标识。

ElicRanlAvatar.png

当然用图床URL的形式更方便。但是曾经用七牛做博客图床,然后现在图全挂了,还要自己绑域名(虽然我有)。想想算了还是苹果靠谱点(不要钱)。

四、 违规控制

由于榜单内的内容包含了用户自定义的部分如:Nickname Avatar。而且有人的地方就有人搞事。

如果有不好的用户用了一些不好的文案或者头像,对于项目来说是有风险的。平时可能还好,你要是审核的时候被看到那不是妥妥要把你拒掉。

但作为独立开发者(想省钱),我又不可能去接什么审核服务。况且场景本身就把违规的范围控制的很小了,最多两个榜单200条数据。我没事刷一刷看看就行了。

4.1 管理员

为了能快速获得违规用户的ID,我设置了用户角色的字段 manager。拥有该权限的用户直接点击榜单 Cell 就可以复制 User record id。然后进行下一步处理。

4.2 违规内容处理

  • 昵称违规
    • 直接置空
  • 头像违规
    • 删除头像

最开始这里是直接删除 Avatar Table 中由该用户创建的记录,但是有问题的。思考一下欢迎在评论中回复你想到的问题。其实挺简单的。

4.3 屏蔽用户

User Table 中有个 blocked 字段,用以屏蔽用户。

这种用户可以正常用 App,游戏记录也会正常记录,但是在榜单列表中会被过滤掉。

到现在为止,只屏蔽过一个用户,用💛图片,我给他删除一次,还继续上传,然后我就把他屏蔽了🤷‍♂️

五、 优化空间

5.1 违规处理

现在违规处理是复制了 User record id 去后台处理。感觉可以直接把处理的动作直接放在App里,处理起来也更高效。

5.2 异步加载图片

现在的封装还挺简单,有空了完善一下开源出来,也方便自己后续项目使用。

5.3 CloudKit 请求

现在在请求方面做了简单的封装,但主要是基于业务的。难以直接套用,还是抽空封装一下把。