Skip to content

Commit ea9e9e2

Browse files
authored
(151106260) Forward ObjC messages to _BridgedURL in rare compatibility cases (#1301)
1 parent 7002497 commit ea9e9e2

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

Sources/FoundationEssentials/URL/URL.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,13 +635,15 @@ public struct URL: Equatable, Sendable, Hashable {
635635

636636
#if FOUNDATION_FRAMEWORK
637637
private static var _type: any _URLProtocol.Type {
638+
if URL.compatibility2 {
639+
return _BridgedURL.self
640+
}
638641
return foundation_swift_url_enabled() ? _SwiftURL.self : _BridgedURL.self
639642
}
640643
#else
641644
private static let _type = _SwiftURL.self
642645
#endif
643646

644-
645647
#if FOUNDATION_FRAMEWORK
646648
internal let _url: any _URLProtocol & AnyObject
647649
internal init(_ url: any _URLProtocol & AnyObject) {

Sources/FoundationEssentials/URL/URL_Bridge.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,32 @@
1414
internal import _ForSwiftFoundation
1515
internal import CoreFoundation_Private.CFURL
1616

17+
#if canImport(os)
18+
internal import os
19+
#endif
20+
1721
/// `_BridgedURL` wraps an `NSURL` reference. Its methods use the old implementations, which call directly into `NSURL` methods.
1822
/// `_BridgedURL` is used when an `NSURL` subclass is bridged to Swift, allowing us to:
1923
/// 1) Return the same subclass object when bridging back to ObjC.
2024
/// 2) Call methods that are overridden by the `NSURL` subclass like we did before.
2125
/// - Note: If the `NSURL` subclass does not override a method, `NSURL` will call into the underlying `_SwiftURL` implementation.
22-
internal final class _BridgedURL: _URLProtocol, @unchecked Sendable {
26+
internal final class _BridgedURL: NSObject, _URLProtocol, @unchecked Sendable {
2327
private let _url: NSURL
2428
internal init(_ url: NSURL) {
2529
self._url = url
2630
}
2731

32+
private static let logForwardingErrorOnce: Void = {
33+
#if canImport(os)
34+
URL.logger.error("struct URL no longer stores an NSURL. Clients should not assume the memory address of a URL will contain an NSURL * or CFURLRef and should not send ObjC messages to it directly. Bridge (url as NSURL) instead.")
35+
#endif
36+
}()
37+
38+
override func forwardingTarget(for aSelector: Selector!) -> Any? {
39+
_ = Self.logForwardingErrorOnce
40+
return _url
41+
}
42+
2843
init?(string: String) {
2944
guard !string.isEmpty, let inner = NSURL(string: string) else { return nil }
3045
_url = inner
@@ -384,11 +399,11 @@ internal final class _BridgedURL: _URLProtocol, @unchecked Sendable {
384399
}
385400
#endif
386401

387-
var description: String {
402+
override var description: String {
388403
return _url.description
389404
}
390405

391-
var debugDescription: String {
406+
override var debugDescription: String {
392407
return _url.debugDescription
393408
}
394409

0 commit comments

Comments
 (0)