Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Sources/FoundationEssentials/URL/URL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,15 @@ public struct URL: Equatable, Sendable, Hashable {

#if FOUNDATION_FRAMEWORK
private static var _type: any _URLProtocol.Type {
if URL.compatibility2 {
return _BridgedURL.self
}
return foundation_swift_url_enabled() ? _SwiftURL.self : _BridgedURL.self
}
#else
private static let _type = _SwiftURL.self
#endif


#if FOUNDATION_FRAMEWORK
internal let _url: any _URLProtocol & AnyObject
internal init(_ url: any _URLProtocol & AnyObject) {
Expand Down
21 changes: 18 additions & 3 deletions Sources/FoundationEssentials/URL/URL_Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,32 @@
internal import _ForSwiftFoundation
internal import CoreFoundation_Private.CFURL

#if canImport(os)
internal import os
#endif

/// `_BridgedURL` wraps an `NSURL` reference. Its methods use the old implementations, which call directly into `NSURL` methods.
/// `_BridgedURL` is used when an `NSURL` subclass is bridged to Swift, allowing us to:
/// 1) Return the same subclass object when bridging back to ObjC.
/// 2) Call methods that are overridden by the `NSURL` subclass like we did before.
/// - Note: If the `NSURL` subclass does not override a method, `NSURL` will call into the underlying `_SwiftURL` implementation.
internal final class _BridgedURL: _URLProtocol, @unchecked Sendable {
internal final class _BridgedURL: NSObject, _URLProtocol, @unchecked Sendable {
private let _url: NSURL
internal init(_ url: NSURL) {
self._url = url
}

private static let logForwardingErrorOnce: Void = {
#if canImport(os)
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.")
#endif
}()

override func forwardingTarget(for aSelector: Selector!) -> Any? {
_ = Self.logForwardingErrorOnce
return _url
}

init?(string: String) {
guard !string.isEmpty, let inner = NSURL(string: string) else { return nil }
_url = inner
Expand Down Expand Up @@ -384,11 +399,11 @@ internal final class _BridgedURL: _URLProtocol, @unchecked Sendable {
}
#endif

var description: String {
override var description: String {
return _url.description
}

var debugDescription: String {
override var debugDescription: String {
return _url.debugDescription
}

Expand Down