Skip to content

Instantly share code, notes, and snippets.

@Aayush9029
Last active January 13, 2024 03:34
Show Gist options
  • Select an option

  • Save Aayush9029/b49b0128f64a2bfd599e6cd75e27e35c to your computer and use it in GitHub Desktop.

Select an option

Save Aayush9029/b49b0128f64a2bfd599e6cd75e27e35c to your computer and use it in GitHub Desktop.
Swift URLMeta Data Fetcher
import LinkPresentation
import UIKit
struct LinkMetadata {
let title: String
let image: Data?
let url: URL?
init(_ metadata: LPLinkMetadata, imageData: Data? = nil) {
self.title = metadata.title ?? "Untitled Website"
self.url = metadata.url
self.image = imageData
}
}
enum MetadataFetcher {
static func fetchMetadata(for url: URL) async throws -> LinkMetadata {
let metadataProvider = LPMetadataProvider()
let metadata = try await metadataProvider.startFetchingMetadata(for: url)
var imageData: Data? = nil
if let imageProvider = metadata.imageProvider {
imageData = try await loadImageData(imageProvider: imageProvider)
}
return LinkMetadata(metadata, imageData: imageData)
}
private static func loadImageData(imageProvider: NSItemProvider) async throws -> Data? {
try await withCheckedThrowingContinuation { continuation in
imageProvider.loadObject(ofClass: UIImage.self) { image, error in
DispatchQueue.main.async {
if let error = error {
continuation.resume(throwing: error)
} else if let image = image as? UIImage, let data = image.jpegData(compressionQuality: 1.0) {
continuation.resume(returning: data)
} else {
continuation.resume(returning: nil)
}
}
}
}
}
}
// MARK: - View
import SwiftUI
struct LinkView: View {
let url: URL
@State private var metadata: LinkMetadata?
init(_ url: URL) {
self.url = url
}
var body: some View {
ZStack(alignment: .bottom) {
if let metadata {
Group {
if let data = metadata.image {
Image(uiImage: UIImage(data: data)!)
} else {
Image(.appIcon)
}
}
.frame(
width: UIScreen.main.bounds.width - 24,
height: 240
)
VStack {
Text(metadata.title)
.font(.headline)
.lineLimit(2)
if let url = metadata.url {
Text(url.absoluteString)
.font(.subheadline)
.foregroundStyle(.tertiary)
.lineLimit(1)
}
}
.padding(12)
.hSpacing(.leading)
.background(.ultraThinMaterial)
} else {
Rectangle()
.fill(.ultraThinMaterial)
Text(url.absoluteString)
.foregroundStyle(.secondary)
.padding()
}
}
.frame(height: (metadata?.image != nil ? 240 : 48))
.clipShape(.rect(cornerRadius: 18))
.overlay(
RoundedRectangle(cornerRadius: 18)
.stroke(.primary.opacity(0.05), lineWidth: 4)
)
.animation(.bouncy, value: metadata?.image)
.task {
self.metadata = try? await MetadataFetcher.fetchMetadata(for: url)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment