Reputation: 3289
I am in a situation where backend generates hash value of the string it's passing to the app, and there's no control over that hash value generation on backend. I need to generate same string to pass it to app's hash verification algorithm, and here's the problem: the string that is being passed for verification needs to look like this:
[{"crawlLogic":{"startURL":"https://somesite.com/start","someParam":"\r\n\r\n/** Retrieves element's text either by class name" ....
The issue here is that string that is being verified needs to conform to 2 conditions:
1. no backslashes escaping double quotes (as in [{\"crawlLogic\":{\"startURL\":\"https://somesite.com/start\"
)
2. has new line and tab with escapes in it without actually turning those into tabs and new lines.
When I set breakpoint and check the string literal, I see of course those backslashes. But when I print a string in console I see the \n
turned into new lines.
I assume it takes string literal as actual value for verifiation, and therefore my question is how to remove those backslashes in the string literal?
Why or how I know this? Because in Android just before passing in string I do see this string.
Where the string is coming from it's a JSON custom encoder, the string encoding looks like this:
private func encode(_ value: JSON, depth: Int) throws -> String {
switch value {
case let .string(string):
let zeString = #""\#(string)""#
return zeString
case let .number(digits): return digits
case let .bool(value): return value ? "true" : "false"
case let .object(object): return try encode(object: object, depth: depth)
case let .array(array): return try encode(array: array, depth: depth)
case .null: return "null"
}
}
With this I am able to get rid of backslashes in the printed string, but how to keep the \n \r in there?
Upvotes: 0
Views: 2963
Reputation: 299325
You may be confusing how the IDE displays strings and the actual strings that would be printed. Setting breakpoints and looking at the debugger will show you C-escaped strings. If you print those values, the escaping will be gone. For example, if I create the literal string you're describing:
let string = #"[{"crawlLogic":{"startURL":"https://somesite.com/start","someParam":"\r\n\r\n/** Retrieves element's text either by class name""#
The debugger will print this value's debugDescription
which will include escaping (such as \"
and \\r
, note the double-backslash):
print(string.debugDescription)
"[{\"crawlLogic\":{\"startURL\":\"https://somesite.com/start\",\"someParam\":\"\\r\\n\\r\\n/** Retrieves element\'s text either by class name\""
But those extra escapes aren't actually in the string:
print(string)
[{"crawlLogic":{"startURL":"https://somesite.com/start","someParam":"\r\n\r\n/** Retrieves element's text either by class name"
If the debugDescription
has \r
rather than \\r
, then that's indicating you have a carriage return (UTF-8: 0x0d) in your string, not \r
(UTF-8: 0x5c 0x72). If you need to convert carriage return + newline into \r\n
, then you can do that with with replaceOccurrences(of:with:)
.
string.replaceOccurrences(of: "\r\n", with: #"\r\n"#)
This says to replace the string "carriage return, newline" with "backslash r backslash n."
(But I would first investigate why the string is in the wrong form to start with. I'm guessing you're constructing it with "\r\n"
at some point when you meant #"\r\n"#
or "\\r\\n"
. Or perhaps you're unescaping a string you were given when you shouldn't. Escaping and unescaping strings is very tricky. Try to build the string to hold the characters you want in the first place rather than trying to fix it later.)
If you continue to have trouble, I recommend converting your string into UTF-8 (Array(string.utf8)
) and looking at the actual bytes. This will remove all ambiguity about what is in the string.
Upvotes: 3