如何使用CodingKeys解决“无值关联”错误?

时间:2019-06-23 14:59:35

标签: json swift

我正在尝试从下面的API解码API,但是仍然出现以下错误:

  

keyNotFound(CodingKeys(stringValue:“ resources”,intValue:nil),Swift.DecodingError.Context(codingPath:[_JSONKey(stringValue:“ resources”,intValue:nil)],debugDescription:“没有与键CodingKeys关联的值(stringValue:\“ resources \”,intValue:nil)(\“ resources \”)。“,底层错误:nil))

API地址:https://age-of-empires-2-api.herokuapp.com/docs/

我已经尝试过多次检查结构,并尝试在API的不同级别中调用代码,但仍然无法获取数据。我还尝试过使用print(resources.XXX)格式从不同级别调用对象。

这是我从API进行的第一个数据调用:

{
  "resources": {
    "civilizations": "https://age-of-empires-2-api.herokuapp.com/api/v1/civilizations", 
    "units": "https://age-of-empires-2-api.herokuapp.com/api/v1/units", 
    "structures": "https://age-of-empires-2-api.herokuapp.com/api/v1/structures", 
    "technologies": "https://age-of-empires-2-api.herokuapp.com/api/v1/technologies"
  }
}

这些是结构的前两个级别:

// MARK: - Resources
struct Resources: Codable {
    let resources: [String : ResourcesList]

    enum CodingKeys: String, CodingKey {
        case resources
    }
}

// MARK: - ResourcesList
struct ResourcesList: Codable {
    let civilizations: CivilizationList
    let units: UnitList
    let structures: StructureList
    let technologies: TechnologyList

    enum CodingKeys: String, CodingKey {
        case civilizations, units, technologies, structures
    }
}

在这些结构下,我已经实现了API网站中指示的模型,例如CivilizationList,Civilization等。

这是我的通话代码:

        let jsonUrl = "https://age-of-empires-2-api.herokuapp.com/api/v1"
        guard let url = URL(string: jsonUrl) else { return }
        URLSession.shared.dataTask(with: url) { (data, response, error) in

            guard let data = data else { return }
            let dataAsString = String(data: data, encoding: .utf8)

            do {
                let decoder = JSONDecoder()
                let resources = try decoder.decode([String : Resources].self, from: data)
                print(resources)
            } catch {
                print(error)
            }
            print(dataAsString!)
        }.resume()

我在这里回顾了所有其他线程,讨论相同的错误代码,尝试了一些东西,但是可能缺少一些非常基本的东西,不幸的是,我对初学者来说太过注意了。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

模型应为

public static class MyTextfieldUI extends com.sun.java.swing.plaf.windows.WindowsTextFieldUI /* TODO which UI class is really used? */ {

    public static ComponentUI createUI(JComponent c) {
        return new MyTextfieldUI();
    }

    @Override
    public View create(Element elem) {
        return new FieldView(elem) {

            @Override
            protected Shape adjustAllocation(final Shape shape) {
                if (shape instanceof Rectangle) {
                    final Rectangle result = (Rectangle) super.adjustAllocation(shape);
                    /* set vertical text position to top */
                    result.y = ((Rectangle) shape).y;
                    return result;
                }

                return super.adjustAllocation(shape);
            }
        };
    }
}

public class Test extends JPanel {

private Test() {
    super(new BorderLayout());

    final JTextField northField = new JTextField();
    northField.setBackground(Color.YELLOW);
    northField.setText("north");

    final JTextField eastField = new JTextField();
    eastField.setBackground(Color.GREEN);
    eastField.setText("east");
    eastField.setPreferredSize(new Dimension(200, -1));

    final JTextField centerField = new JTextField();
    centerField.setBackground(Color.CYAN);
    centerField.setText("center");
    centerField.setHorizontalAlignment(SwingConstants.CENTER);

    final JTextField westField = new JTextField();
    westField.setBackground(Color.GRAY);
    westField.setText("west");
    westField.setHorizontalAlignment(SwingConstants.RIGHT);
    westField.setPreferredSize(new Dimension(200, -1));

    final JTextField southField = new JTextField();
    southField.setBackground(Color.MAGENTA);
    southField.setText("south");
    southField.setHorizontalAlignment(SwingConstants.RIGHT);

    add(northField, BorderLayout.NORTH);
    add(eastField, BorderLayout.EAST);
    add(centerField, BorderLayout.CENTER);
    add(westField, BorderLayout.WEST);
    add(southField, BorderLayout.SOUTH);
}

public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

    /* Set custom look and feel for all text fields */
    UIManager.put("TextFieldUI", MyTextfieldUI.class.getName());

    final JFrame frame = new JFrame("TextDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.add(new Test());
    frame.setSize(800, 500);
    frame.setVisible(true);
}

解码

// MARK: - Empty
struct Resources: Codable {
    let resources: ResourcesList
}

// MARK: - Resources
struct ResourcesList: Codable {
    let civilizations, units, structures, technologies: String
}

let resources = try decoder.decode(Resources.self, from: data) 是字符串而不是模型

OR

civilizations, units, structures, technologies