From a0877d146100dc1d16c259b1540bd49976eb3bcc Mon Sep 17 00:00:00 2001 From: Kyle Hickinson Date: Tue, 24 Mar 2026 09:59:06 -0400 Subject: [PATCH] [iOS] Add new favicon status to TabState (#34909) This exposes the new favicon status method from WebState in TabState. In the future the `Favicon` value will be removed --- ios/brave-ios/Sources/Web/AnyTabState.swift | 1 + .../Sources/Web/Chromium/ChromiumTabState.swift | 10 ++++++++++ ios/brave-ios/Sources/Web/TabState.swift | 11 +++++++++++ ios/brave-ios/Sources/Web/Test/FakeTabState.swift | 1 + 4 files changed, 23 insertions(+) diff --git a/ios/brave-ios/Sources/Web/AnyTabState.swift b/ios/brave-ios/Sources/Web/AnyTabState.swift index a1cece3ab93..50fef8f5af8 100644 --- a/ios/brave-ios/Sources/Web/AnyTabState.swift +++ b/ios/brave-ios/Sources/Web/AnyTabState.swift @@ -79,6 +79,7 @@ public class AnyTabState: TabState { set { tab.favicon = newValue } } + public var faviconStatus: FaviconStatus? { tab.faviconStatus } public var url: URL? { tab.url } public var visibleURL: URL? { tab.visibleURL } public var lastCommittedURL: URL? { tab.lastCommittedURL } diff --git a/ios/brave-ios/Sources/Web/Chromium/ChromiumTabState.swift b/ios/brave-ios/Sources/Web/Chromium/ChromiumTabState.swift index a267cea04e0..68c1654d5ec 100644 --- a/ios/brave-ios/Sources/Web/Chromium/ChromiumTabState.swift +++ b/ios/brave-ios/Sources/Web/Chromium/ChromiumTabState.swift @@ -320,6 +320,10 @@ class ChromiumTabState: TabState, TabStateImpl { return webView?.visibleSSLStatus?.certificate?.createServerTrust() } var favicon: Favicon? + var faviconStatus: FaviconStatus? { + guard let faviconStatus = webView?.faviconStatus else { return nil } + return .init(faviconStatus) + } var url: URL? { visibleURL } @@ -558,6 +562,12 @@ extension UserAgentType { } } +extension FaviconStatus { + init(_ faviconStatus: CWVFaviconStatus) { + self.init(url: faviconStatus.url, image: faviconStatus.image) + } +} + private struct ChromiumBackForwardList: BackForwardListProxy { struct Item: BackForwardListItemProxy { var item: CWVBackForwardListItem diff --git a/ios/brave-ios/Sources/Web/TabState.swift b/ios/brave-ios/Sources/Web/TabState.swift index a1486164278..3d581f5505d 100644 --- a/ios/brave-ios/Sources/Web/TabState.swift +++ b/ios/brave-ios/Sources/Web/TabState.swift @@ -63,6 +63,15 @@ public enum TabRestorationError: Error { case invalidData } +/// Favicon related information for a current navigation +public struct FaviconStatus { + /// The URL of the favicon which was used to load it off the web. + public var url: URL? + /// The favicon bitmap for the page. It is fetched asynchronously after the favicon URL is set, + /// so it is possible for `image` to be nil if the fetch hasn't completed + public var image: UIImage? +} + /// Core interface for interaction with the web @dynamicMemberLookup public protocol TabState: AnyObject { @@ -129,6 +138,8 @@ public protocol TabState: AnyObject { /// The current pages favicon // TODO: Should be get only, make favicon fetch logic internal (brave/brave-browser#45095) var favicon: Favicon? { get set } + /// The current cached favicon for the realized tab + var faviconStatus: FaviconStatus? { get } /// The current URL loaded on the page, regardless of the navigation status or spoofing @available(iOS, deprecated, message: "Use `visibleURL` or `lastCommittedURL` instead") var url: URL? { get } diff --git a/ios/brave-ios/Sources/Web/Test/FakeTabState.swift b/ios/brave-ios/Sources/Web/Test/FakeTabState.swift index b5bdaed6978..5ac20c93143 100644 --- a/ios/brave-ios/Sources/Web/Test/FakeTabState.swift +++ b/ios/brave-ios/Sources/Web/Test/FakeTabState.swift @@ -52,6 +52,7 @@ public final class FakeTabState: TabState { public var visibleSecureContentState: SecureContentState { .unknown } public var serverTrust: SecTrust? { nil } public var favicon: Favicon? + public var faviconStatus: FaviconStatus? { nil } public var url: URL? { visibleURL } public var visibleURL: URL? public var lastCommittedURL: URL?