【问题标题】:Can we extract image from LPLinkView in LinkPresentation framework?我们可以从 LinkPresentation 框架中的 LPLinkView 中提取图像吗?
【发布时间】:2020-12-21 02:49:22
【问题描述】:

我想在我的应用程序中显示一个丰富的链接,并将这些数据发送到我的服务器。 我需要访问LPLinkView视图内的图像。

如何访问其中的参数? (例如:图片、描述、标题、图标和扩展...)

【问题讨论】:

    标签: swift xcode web-crawler api-linkpreview


    【解决方案1】:

    很遗憾,您无法访问LPLinkView 的任何内部属性,但您可以轻松创建自己的视图。 LPLinkMetadata 对象有你需要的一切,你只需要知道如何从它的iconProviderimageProvider 中提取图像,它们是NSItemProvider 的子类。

    UIKit (iOS)

    您可以使用NSItemProvdierloadObject(ofClass:) 方法轻松获得UIImage。这是因为UIImage 符合NSItemProviderReading 协议。

    import LinkPresentation
    import UIKit
    
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    
    let url = URL(string: "https://stackoverflow.com/q/61286308/2101447")!
    
    LPMetadataProvider().startFetchingMetadata(for: url) { (linkMetadata, error) in
        guard let linkMetadata = linkMetadata, let imageProvider = linkMetadata.iconProvider else { return }
    
        print(linkMetadata.title ?? "Untitled")
    
        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 {
                    imageView.image = image
                }
            } else {
                print("no image available")
            }
        }
    }
    

    SwiftUI

    SwiftUI 的Image 是一个struct,所以它不能符合NSItemProviderReading。使用上面的 UIKit 代码来获取 UIImage 并从中实例化一个 SwiftUI Image 是最简单的。

    ...
    
    if let uiImage = loadedImage as? UIImage {
        let image = Image(uiImage: uiImage)
    }
    

    AppKit (macOS)

    与其UIImage 姐妹不同,NSImage 不符合NSItemProviderReading,这意味着您必须使用NSItemProvdier 的旧loadItem(forTypeIdentifier:options:) 方法。

    您需要自己指定typeIdentifier 并从Data 初始化NSImage,但除此之外几乎相同。

    import CoreServices // may be necessary for kUTTypeImage 
    import LinkPresentation
    import AppKit
    
    let imageView = NSImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    
    let url = URL(string: "https://stackoverflow.com/q/61286308/2101447")!
    
    LPMetadataProvider().startFetchingMetadata(for: url) { (linkMetadata, error) in
        guard let linkMetadata = linkMetadata, let imageProvider = linkMetadata.iconProvider else { return }
    
        print(linkMetadata.title ?? "Untitled")
    
        imageProvider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil) { (data, error) in
            guard error == nil else {
                // handle error
                return
            }
            guard let data = data as? Data else {
                print("no image available")
                return
            }
            if let image = NSImage(data: data) {
                // do something with image
                DispatchQueue.main.async {
                    self.imageView.image = image
                }
            } else {
                print("no image available")
            }
        }
    }
    

    【讨论】:

    • 不要忘记在DispatchQueue闭包中将self.放在imageView之前
    猜你喜欢
    • 2021-05-28
    • 2012-04-13
    • 2020-12-15
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多