Skip to content

Warning: Extension declares a conformance of imported type 'MetadataValue' to imported protocols 'Decodable', 'Encodable'; this will not behave correctly if the owners of 'Logging' introduce this conformance in the future #4

@david-fruehwirth

Description

@david-fruehwirth

When compiling the package for iOS26, a warning pops up:

extension Logger.MetadataValue: Codable { // Warning: Extension declares a conformance of imported type 'MetadataValue' to imported protocols 'Decodable', 'Encodable'; ...
    public init(from decoder: Decoder) throws {
... 
   }
}

I silenced the warning by wrapping the MetadataValue into a structure I own:

struct CodableMetadataValue: Codable {
    let value: Logger.MetadataValue

    init(_ value: Logger.MetadataValue) {
        self.value = value
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()

        if let string = try? container.decode(String.self) {
            value = .string(string)
        } else if let dictionary = try? container.decode([String: CodableMetadataValue].self) {
            value = .dictionary(dictionary.mapValues(\.value))
        } else if let array = try? container.decode([CodableMetadataValue].self) {
            value = .array(array.map(\.value))
        } else {
            throw DecodingError.dataCorrupted(
                .init(codingPath: decoder.codingPath,
                      debugDescription: "Unsupported Logger.MetadataValue type.")
            )
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch value {
        case let .string(s):
            try container.encode(s)
        case let .stringConvertible(s):
            try container.encode(s.description)
        case let .dictionary(d):
            try container.encode(d.mapValues(CodableMetadataValue.init))
        case let .array(a):
            try container.encode(a.map(CodableMetadataValue.init))
        }
    }
}

/// Codable wrapper for `Logger.Metadata`
struct CodableMetadata: Codable {
    let value: Logger.Metadata

    init(_ value: Logger.Metadata) {
        self.value = value
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let dictionary = try container.decode([String: CodableMetadataValue].self)
        value = dictionary.mapValues(\.value)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(value.mapValues(CodableMetadataValue.init))
    }
}

and adjusting the log creation:

 let combinedMetadata = self.metadata.merging(metadata ?? [:]) { $1 }
        let entry = LogEntry(
            label: label, file: file, line: "\(line)", source: source, function: function,
            level: level.rawValue, message: message.description, loggedAt: Date(),
            metadata: CodableMetadata(combinedMetadata)
        )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions