import Foundation struct SubBanner: Decodable, Hashable, Identifiable { enum Placement: String, Decodable { case homeRecommendation = "HOME_RECOMMENDATION" case contentRecommendation = "CONTENT_RECOMMENDATION" } let id: Int let placement: Placement let imageUrl: String let webUrl: String? let androidDeepLink: String? let iosDeepLink: String? var imageURL: URL? { Self.webURL(imageUrl) } var webURL: URL? { Self.webURL(webUrl) } var iosURL: URL? { guard let url = Self.absoluteURL(iosDeepLink), let scheme = url.scheme?.lowercased(), !["javascript", "data", "file", "content"].contains(scheme) else { return nil } return url } var isEligible: Bool { imageURL != nil && (iosURL != nil || webURL != nil) } private static func absoluteURL(_ raw: String?) -> URL? { guard let raw, let url = URL(string: raw), url.scheme != nil, url.absoluteString == raw else { return nil } return url } private static func webURL(_ raw: String?) -> URL? { guard let url = absoluteURL(raw), let scheme = url.scheme?.lowercased(), scheme == "http" || scheme == "https", let host = url.host, !host.isEmpty else { return nil } return url } }