Skip to content

Commit 07b8c3a

Browse files
colemancdaclaude
andcommitted
Prefer FoundationEssentials over Foundation when available
On Android/Linux, a plain `import Foundation` autolinks the full swift-corelibs-foundation umbrella (libFoundation.so), which transitively requires libFoundationInternationalization.so and the ~42 MB lib_FoundationICU.so in every consumer's DT_NEEDED chain — even when no ICU-backed API is actually referenced. Preferring FoundationEssentials drops that entire chain; on Darwin nothing changes (FoundationEssentials is not importable there). The only full-Foundation-only API in use was `replacingOccurrences(of:with:)`, replaced with a pure-stdlib helper (the stdlib's own `replacing(_:with:)` needs a newer platform floor than this package supports). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent e96bebb commit 07b8c3a

7 files changed

Lines changed: 59 additions & 6 deletions

File tree

‎Sources/CoreModelSQLite/AttributeValue.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/4/25.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

‎Sources/CoreModelSQLite/CustomFunction.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/16/26.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

‎Sources/CoreModelSQLite/Database.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/4/25.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

‎Sources/CoreModelSQLite/Error.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/9/25.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

‎Sources/CoreModelSQLite/ModelData.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/4/25.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

‎Sources/CoreModelSQLite/Predicate.swift‎

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/4/25.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
import CoreModel
1014
import SQLite
1115

@@ -150,8 +154,8 @@ internal extension FetchRequest.Predicate.Comparison {
150154
case .like:
151155
// Translate Cocoa-style wildcards (`*`, `?`) to SQL (`%`, `_`).
152156
let pattern = try right.likePattern(predicate: predicate)
153-
.replacingOccurrences(of: "*", with: "%")
154-
.replacingOccurrences(of: "?", with: "_")
157+
.replacing(occurrencesOf: "*", with: "%")
158+
.replacing(occurrencesOf: "?", with: "_")
155159
return .like(column: column, pattern: pattern)
156160
case .in:
157161
let values = try right.constantBindings(predicate: predicate)
@@ -308,9 +312,9 @@ private extension FetchRequest.Predicate.Expression {
308312
throw SQLiteDatabaseError.invalidPredicate(predicate)
309313
}
310314
return value
311-
.replacingOccurrences(of: "\\", with: "\\\\")
312-
.replacingOccurrences(of: "%", with: "\\%")
313-
.replacingOccurrences(of: "_", with: "\\_")
315+
.replacing(occurrencesOf: "\\", with: "\\\\")
316+
.replacing(occurrencesOf: "%", with: "\\%")
317+
.replacing(occurrencesOf: "_", with: "\\_")
314318
}
315319
}
316320

@@ -343,6 +347,31 @@ internal extension String {
343347

344348
/// Quote as a SQL identifier.
345349
var quotedIdentifier: String {
346-
"\"" + replacingOccurrences(of: "\"", with: "\"\"") + "\""
350+
"\"" + replacing(occurrencesOf: "\"", with: "\"\"") + "\""
351+
}
352+
353+
/// Replace every occurrence of `target` with `replacement`.
354+
///
355+
/// Pure-stdlib stand-in for Foundation's `replacingOccurrences(of:with:)`,
356+
/// which `FoundationEssentials` (Android/Linux) does not provide; the
357+
/// stdlib's own `replacing(_:with:)` requires a newer platform floor than
358+
/// this package supports on Darwin.
359+
func replacing(occurrencesOf target: String, with replacement: String) -> String {
360+
guard target.isEmpty == false else {
361+
return self
362+
}
363+
var result = String()
364+
result.reserveCapacity(count)
365+
var index = startIndex
366+
while index < endIndex {
367+
if self[index...].hasPrefix(target) {
368+
result += replacement
369+
index = self.index(index, offsetBy: target.count)
370+
} else {
371+
result.append(self[index])
372+
index = self.index(after: index)
373+
}
374+
}
375+
return result
347376
}
348377
}

‎Sources/CoreModelSQLite/ViewContext.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// Created by Alsey Coleman Miller on 7/9/26.
66
//
77

8+
#if canImport(FoundationEssentials)
9+
import FoundationEssentials
10+
#elseif canImport(Foundation)
811
import Foundation
12+
#endif
913
#if canImport(Combine)
1014
import Combine
1115
#endif

0 commit comments

Comments
 (0)