Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we extract image from LPLinkView in LinkPresentation framework?

I want to present a rich link in my app and also send those data to my server. I need to access the image inside the view of LPLinkView.

how can I access the parameters inside it? (like: image, description, title, icon, and ext...)

LPLinkView of URL swift

like image 513
Sajjad Sarkoobi Avatar asked Apr 18 '20 08:04

Sajjad Sarkoobi


1 Answers

Unfortunately, you can't access any internal properties of an LPLinkView, but you can easily create your own view. The LPLinkMetadata object has everything you need, you just need to know how to extract the images from its iconProvider and imageProvider, which are subclasses of NSItemProvider.

UIKit (iOS)

You can use NSItemProvdier's loadObject(ofClass:) method to easily get a UIImage. This works because UIImage conforms to the NSItemProviderReading protocol.

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's Image is a struct, so it cannot conform to NSItemProviderReading. It's easiest to use the UIKit code above to obtain a UIImage and instantiate a SwiftUI Image from that.

...

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

AppKit (macOS)

Unlike its UIImage sister, NSImage does not conform to NSItemProviderReading, which means you'll have to use NSItemProvdier's older loadItem(forTypeIdentifier:options:) method.

You'll need to specify the typeIdentifier and initialize the NSImage from Data yourself, but otherwise it's pretty much the same.

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")
        }
    }
}
like image 140
robfeldmann Avatar answered Nov 09 '22 04:11

robfeldmann