如何将CGFloat和Color类型数据存储到Realm数据库中?
Realm 存储 CGFloat 与 Color 类型的实现方案
核心逻辑是通过类型映射转换实现非支持类型的存储:在Realm模型层存储Realm原生支持的基础类型,通过计算属性完成与业务所需类型的自动转换,不影响上层业务逻辑。
CGFloat 存储实现
Realm 原生支持 Double 类型,可将 CGFloat 转为 Double 存储,存取时自动转换,完全覆盖DragGesture返回值的精度要求,同时规避了官方提到的CGFloat平台不兼容问题。
Color 存储实现
将SwiftUI Color拆解为RGBA四个Double分量存储,跨平台兼容性高,也可根据需求替换为十六进制字符串存储。
完整Realm模型代码
import RealmSwift import SwiftUI #if os(iOS) || os(tvOS) || os(watchOS) import UIKit typealias ColorConvert = UIColor #elseif os(macOS) import AppKit typealias ColorConvert = NSColor #endif class CardDB: Object { @objc dynamic var id = UUID() @objc dynamic var name = "" // CGFloat对应存储属性 @objc dynamic var x: Double = 0 @objc dynamic var y: Double = 0 // Color对应RGBA存储属性 @objc dynamic var red: Double = 0 @objc dynamic var green: Double = 0 @objc dynamic var blue: Double = 0 @objc dynamic var alpha: Double = 0 // 对外暴露的业务类型计算属性,上层无需关心转换逻辑 var cgX: CGFloat { get { CGFloat(x) } set { x = Double(newValue) } } var cgY: CGFloat { get { CGFloat(y) } set { y = Double(newValue) } } var color: Color { get { Color(red: red, green: green, blue: blue, opacity: alpha) } set { let convertColor = ColorConvert(newValue) var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 convertColor.getRed(&r, green: &g, blue: &b, alpha: &a) red = Double(r) green = Double(g) blue = Double(b) alpha = Double(a) } } // 声明主键,方便后续查询、更新操作 override static func primaryKey() -> String? { return "id" } }
业务模型与Realm模型互转扩展
无需修改原有业务层的Card结构体,通过扩展实现快速转换:
// 业务Card转Realm存储模型 extension Card { func toDBModel() -> CardDB { let dbModel = CardDB() dbModel.id = id dbModel.name = name dbModel.cgX = x dbModel.cgY = y dbModel.color = color return dbModel } } // Realm存储模型转业务Card extension CardDB { func toCardModel() -> Card { Card(id: id, name: name, color: color, y: cgY, x: cgX) } }
注意事项
- 所有Realm存储属性都需要加
@objc dynamic修饰,计算属性不需要加 - 存储的Double类型可完美覆盖32/64位平台的CGFloat精度要求,不会出现数据丢失
内容的提问来源于stack exchange,提问作者fdvfarzin
相关产品推荐
相关产品推荐

