如何使用 LinkPresentation 在 SwiftUI 中获取链接元数据?
Posted
技术标签:
【中文标题】如何使用 LinkPresentation 在 SwiftUI 中获取链接元数据?【英文标题】:How to fetch Link metadata in SwiftUI using LinkPresentation? 【发布时间】:2021-03-01 18:42:22 【问题描述】:根据 WWDC20 和其他文章,从给定的 url 获取图像 url 似乎很容易。下面是我的入门代码。这只是列出了一个随机的 url 列表,并且应该为 url 的丰富链接预览获取 imageurl。 一个简单的使用 LPMetadataProvider 获取元数据。但我无法让它显示图像网址。有人知道它在 SwiftUI 中是如何完成的吗?
import SwiftUI
import LinkPresentation
struct ExampleHTTPLinks: View
var links = [ "https://www.google.com", "https://www.hotmail.com"]
let metadataProvider = LPMetadataProvider()
var body: some View
List(links, id:\.self) item in
HStack
Text(item)
Image(systemName: "heart.fill")
metadataProvider.startFetchingMetadata(for: URL(string: item)!) metadata, error in
if error != nil
// The fetch failed; handle the error.
// Examples: server doesn't respond, is too slow, user doesn't have network.
return
let linkView = LPLinkView(metadata: metadata)
Image(linkView.image)
// Make use of the fetched metadata.
struct ExampleHTTPLinks_Previews: PreviewProvider
static var previews: some View
ExampleHTTPLinks()
【问题讨论】:
【参考方案1】:这是一个工作版本:
class LinkViewModel : ObservableObject
let metadataProvider = LPMetadataProvider()
@Published var metadata: LPLinkMetadata?
@Published var image: UIImage?
init(link : String)
guard let url = URL(string: link) else
return
metadataProvider.startFetchingMetadata(for: url) (metadata, error) in
guard error == nil else
assertionFailure("Error")
return
DispatchQueue.main.async
self.metadata = metadata
guard let imageProvider = metadata?.imageProvider else return
imageProvider.loadObject(ofClass: UIImage.self) (image, error) in
guard error == nil else
// handle error
return
if let image = image as? UIImage
// do something with image
DispatchQueue.main.async
self.image = image
else
print("no image available")
struct MetadataView : View
@StateObject var vm : LinkViewModel
var body: some View
VStack
if let metadata = vm.metadata
Text(metadata.title ?? "")
if let uiImage = vm.image
Image(uiImage: uiImage)
.resizable()
.frame(width: 100, height: 100)
struct ContentView: View
var links = [ "https://www.google.com", "https://www.hotmail.com"]
let metadataProvider = LPMetadataProvider()
var body: some View
List(links, id:\.self) item in
HStack
Text(item)
Image(systemName: "heart.fill")
MetadataView(vm: LinkViewModel(link: item))
如果您尝试将其用于多次调用,LPMetadataProvider 会报错,因此我已将其移至视图模型。
图片是由NSImageProvider
提供的——您可以看到loadObject
调用是从其中获取UIImage
的原因。
请注意,如果您想使用 Apple 提供的开箱即用演示文稿,您可以使用 LPLinkView
。因为它是一个UIView
,要在 SwiftUI 中使用它,你必须用 UIViewRepresentable
包装它:
struct LPLinkViewRepresented: UIViewRepresentable
var metadata: LPLinkMetadata
func makeUIView(context: Context) -> LPLinkView
return LPLinkView(metadata: metadata)
func updateUIView(_ uiView: LPLinkView, context: Context)
struct MetadataView : View
@StateObject var vm : LinkViewModel
var body: some View
if let metadata = vm.metadata
LPLinkViewRepresented(metadata: metadata)
else
EmptyView()
class LinkViewModel : ObservableObject
let metadataProvider = LPMetadataProvider()
@Published var metadata: LPLinkMetadata?
init(link : String)
guard let url = URL(string: link) else
return
metadataProvider.startFetchingMetadata(for: url) (metadata, error) in
guard error == nil else
assertionFailure("Error")
return
DispatchQueue.main.async
self.metadata = metadata
【讨论】:
太棒了。这是一件值得学习的好事情——我也需要在我的一个项目中实现它。 你知道如何打印imageurl吗?文本(metadata.imageurl ??“”)不起作用。 我查看了LPLinkMetadata
、LPLinkView
、NSItemProvider
等的文档,并没有看到任何明显的实际获取 URL 的内容。我的感觉是,如果您特别需要,您可能必须自己执行 http 请求并解析出图像 url。否则,NSItemProvider
会在幕后进行工作以获取图像,而无需让您访问该信息。
好吧,我想是的。但这可能有帮助吗? metaData.imageProvider = NSItemProvider(contentsOf: URL(fileURLWithPath: path ?? "")) 如本文所述? betterprogramming.pub/linkpresentation-in-ios-13-bbb6007818c6
不,这有点倒退。如果你想修改你自己的链接图片。以上是关于如何使用 LinkPresentation 在 SwiftUI 中获取链接元数据?的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 13 dyld:库未加载:/System/Library/Frameworks/LinkPresentation.framework/LinkPresentation
在添加 LinkPresentation 视图的堆栈上重用单元格时不显示元素