xcode 我要将字符串值从API转换为自定义可编码模型

ocebsuys  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(78)

我有一个来自API的回应是这样的:

{
"data": {
    "items": [
        {
            "jsonBody": "{\n  \"documentInfo\": {\n    \"docId\": \"AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA\",\n    \"docCreateTimestamp\": 56565687867,\n    \"docUpdateTimestamp\": 56465755766,\n    \"docSynchTimestamp\": 56565687867,\n    \"documentType\": \"document-monthly-instagram\",\n    \"documentName\": \"Monthly Instagram Posts\",\n    \"docDescription\": \"Monthly Instagram Posts\"\n  },\n  \"documentData\": {\n    \"header\": {\n      \"configuration\": {\n        \"autoGenerate\": [\n          {\n            \"id\": \"headerDocNumberId\",\n            \"type\": \"8code\"\n          },\n          {\n            \"id\": \"headerVersionNumberId\",\n            \"type\": \"autonum\"\n          },\n          {\n            \"id\": \"headerDocumentCreationDateId\",\n            \"type\": \"date\"\n          }\n        ],\n        \"autoFill\": [],\n        \"tileTitle\": \"headerDocumentTileNameId\",\n        \"tileView\": [\n          \"headerDocumentTileNameId\",\n          \"headerDetailsId\",\n          \"headerDocumentCreationDateId\"\n        ],\n        \"createView\": [\n          \"headerMonthNameId\",\n          \"headerNameId\",\n          \"headerDetailsId\"\n        ],\n        \"editView\": [\n          \"headerMonthNameId\",\n          \"headerNameId\",\n          \"headerDetailsId\"\n        ]\n      },\n      \"data\": [\n        {\n          \"id\": \"headerDocNumberId\",\n          \"name\": \"Document Number\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter An Unique Value\",\n          \"value\": \"\",\n          \"type\": \"text\",\n          \"extType\": \"\",\n          \"tag\": \"\",\n          \"readonly\": false,\n          \"required\": true,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerVersionNumberId\",\n          \"name\": \"Document Version\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter A Number\",\n          \"value\": 1,\n          \"type\": \"int\",\n          \"extType\": \"\",\n          \"tag\": \"\",\n          \"readonly\": true,\n          \"required\": true,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerDocumentCreationDateId\",\n          \"name\": \"Time & Date\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter Date\",\n          \"value\": \"\",\n          \"type\": \"text\",\n          \"extType\": \"\",\n          \"tag\": \"\",\n          \"readonly\": true,\n          \"required\": true,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerNameId\",\n          \"name\": \"Name\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter Name\",\n          \"value\": \"\",\n          \"type\": \"text\",\n          \"extType\": \"\",\n          \"tag\": \"\",\n          \"readonly\": true,\n          \"required\": true,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerDocumentTileNameId\",\n          \"name\": \"Document Type\",\n          \"attr\": \"\",\n          \"placeholder\": \"\",\n          \"value\": \"Monthly Log Book\",\n          \"type\": \"text\",\n          \"extType\": \"\",\n          \"readonly\": true,\n          \"requred\": true,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerMonthNameId\",\n          \"name\": \"Month\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter Post Month\",\n          \"value\": \"\",\n          \"type\": \"list\",\n          \"extType\": \"monthTypeListId\",\n          \"readonly\": false,\n          \"requred\": false,\n          \"keyboardType\": \"\"\n        },\n        {\n          \"id\": \"headerDetailsId\",\n          \"name\": \"Details\",\n          \"attr\": \"\",\n          \"placeholder\": \"Enter Details\",\n          \"value\": \"\",\n          \"type\": \"text\",\n          \"extType\": \"\",\n          \"readonly\": false,\n          \"requred\": false,\n          \"keyboardType\": \"\"\n        }\n      ]\n    },\n    \"content\": {\n      \"groups\": [\n        {\n          \"name\": \"Week 1\",\n          \"sectionType\": {\n            \"extendable\": \"dynamic\",\n            \"allowedTypeIds\": [\n              \"typePostId\"\n            ]\n          },\n          \"sections\": [\n          ]\n        },\n        {\n          \"name\": \"Week 2\",\n          \"sectionType\": {\n            \"extendable\": \"dynamic\",\n            \"allowedTypeIds\": [\n              \"typePostId\"\n            ]\n          },\n          \"sections\": [\n          ]\n        },\n        {\n          \"name\": \"Week 3\",\n          \"sectionType\": {\n            \"extendable\": \"dynamic\",\n            \"allowedTypeIds\": [\n              \"typePostId\"\n            ]\n          },\n          \"sections\": [\n          ]\n        },\n        {\n          \"name\": \"Week 4\",\n          \"sectionType\": {\n            \"extendable\": \"dynamic\",\n            \"allowedTypeIds\": [\n              \"typePostId\"\n            ]\n          },\n          \"sections\": [\n          ]\n        }\n      ]\n    },\n    \"summary\": \"\"\n  },\n  \"documentStructure\": {\n    \"sectionTypes\": [\n      {\n        \"id\": \"typePostId\",\n        \"name\": \"INSTAGRAM POST\",\n        \"order\": 0,\n        \"rowType\": {\n          \"extendable\": \"static\",\n          \"allowedTypeIds\": [\n            \"rowDateId\",\n            \"rowNameOfEventId\",\n            \"rowDescriptionId\",\n            \"rowHashTagsId\",\n            \"rowLocationId\",\n            \"rowPeopleLinksId\",\n            \"rowLogosId\",\n            \"rowPicturesVideoId\",\n            \"rowPromoteId\",\n            \"rowDestinationId\",\n            \"rowAudienceId\",\n            \"rowBudgetId\"\n          ]\n        },\n        \"rows\": [\n        ],\n        \"collapsed\": false\n      }\n    ],\n    \"rowTypes\": [\n      {\n        \"id\": \"rowDateId\",\n        \"name\": \"Date\",\n        \"attr\": \"Select date\",\n        \"placeholder\": \"Enter Trip Date\",\n        \"value\": \"\",\n        \"type\": \"date\",\n        \"extType\": \"\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 2\n      },\n      {\n        \"id\": \"rowNameOfEventId\",\n        \"name\": \"Name of Event\",\n        \"attr\": \"Enter name of event\",\n        \"placeholder\": \"Enter name of event\",\n        \"value\": \"\",\n        \"type\": \"textArea\",\n        \"extType\": \"512\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 3\n      },\n      {\n        \"id\": \"rowDescriptionId\",\n        \"name\": \"Decription of Event\",\n        \"attr\": \"Enter description of event\",\n        \"placeholder\": \"Enter description\",\n        \"value\": \"\",\n        \"type\": \"textArea\",\n        \"extType\": \"512\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 4\n      },\n      {\n        \"id\": \"rowHashTagsId\",\n        \"name\": \"Hash Tags\",\n        \"attr\": \"Enter hash tags\",\n        \"placeholder\": \"Enter hash tags\",\n        \"value\": \"\",\n        \"type\": \"textArea\",\n        \"extType\": \"512\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 5\n      },\n      {\n        \"id\": \"rowLocationId\",\n        \"name\": \"Location\",\n        \"attr\": \"Select location\",\n        \"placeholder\": \"Enter location\",\n        \"value\": {\n          \"description\": \"\",\n          \"location\": {}\n        },\n        \"type\": \"address\",\n        \"extType\": \"300\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 6\n      },\n      {\n        \"id\": \"rowPeopleLinksId\",\n        \"name\": \"People links\",\n        \"attr\": \"Enter people links\",\n        \"placeholder\": \"Enter people links\",\n        \"value\": \"\",\n        \"type\": \"textArea\",\n        \"extType\": \"512\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 7\n      },\n      {\n        \"id\": \"rowLogosId\",\n        \"name\": \"Logos\",\n        \"attr\": \"Logos\",\n        \"placeholder\": \"\",\n        \"value\": [],\n        \"type\": \"photo\",\n        \"extType\": \"3\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 8\n      },\n      {\n        \"id\": \"rowPicturesVideoId\",\n        \"name\": \"Pictures/Video Records\",\n        \"attr\": \"Pictures/Video\",\n        \"placeholder\": \"\",\n        \"value\": [],\n        \"type\": \"video\",\n        \"extType\": \"5\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 9\n      },\n      {\n        \"id\": \"rowPromoteId\",\n        \"name\": \"Promote\",\n        \"attr\": \"\",\n        \"placeholder\": \"\",\n        \"value\": false,\n        \"type\": \"bool\",\n        \"extType\": \"\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 10\n      },\n      {\n        \"id\": \"rowDestinationId\",\n        \"name\": \"Destination\",\n        \"attr\": \"Please select destination\",\n        \"placeholder\": \"Select destination\",\n        \"value\": \"iDestinationProfileId\",\n        \"type\": \"list\",\n        \"extType\": \"DestinationTypeListId\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 11\n      },\n      {\n        \"id\": \"rowAudienceId\",\n        \"name\": \"Audience\",\n        \"attr\": \"Please select audience to promote\",\n        \"placeholder\": \"Select audience\",\n        \"value\": \"iAudienceAutomaticId\",\n        \"type\": \"list\",\n        \"extType\": \"AudienceTypeListId\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 12\n      },\n      {\n        \"id\": \"rowBudgetId\",\n        \"name\": \"Budget&Duration\",\n        \"attr\": \"Please choose Budget or Duration\",\n        \"placeholder\": \"Select Budget or Duration\",\n        \"value\": \"iBudgetBudgetId\",\n        \"type\": \"list\",\n        \"extType\": \"BudgetTypeListId\",\n        \"readonly\": false,\n        \"requred\": false,\n        \"keyboardType\": \"\",\n        \"col\": 13\n      }\n    ],\n    \"listTypes\": [\n        {\n            \"id\": \"DestinationTypeListId\",\n            \"items\": [\n                {\n                    \"id\": \"iDestinationProfileId\",\n                    \"value\": \"Your Profile\",\n                    \"selected\": true\n                },\n                {\n                    \"id\": \"iDestinationWebsiteId\",\n                    \"value\": \"Your Website\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iDestinationDirectId\",\n                    \"value\": \"Your Direct Messages\",\n                    \"selected\": false\n                }\n            ]\n        },\n        {\n            \"id\": \"AudienceTypeListId\",\n            \"items\": [\n                {\n                    \"id\": \"iAudienceAutomaticId\",\n                    \"value\": \"Automatic\",\n                    \"selected\": true\n                },\n                {\n                    \"id\": \"iAudienceKUId\",\n                    \"value\": \"Kite Union Clients\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iAudienceCreateId\",\n                    \"value\": \"Create Your Own\",\n                    \"selected\": false\n                }\n            ]\n        },\n        {\n            \"id\": \"BudgetTypeListId\",\n            \"items\": [\n                {\n                    \"id\": \"iBudgetBudgetId\",\n                    \"value\": \"Budget\",\n                    \"selected\": true\n                },\n                {\n                    \"id\": \"iBudgetDurationId\",\n                    \"value\": \"Duration\",\n                    \"selected\": false\n                }\n            ]\n        },\n        {\n            \"id\": \"monthTypeListId\",\n            \"items\": [\n                {\n                    \"id\": \"iMonthTypeJanuaryId\",\n                    \"value\": \"January\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeFebruaryId\",\n                    \"value\": \"February\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeMarchId\",\n                    \"value\": \"March\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeAprilId\",\n                    \"value\": \"April\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeMayId\",\n                    \"value\": \"May\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeJuneId\",\n                    \"value\": \"June\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeJulyId\",\n                    \"value\": \"July\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeAugustId\",\n                    \"value\": \"August\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeSeptemberId\",\n                    \"value\": \"September\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeOctoberId\",\n                    \"value\": \"October\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeNovemberId\",\n                    \"value\": \"November\",\n                    \"selected\": false\n                },\n                {\n                    \"id\": \"iMonthTypeDecemberId\",\n                    \"value\": \"December\",\n                    \"selected\": false\n                }\n            ]\n        }\n    ]\n  }\n}"
        }
    ]
},
"code": 0,
"message": ""

}
我想把字符串“jsonBody”的值转换成可编码模型。
我尝试将其转换为[String:Array],但当我将模型赋值给结果时,它会给出以下错误:
(编码路径:[编码键(字符串值:“jsonBody”,整数值:nil)],调试描述:“应解码Dictionary〈String,Any〉,但找到的是字符串/数据。",underlyingError:无))

d4so4syb

d4so4syb1#

这并不复杂,项目必须使用辅助JsonDecoder

struct Item: Decodable {
    let body: Body

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let jsonBody = try container.decode(String.self, forKey: .jsonBody)
        let jsonBodyData = jsonBody.data(using: .utf8)!

        let decoder = JSONDecoder()
        body = try decoder.decode(Body.self, from: jsonBodyData)
    }

    private enum CodingKeys: String, CodingKey {
        case jsonBody
    }
}

struct Body: Decodable {
    let documentInfo: ...
}
6rqinv9w

6rqinv9w2#

这是一个坚韧的问题。希望这能帮助其他人。我正在解析JSON文件中的数据。下面是解析JSON的代码:

guard let url = Bundle.main.url(forResource: "SYNC_DATA", withExtension: "json") else {
        fatalError("Failed to locate SYNC_DATA in bundle")
    }
    if let data = try? Data(contentsOf: url) {
        let decoder = JSONDecoder()
        if let syncData = try? decoder.decode(SyncResponse.self, from: data) {
            print("Successfully decoded sync data!!!")
            print("Sync Data = \(syncData)")
        }
    } else {
        fatalError("Failed to load SYNC_DATA from bundle")
    }

下面是可编码的:

struct SyncResponse: Codable {
//MARK: items currently in the sync download
var serverTimestamp: String
var status: Bool

//MARK: init method used to decode the data for this object
init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.serverTimestamp = try container.decode(String.self, forKey: .serverTimestamp)
    self.status = try container.decode(Bool.self, forKey: .status)
    ....(other data to decode)
}

enum CodingKeys: String, CodingKey {
    case serverTimestamp = "serverTimestamp"
    case status = "status"
    ....(other data)
}
}

相关问题