코딩 경로에서 정확히 어떤 요소가 Swift Decoding 오류를 일으키는 지 어떻게 알 수 있습니까?

Bernhard Engl

API 끝점 getChatMessages를 호출하고 다음과 같이 응답을 디코딩합니다.

func getChatMessages(conversation: Int, pagesize: Int = 10, page: Int = 1, completion: @escaping(Result<ConversationDetails, APIError>) -> Void) {
    
    {...some networking - configure request and start dataTask}
    
        do {
            let dateFormatter: DateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .formatted(dateFormatter)
            decoder.keyDecodingStrategy = .custom { codingKeys in
                let lastKey = codingKeys.last!
                if lastKey.intValue != nil || codingKeys.count != 2 { return lastKey }
                if lastKey.stringValue == "count" || lastKey.stringValue == "conversation_participants" { return lastKey }
                return AnyCodingKey(stringValue: "element")!
            }
            let result = try decoder.decode(ResponseMultipleElements<ConversationDetails>.self, from: data!)
            completion(.success(result.detailresponse.element))
        }catch {
            print("Error is: ", error)
            completion(.failure(.decodingError))
        }
    }
    dataTask.resume()
}

이것은 ResponseMultipleElements 구조입니다.

struct ResponseMultipleElements<T1: Decodable>: Decodable {
    let statuscode: Int
    let response_type: Int
    let errormessage: String?
    let detailresponse: Element<T1>

}

struct Element<T2: Decodable>: Decodable {
    let count: Int
    let element: T2
    let conversation_participants: [ConversationParticipants]?
}

struct AnyCodingKey: CodingKey {

    var stringValue: String
    init?(stringValue: String) {
        self.stringValue = stringValue
    }

    var intValue: Int? { return nil }
    init?(intValue: Int) {
        return nil
    }
}

마지막으로, getChatMessages 함수에서 반환 한 ConversationDetails 객체의 구조

class ConversationDetails: Codable {
    
    var messages: [ChatMessage]?
    var conversation_participants: [ConversationParticipants]?
}

getChatMessages API 호출의 응답은 다음과 같습니다. 여기에 이미지 설명 입력

문제 : 나는 typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "detailresponse", intValue: nil), CodingKeys(stringValue: "element", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))

지금 모든 것을 여러 번 봤지만 오류를 찾을 수 없습니다. 예상되는 <String, Any> 대신 배열을 찾는 요소가 확실하지 않으므로 무엇을 수정해야할지 모르겠습니다. 누군가가 도울 수 있기를 바랍니다.

스위퍼

귀하는 keyDecodingStrategy그이 아닌, 정확히 하나의 부모가 모든 문자열 키를 치료하는 디코더를 지시 count또는 conversation_participants"요소"로. -이 조건을 만족하여 JSON에 하나의 열쇠가 messages아래는 detailresponse.

messages키에 의해 디코딩 될 것이다 :

let element: T2

어디에 T2:

class ConversationDetails: Codable {
    var messages: [ChatMessage]?
    var conversation_participants: [ConversationParticipants]?
}

그러나 messages실제로는 JSON의 배열입니다!

내가 제안하는 것은 ResponseMultipleElements<[ChatMessage]?>. 이 방법 T2은 실제로 예상되는 배열 유형입니다.

이니셜 라이저를 추가하여 채팅 메시지 및 참가자 배열에서 ConversationDetails를 만들 수 있습니다 ConversationDetails.

init(messages: [ChatMessage]?, conversation_participants: [ConversationParticipants]?) {
    self.messages = messages
    self.conversation_participants = conversation_participants
}

그리고 그것을 사용하십시오 getChatMessages:

let result = try decoder.decode(ResponseMultipleElements<[ChatMessage]?>.self, from: data!)
let convoDetails = ConversationDetails(
    messages: result.detailresponse.element, 
    conversation_participants: result.detailresponse.conversation_participants
    )
completion(.success(convoDetails))

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관