A small client for downloading metadata from public endpoints.
0

Configure Feed

Select the types of activity you want to include in your feed.

Swift 100.0%
4 3 0

Clone this repository

https://tangled.org/woody.fm/swift-web-metadata https://tangled.org/did:plc:5jfsnks3h3zkpsmgcffpup6i
git@tangled.org:woody.fm/swift-web-metadata git@tangled.org:did:plc:5jfsnks3h3zkpsmgcffpup6i

For self-hosted knots, clone URLs may differ based on your setup.



README.md

Web Metadata#

Small Swift helpers for fetching and constructing metadata about web pages.

swift-web-metadata keeps common web-preview building blocks in focused modules: favicon URL construction, oEmbed request/response models, and an optional Point-Free Dependencies client for fetching metadata through an injectable boundary.

import Favicon
import OEmbed

let faviconURL = Favicon.googleS2URL(host: "bsky.social", size: 64)

let request = OEmbedRequest(
  endpointURL: OEmbedEndpoint.youtube,
  resourceURL: URL(string: "https://www.youtube.com/watch?v=abc123")!,
  maxWidth: 640,
  maxHeight: 360
)

Installation#

Add the package to your Swift package dependencies:

.package(url: "https://tangled.org/woody.fm/swift-web-metadata", branch: "main")

Then add the products you need to your target dependencies:

.target(
  name: "YourFeature",
  dependencies: [
    "Favicon",
    "OEmbed",
  ]
)

Favicons#

Use Favicon to derive conventional favicon URLs from either a host string or an existing page URL.

let googleURL = Favicon.googleS2URL(host: "example.com", size: 128)
// https://www.google.com/s2/favicons?domain=example.com&sz=128

let directURL = Favicon.directURL(host: "example.com")
// https://example.com/favicon.ico

The Google S2 helper is useful for previews that need a normalized icon source, while the direct helper points at the site's conventional /favicon.ico location.

oEmbed#

OEmbedRequest builds provider request URLs and OEmbedMetadata decodes the standard oEmbed response fields.

let request = OEmbedRequest(
  endpointURL: OEmbedEndpoint.spotify,
  resourceURL: URL(string: "https://open.spotify.com/track/example")!
)

let url = request.url

Common provider endpoints are available through OEmbedEndpoint:

OEmbedEndpoint.youtube
OEmbedEndpoint.soundCloud
OEmbedEndpoint.spotify
OEmbedEndpoint.twitter
OEmbedEndpoint.tiktok

Dependencies#

Enable the Dependencies trait to use the WebMetadataClient product:

swift test --traits Dependencies

Then add WebMetadataClient and Dependencies to the targets that need an injectable metadata boundary:

.target(
  name: "YourFeature",
  dependencies: [
    "WebMetadataClient",
    .product(name: "Dependencies", package: "swift-dependencies"),
  ]
)

The live client fetches oEmbed metadata through URLSession and delegates favicon URL construction to the Favicon module.

import Dependencies
import WebMetadataClient

@Dependency(\.webMetadataClient) var webMetadataClient

let metadata = try await webMetadataClient.fetchOEmbed(request)

In tests, replace the client with closures that return the metadata your feature expects:

let expected = OEmbedMetadata(type: .link, title: "Example")

let metadata = try await withDependencies {
  $0.webMetadataClient = WebMetadataClient(
    fetchOEmbed: { _ in expected },
    googleS2FaviconURL: { host, size in
      Favicon.googleS2URL(host: host, size: size)
    },
    directFaviconURL: { host in
      Favicon.directURL(host: host)
    }
  )
} operation: {
  @Dependency(\.webMetadataClient) var client
  return try await client.fetchOEmbed(request)
}

#expect(metadata == expected)

Requirements#

This package currently targets Swift 6.1 or later, iOS 17 or later, and macOS 14 or later.