考虑此示例JSON:
{
"sections": [{
"title": "Sign up",
"rows": [
{
"type": "image",
"imageURL": "https://example.com/image.jpg"
},
{
"type": "textField",
"value": "",
"placeholder": "Username"
},
{
"type": "textField",
"placeholder": "password"
},
{
"type": "textField",
"placeholder": "confirmPassword"
},
{
"type": "button",
"placeholder": "Register!"
}
]
}]
}
假设我想将上面的JSON解析为以下模型(我知道由于Row
协议与Decodable
不对应,因此无法编译):
enum RowType: String, Codable {
case textField
case image
case button
}
protocol Row: Codable {
var type: RowType { get }
}
struct TextFieldRow: Row {
let type: RowType
let placeholder: String
let value: String
enum CodingKey: String {
case type
case placeholder
case value
}
}
struct ImageRow: Row {
let type: RowType
let imageURL: URL
enum CodingKey: String {
case type
case imageURL
}
}
struct ButtonRow: Row {
let type: RowType
let title: String
enum CodingKey: String {
case type
case title
}
}
struct Section: Codable {
let rows: [Row]
let title: String
enum CodingKey: String {
case rows
case title
}
}
struct Response: Codable {
let sections: [Section]
enum CodingKey: String {
case sections
}
}
// Parsing the response using the Foundation JSONDecoder
let data: Data // From network
let decoder = JSONDecoder()
do {
let response = try decoder.decode(Response.self, from: data)
} catch {
print("error: \(error)")
}
有没有办法使高于Codable的Swift代码兼容?
我知道您可以通过以下方法手动解决此问题:首先获取每个Row
的{{1}}字符串,然后创建正确类型的type
模型,并将它们从结构更改为类,然后让{ {1}}协议应改为超类。但是有没有一种方法可以减少手工劳动呢?
答案 0 :(得分:1)
使用具有关联值的private void connectDb()
{
SqlConnection conn = new SqlConnection("YOUR DATABASE LOCATION/ DATABASE PATH");
conn.Open(); // initalize your database connection
}
private void searchForStudentName()
{
string name;// = your textbox that holds value of students name;
this.connectDb(); //your connection into database
SqlCommand cmd = new SqlCommand("Select * from ['YOUR TABLE NAME'] where Name = @Name",conn);
cmd.parameters.AddWithValue("@Name", name);
dr= cmd.ExcecuteReader();
if(dr.Read())//meaning, the system found the value of the input data/ name
{
ListViewItem lvi = new ListViewItem(dr["NAME"].ToString);// name will be displayed in listview control
listView1.items.add(lvi);
}else
{
//there is no data found
}
}
是最佳选择:
考虑这个枚举:
enum
进行以下更改:
enum Row: Decodable {
case textField(TextFieldRow)
case image(ImageRow)
// and other cases
case unknown
enum CodingKeys: String, CodingKey {
case type
}
public init(from decoder: Decoder) throws {
do {
let selfContainer = try decoder.singleValueContainer()
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
let type = try typeContainer.decode(String.self, forKey: .type)
switch type {
case "textField": self = .textField( try selfContainer.decode(TextFieldRow.self) )
case "Image": self = .image( try selfContainer.decode(ImageRow.self) )
// and other cases
default: self = .unknown
}
}
}
}
现在,它会像魅力一样解码:
struct TextFieldRow: Decodable {
let placeholder: String?
let value: String?
}
struct ImageRow: Decodable {
let imageURL: URL
}
// and so on
// Minmal testing JSON
let json = """
[
{
"type": "image",
"imageURL": "https://example.com/image.jpg"
},
{
"type": "textField",
"value": "",
"placeholder": "Username"
},
{
"type": "textField",
"placeholder": "password"
}
]
""".data(using: .utf8)!
您现在可以将所需的其他任何情况添加到解码器中,以构建您的 application builder 应用。