Skip to content

Commit ff12a98

Browse files
authored
(128549365) Add compatibility path for JSONEncoder.sortedKeys behavior change (#631)
1 parent f657181 commit ff12a98

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

Sources/FoundationEssentials/JSON/JSONWriter.swift

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,36 @@ internal struct JSONWriter {
347347
}
348348

349349
if sortedKeys {
350-
let elems = dict.sorted { a, b in
351-
a.key.utf8.lexicographicallyPrecedes(b.key.utf8)
350+
#if FOUNDATION_FRAMEWORK
351+
var compatibilitySorted = false
352+
if JSONEncoder.compatibility1 {
353+
// If applicable, use the old NSString-based sorting with appropriate options
354+
compatibilitySorted = true
355+
let nsKeysAndValues = dict.map {
356+
(key: $0.key as NSString, value: $0.value)
357+
}
358+
let elems = nsKeysAndValues.sorted(by: { a, b in
359+
let options: String.CompareOptions = [.numeric, .caseInsensitive, .forcedOrdering]
360+
let range = NSMakeRange(0, a.key.length)
361+
let locale = Locale.system
362+
return a.key.compare(b.key as String, options: options, range: range, locale: locale) == .orderedAscending
363+
})
364+
for elem in elems {
365+
try serializeObjectElement(key: elem.key as String, value: elem.value, depth: depth)
366+
}
352367
}
353-
for elem in elems {
354-
try serializeObjectElement(key: elem.key as String, value: elem.value, depth: depth)
368+
#else
369+
let compatibilitySorted = false
370+
#endif
371+
372+
// If we didn't use the NSString-based compatibility sorting, sort lexicographically by the UTF-8 view
373+
if !compatibilitySorted {
374+
let elems = dict.sorted { a, b in
375+
a.key.utf8.lexicographicallyPrecedes(b.key.utf8)
376+
}
377+
for elem in elems {
378+
try serializeObjectElement(key: elem.key as String, value: elem.value, depth: depth)
379+
}
355380
}
356381
} else {
357382
for (key, value) in dict {

0 commit comments

Comments
 (0)