我做了一个毒舌版 MBTI,顺便聊聊 SwiftUI 里怎么管多版本题库数据
市面上所有 MBTI App,要么是学术腔套话——「INTJ是天生的战略家,你拥有卓越的远见」——要么在问我「在派对上你会主动认识陌生人吗」。我哪有时间去派对,我上班都快死了。
这就是我做 NMTI 人格测试 的起因。题目全部设定在职场场景,文案写得毒一点,不要那种让人看完尴尬的温情表述。
四个维度,重新定义
我把人格拆成四个维度:C(控制欲/执行风格)、S(稳定性/抗压倾向)、E(表达欲/存在感需求)、A(利他性/配合意愿),每个维度答题后得出 +/- 标签,四位组合就是你的人格 ID,对应 16 种结果。
文案是我自己写的,写了很久。比如「C+S+E+A-」的人,标签是「优雅吸血鬼」,slogan 是:
满嘴大局观,实则不干活,还能把锅甩得极其自然。
我把这个给几个同事看,他们不约而同地说「这说的是谁?」然后互相开始对号入座。我就知道方向对了。
类似的还有「六边形悍匪」(降维打击型,你不累因为你根本没在试)、「金牌老黄牛」(全组背锅还把姿态摆得极其优美)、「赛博隐形人」(会议里从不发言但把所有人说的话都记住了)。每个人格都有 400-500 字完整描述,我尽量让每段都戳到真实的职场体验,不要放之四海皆准的废话。
做题家版是后来加的
上线后有人问有没有学生版,职场场景对在校学生确实不搭。于是加了 QuizPack 的概念,题目和文案按包切换,现在有「基础牛马包」(职场版)和「做题家版」(学生版)。
文案存储上,职场版直接挂在 Personality 结构体字段里,学生版单独维护一个编译期写死的静态字典 studentCopy——16 个人格 ID 各对应一套 PersonalityCopy,运行时按 pack 取对应内容:
func copy(for pack: QuizPack) -> PersonalityCopy {
switch pack {
case .workplace:
return PersonalityCopy(slogan: slogan, tagline: tagline, fullDesc: fullDesc)
case .student:
// studentCopy 是编译期硬编码的静态字典,key 为人格 ID
// 没用 JSON/plist 是为了避免运行时解析失败,文案改动直接走代码审查
return Self.studentCopy[id]
?? PersonalityCopy(slogan: slogan, tagline: tagline, fullDesc: fullDesc)
}
}
为什么不用 JSON 或 plist?文案内容改动我希望走代码 review,硬编码意味着任何改动都会体现在 diff 里,不会出现「不知道谁在什么时候悄悄改了一句话」的情况。运行时也省掉了一次解析的出错可能。
旧存档兼容也好处理——ArchiveEntry 解码时用 decodeIfPresent,老版本数据没有 pack 字段就默认回 .workplace,不会崩。
题目顺序:分组打乱而不是全局随机
这是个小细节,但踩过坑之后觉得值得说一下。
如果题目全局随机打乱,测几次的用户很快会发现「这道题上次在第3题,这次在第11题」——顺序变了但内容没变,记住选项之后测试就失去意义了。但更大的问题是:全局随机可能导致前 8 道题全部集中在 C/S 两个维度,用户答到一半时已经对 E/A 毫无感知,体验割裂。
我的解法是按维度分 4 个桶,每桶内部各自 shuffle,然后交叉合并——类似洗牌时的「完美洗牌」思路,保证每相邻的 4 道题里各维度各出现一次。大概逻辑是:
// 按维度分桶,各自打乱,再按索引交叉取
let buckets = Dimension.allCases.map { dim in
questions.filter { $0.dimension == dim }.shuffled()
}
let interleaved = (0 ..< buckets[0].count).flatMap { i in
buckets.compactMap { $0.indices.contains(i) ? $0[i] : nil }
}
这样每次进入测试顺序都不同,但维度分布始终均衡,答题节奏也更自然。
其他几个坑
文案工作量比代码大得多。 16 种人格,职场版 + 学生版各一套,slogan/tagline/fullDesc 三个层次,写到后期我自己都在怀疑:我是在做 App 还是在当文案。
海报布局试了三套全删了重来。 原来想做渐变背景,但 ImageRenderer 导出后色彩显示不稳定,改成纯色块 + 大字标题的方案,反而更耐看,分享出去辨识度也更高。
互测功能用 CloudKit 做中转。 把链接发给朋友,对方完成后双方都能看到人格对比和相处建议。逻辑很薄,但这个功能的核心价值是社交——两个人看到系统说「你们这对组合……」,不管说什么都会引发对话。
测完发现自己是「赛博隐形人」的,欢迎来评论区对号入座——我很好奇这个类型在开发者群体里占比有多高。
App Store 搜索「NMTI人格测试」,或直接访问:https://apps.apple.com/app/id6762134564

浙公网安备 33010602011771号