获取颜色作为存储在 Firestore 中的字符串

Posted

技术标签:

【中文标题】获取颜色作为存储在 Firestore 中的字符串【英文标题】:Get color as a string stored in Firestore 【发布时间】:2020-12-13 20:14:59 【问题描述】:

我有这个扩展

 extension Color 
 static func hexColour(hexValue:UInt32)->Color
  
  let red = Double((hexValue & 0xFF0000) >> 16) / 255.0
  let green = Double((hexValue & 0xFF00) >> 8) / 255.0
  let blue = Double(hexValue & 0xFF) / 255.0
  return Color(red:red, green:green, blue:blue)


及用法:

@State var  cstmBackground = Color.hexColour(hexValue: 0xFF0000)

我将颜色作为字符串(hexValue)存储在 Firestore 中。这是我用来从 Firestore 获取颜色的方法:

    struct Spty: Identifiable
var id: String = UUID().uuidString
var spty: String
var color: String

 

    class SptyViewModel: NSObject, ObservableObject


    @Published var specialities = [Spty]()

func fetchData()
    let db = Firestore.firestore()
    db.collection("specialities").addSnapshotListener  (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else return 
        self.specialities = documents.map  (queryDocumentSnapshot) -> Spty in
           let data = queryDocumentSnapshot.data()
            
            let spty = data["spty"] as? String ?? ""
            let color = data["color"] as? String ?? ""
            
            return Spty(spty: spty, color: color)
        
    
    



要根据存储在 Firestore 中的十六进制值显示不同的颜色,我需要连接 SptyViewModel(hexValue: xxxx) 中的 color,但没有成功。怎么做?

编辑:

调试时出现的内容:

2020-12-17 15:28:02.590860-0300 MedApp[4917:50349] 6.34.0 - [Firebase/Analytics][I-ACS023007] Analytics v.60900000 已启动 2020-12-17 15:28:02.592600-0300 MedApp[4917:50349] 6.34.0 - [Firebase/Analytics][I-ACS023008] 要启用调试日志记录,请设置 以下应用程序参数:-FIRAnalyticsDebugEnabled(请参阅 goo.gl/RfcP7r) 信息成功 信息成功 信息成功 2020-12-17 15:28:05.439911-0300 MedApp[4917:50347] 6.34.0 - [Firebase/Analytics][I-ACS800023] 没有待激活的快照。 SDK 名称:app_measurement 2020-12-17 15:28:05.459475-0300 MedApp[4917:50344] 6.34.0 - [Firebase/Analytics][I-ACS023012] 分析收集已启用 2020-12-17 15:28:05.459898-0300 MedApp[4917:50344] 6.34.0 - [Firebase/Analytics][I-ACS023220] 分析屏幕报告已启用。致电 +[FIRAAnalytics logEventWithName:FIREventScreenView parameters:] 记录屏幕视图 事件。要禁用自动屏幕报告,请设置标志 FirebaseAutomaticScreenReportingEnabled 为 NO(布尔值) Info.plist 字段错误 字段错误 字段错误 字段错误

所有字段都是字符串

【问题讨论】:

我不明白你的问题。你是什​​么意思你需要将视图模型中的color(hexValue: xxxx) 连接起来?更加详细一些。使用格式正确的代码,您的问题将获得更好的牵引力。最好的程序员通常是强迫症,当他们看到你为格式化代码付出的努力时,他们甚至不会触及这个问题。 您好,谢谢您的回复。我会尽力解释它,因为英语不是我的母语,有时会有语言限制。我将颜色存储在 Firestore 中,对吗?然后,我需要一种获取颜色字符串的方法,为此我使用类SptyViewModel。由于存储的颜色不是真正的颜色,而是字符串,我需要将它们转换为颜色,以便可以在.background() 中使用它们。为此,我使用extension Color(它使用字符串作为颜色)。我的问题是:怎么做? @bsod 最终结果必须是一个 ForEach 带有不同背景的矩形(根据存储在 firestore 中的颜色字符串) 在 Firestore 中,您将颜色存储为字符串文字,例如 "0xFF0000",对吗?只是好奇,当你将它们存储为整数时会发生什么? 如果我选择“数字”并写,例如0xFF0000,它会自动变为字符串,因为有字母 【参考方案1】:
extension Color 
    init?(rgb: [String: Int]) 
        if let r = rgb["r"],
           let g = rgb["g"],
           let b = rgb["b"] 
            let red = Double(r)/255
            let green = Double(g)/255
            let blue = Double(b)/255
            
            self.init(red: red, green: green, blue: blue)
         else 
            return nil
        
    


struct Spty: Identifiable 
    let id = UUID().uuidString
    let spty: String
    let color: Color?

    init(spty: String, rgbMap: [String: Int]) 
        self.spty = spty
        self.color = Color(rgb: rgbMap)
    


class SptyViewModel: NSObject, ObservableObject 
    @Published var specialities = [Spty]()

    func fetchData()
        Firestore.firestore().collection("specialities").addSnapshotListener  (snapshot, error) in
            guard let snapshot = snapshot else 
                if let error = error 
                    print(error)
                
                return
            
            for doc in snapshot.documents 
                if let spty = doc.get("spty") as? String,
                   let color = doc.get("color") as? [String: Int] 
                    let s = Spty(spty: spty, rgbMap: color)
                    self.specialities.append(s)
                 else 
                    print("field error")
                
            
        
    

【讨论】:

感谢您的所有解释!但是,我将如何正确使用它?顺便说一句,在第一个 if let 中,我收到错误消息:“条件绑定的初始化程序必须具有可选类型,而不是 '[String : Any]'” 刚刚通过删除if let data 中的if 并在其下方添加if let spty 来修复此错误。对吗? 应用启动后,spty相关信息不显示。我用@StateObject.onAppear() self.sptyModel.fetchData() 引用这个类 @MateusNeves 我进行了编辑以修复有关条件绑定的错误。 @MateusNeves 顺便说一句,您可以将 RGB 值作为地图存储在 Firestore 中,而不是使用十六进制字符串,例如 [r: 100, g: 55, b: 255]【参考方案2】:

在阅读了给出的答案并经过一些研究和测试后,我终于明白了。

首先,我在 Firestore 中存储了字段“r”、“g”和“b”,每个字段都是数字,最大值为 255

然后,我在现有的func fetchData() 中添加了以下代码:

struct Spty: Identifiable
var id: String
var spty: String
var r: NSNumber
var g: NSNumber
var b: NSNumber



class SptyViewModel: NSObject, ObservableObject
@Published var specialities = [Spty]()
@Published var search = ""
func fetchData()
    let db = Firestore.firestore()
    db.collection("specialities").addSnapshotListener  (querySnapshot, error) in
        guard let documents = querySnapshot else return 
        self.specialities = documents.documents.compactMap  (doc) -> Spty? in
           let id = doc.documentID
            let spty = doc.get("spty") as! String
            let r = doc.get("r") as! NSNumber
            let g = doc.get("g") as! NSNumber
            let b = doc.get("b") as! NSNumber
            
            return Spty(id: id, spty: spty, r: r , g: g , b: b )
        
    
  
 

然后,在ForEach里面,我用了:

.background(Color(UIColor(red: CGFloat(truncating: spty.r) / 255.0, green: CGFloat(truncating: spty.g) / 255.0, blue: CGFloat(truncating: spty.b) / 255.0, alpha: 1.0)))

不需要extension Color

【讨论】:

以上是关于获取颜色作为存储在 Firestore 中的字符串的主要内容,如果未能解决你的问题,请参考以下文章

将 Firestore 文档作为纯 Javascript 对象获取?

Firestore 没有从反应本机日历中获取字符串

从Firestore获取一个ArrayList并从该列表中选择3个随机字符串

Flutter Firestore - 获取存储为字符串的 URL 时出现空安全错误

有没有办法获取存储在 firestore 中的数组中对象的索引?

Firestore 获取 DocumentSnapshot 的字段值