枚举图像以匹配 JSON

Enum with Images to match JSON

我有一个枚举状态,映射到我保存在我的 .xcassets 文件夹中的图像:

 enum States: String {

    case AL, AR, etc

    var image: UIImage {
    switch self {
    case .AL: return UIImage(named: "Alabama")!
    case .AR: return UIImage(named: "Arkansas")!

    }
   }
  }

程序结构:

struct Programs: Codable, Identifiable {

        enum CodingKeys: CodingKey {
        case programName, programState
      }

      var id = UUID()
      var programName: String
      var programState: String

      func mapToStates() -> States? {
        return States(rawValue: programState)
        }
      }
    }

计划JSON:

{
"programName": "Alabama Time",
"programState": "AL",
}

在 ProgramRow 中将其与 SwiftUI 一起使用:

    struct ProgramRow: View {
        var programData: Programs

        var body: some View {
        VStack(alignment: .leading) {
        HStack {
        Image(uiImage: States.AL.image) <-- use here, right now static value

        VStack(alignment: .leading) {
        Text(programData.programName)
        }
       }.padding()
     }
    }
   }

我的问题是检查返回的 JSON 并显示与从 JSON 返回的内容匹配的状态图像的最佳方法是什么?

如果你想解析整个JSON,你可以这样做:

//In my case, I'm using SwiftyJSON
import SwiftyJSON

class Program {
  let name: String
  let state: States

  init(from json: JSON) {
    guard 
      let name = json["programName"].string,
      let state = States(rawValue: json["programState"].string ?? "")
      else { return nil }
    self.name = name
    self.state = state
  }
}

然后,您必须将您的回复映射到 Program:


let response: JSON = ... //get response

guard let program = Program(from: response) else { return }

//use program.
myImageView.image = program.state.image

首先,你应该修复你的枚举。在 switch 中添加大小写 etc:

enum States: String {
    case AL, AR, etc

    var image: UIImage? {
        switch self {
        case .AL:
            return UIImage(named: "Alabama")
        case .AR:
            return UIImage(named: "Arkansas")
        case .etc:
            return nil
        }
    }
}

您可以使用可编码模型:

struct Programs: Codable {
    var programName: String
    var programState: String

    func mapToStates() -> States? {
        return States(rawValue: programState ?? "")
    }
}

并从 json 字符串获取您的状态:

do {
    let programs = try JSONDecoder().decode(Programs.self, from: jsonString.data(using: .utf8) ?? Data())
    guard let state = programs.mapToStates() else { return }
    // Use state
} catch {
    print(error)
}

在您的代码中,它应该如下所示:

struct ProgramRow: View {
    var programData: Programs

    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(uiImage: programData.mapToStates()?.image ?? UIImage())

                VStack(alignment: .leading) {
                    Text(programData.programName)
                }
            }.padding()
        }
    }
}

使用 NSLocalizedString 更有效的解决方案。它像字典一样工作,将一个值映射到另一个值。

  • 创建一个新的 strings 文件并将其命名为 States.strings

  • 填充文件(语法很重要)

    "AL" = "Alabama";
    "AR" = "Arkansas";
    
    etc
    
  • 删除enum

  • mapToStates()替换为

    var image : UIImage {
        let imageName = NSLocalizedString(programState, tableName:"States", comment: "")
        return UIImage(named: imageName)!
    }
    

并使用它

Image(uiImage: programData.image)