Swift开发TTRPG应用:如何构建持久化能力值列表及大量数据存储方案
Pathfinder 2e TTRPG iOS应用的Swift实现疑问
我正在开发一款基于TTRPG(具体为Pathfinder 2e)的应用,这是我首次接触Swift与iOS开发,目前对实现需求的合适方式存在困惑。
在TTRPG中存在「能力值(Ability Scores)」——力量(STR)、敏捷(DEX)、体质(CON)、感知(WIS)、智力(INT)、魅力(CHA)。我希望构建一个结构(struct)或类(class)来描述这些能力值,最初设想的struct如下:
struct AbilityScores { var shortName: String //i.e. STR var longName: String //i.e. Strength var description: String //i.e. "Strength is used for XYZ and PDQ" };
由于能力值固定为6个,我直觉认为应该使用枚举(enum),但不确定如何正确实现。我尝试了以下写法:
struct abilityScore { var short: String var long: String var description: String init (short: String, long: String, desc: String){ self.short = short self.long = long self.description = desc } } enum AbilityScores { case STR case DEX case CON case INT case WIS case CHA func GetAbilityScore() -> abilityScore { switch self { case .STR: return abilityScore(short: "STR", long: "Strength", desc: "Strength Description") case .DEX: return abilityScore(short: "DEX", long: "Dexterity", desc: "Dex Description") case .CON: return abilityScore(short: "CON", long: "Constitution", desc: "Con Description") case .INT: return abilityScore(short: "INT", long: "Intelligence", desc: "Int Description") case .WIS: return abilityScore(short: "WIS", long: "Wisdom", desc: "Wisdom Description") case .CHA: return abilityScore(short: "CHA", long: "Charisma", desc: "CHA description") }; } }
并在其他结构中调用,例如:
struct Background { var name: String var description: String var allowedAbilityBoosts: [abilityScore] = [AbilityScores.CON.GetAbilityScore(), AbilityScores.DEX.GetAbilityScore()] }
请问这种实现方式是否正确?另外,对于像Background这类可能多达数百条的数据,有没有更优的实例化方式?是否适合使用iOS内置的SQLite数据库存储这类数据,而非一直使用枚举?
解答
1. 能力值实现的合理性与优化
你的实现思路是可行的,但可以简化得更符合Swift编码习惯:
- 不需要额外的
abilityScore结构体,直接给枚举添加计算属性存储各能力值的相关信息,同时加上CaseIterable协议方便遍历所有枚举值:
enum AbilityScore: CaseIterable { case str, dex, con, int, wis, cha var shortName: String { switch self { case .str: return "STR" case .dex: return "DEX" case .con: return "CON" case .int: return "INT" case .wis: return "WIS" case .cha: return "CHA" } } var longName: String { switch self { case .str: return "Strength" case .dex: return "Dexterity" case .con: return "Constitution" case .int: return "Intelligence" case .wis: return "Wisdom" case .cha: return "Charisma" } } var description: String { switch self { case .str: return "Strength Description" case .dex: return "Dex Description" case .con: return "Con Description" case .int: return "Int Description" case .wis: return "Wisdom Description" case .cha: return "CHA description" } } }
调用时直接通过枚举case获取属性,比如AbilityScore.con.longName,比原方式更简洁直观。
2. Background类数百条数据的实例化优化
硬编码实例化数百条Background数据效率极低,推荐两种方案:
- JSON/Plist资源文件存储:将所有Background数据写成JSON或Plist格式的文件,作为App资源打包,启动时一次性解析成
[Background]数组。适合数据不常变动的场景,实现成本低。
示例JSON结构:
解析时将字符串数组(如[ { "name": "Acolyte", "description": "You served in a temple, learning rituals and doctrines.", "allowedAbilityBoosts": ["WIS", "CHA"] }, { "name": "Criminal", "description": "You lived a life of stealth and subterfuge.", "allowedAbilityBoosts": ["DEX", "CHA"] } ]["WIS", "CHA"])转换为对应的AbilityScore枚举值即可。 - 数据库存储:如果后续需要动态更新数据(比如添加新背景),或支持复杂查询(如按能力值筛选背景),再考虑用数据库。
3. 是否适合使用iOS内置SQLite存储?
- 若数据仅数百条,JSON/Plist完全够用,不需要数据库。这种方式代码量少,维护简单,适合静态数据场景。
- 若数据量会持续增长,或需要搜索、筛选等复杂操作,可以使用SQLite。iOS上推荐用Core Data(苹果官方ORM,底层基于SQLite)或第三方库
GRDB.swift,它们能简化数据库操作,比直接写原生SQLite代码更高效。
内容的提问来源于stack exchange,提问作者phroureo
相关产品推荐
相关产品推荐

