Reputation: 844
I have Swift code which parses an LLDP (link layer discovery protocol) frame, including a field that can be arbitrarily vendor-defined. Sometimes it's a String. Sometimes its an arbitrary data structure.
Here's how I take the data and force it into a String with .utf8 encoding.
let ouiString = String(data: data[data.startIndex + 6 ..< data.startIndex + 2 + tlvLength], encoding: .utf8) ?? ""
Here's the resulting data structure (part of an enumeration with an associated value). "ouiString" above is now in the "info: String" field at the end.
case ouiSpecific(oui: String, subType: Int, info: String)
Here's how I generate a description:
case .ouiSpecific(let oui, let subType, let info):
return "OUI \(oui) subType \(subType) \(info)"
Here's an example of the description where the original data was not a String. The non-displayable characters are shown in a way I find acceptable.
(lldb) po value.description
"OUI 00:12:0f subType 5 \0\u{11}\0\u{11}\0\u{11}\0\u{11}\0\u{11}"
Here's how I try to display it in a SwiftUI List:
List(lldp.values, id: \.self) { value in
Text(value.description)
}
And here's an image of the resulting display in SwiftUI. The info field with all the escaped non-displayable characters are not shown.
How can I display the field in a SwiftUI Text View with the non-displayable characters escaped like in the "po" output?
Upvotes: 3
Views: 712
Reputation: 236568
You can use Unicode.Scalar
method escaped(asASCII: Bool)
to convert unprintable characters to string:
func escaped(asASCII forceASCII: Bool) -> String
Scalar values representing characters that are normally unprintable or that otherwise require escaping are escaped with a backslash.
extension StringProtocol {
var asciiEscaped: String {
unicodeScalars.map{$0.escaped(asASCII: true)}.joined()
}
}
Playground testing:
let str = "\0\u{11}\0\u{11}\0\u{11}\0\u{11}\0\u{11}"
print(str.asciiEscaped)
This will print:
\0\u{11}\0\u{11}\0\u{11}\0\u{11}\0\u{11}
Upvotes: 3