There is an undocumented change in behavior from API v1 to API v2. The website now exhibits the changed behavior, too, presumably because it has changed from using API v1 to using API v2.
Using API v1, when a .strings file was uploaded, a .strings file entry such as
"one\ntwo\nthree\n" = "one\ntwo\nthree\n";
would result in a Crowdin “String” of
"one
two
three
"
In other words, each "\n"
would be converted from a two-character escape sequence to a single ASCII LF character.
The “Identifier (Key)” would not be converted; it would remain "one\ntwo\nthree\n"
, and the string automatically prefixed to “Context” would also not be converted.
This changes in API v2: the resulting Crowdin “String” is "one\ntwo\nthree\n"
In other words, the "\n"
is preserved in the “String”.
This can result in problems when such a file is uploaded if it contains a duplicate of an entry that was previously uploaded using API v1: Although the duplicate entry should “inherit” translations for the uploaded-with-API-v1 string, it doesn’t, because it is considered by Crowdin as a new string [1].
On my project, this resulted in a loss of 34% of my translations when I simply uploaded a copy of an existing file, because 34% of my strings contain “\n”. To deal with this I do the conversion myself, before uploading with the v2 API.
[1] Apparently the “String” is used instead of the “Identifier (Key)” when trying to match a .strings file entry to existing translations. However, that’s a separate issue and could arguably be considered a feature.