contributors |
---|
skhillon |
In iOS 10 and macOS Sierra, Messages got Rich Links to make URLs more beautiful and useful. Rich links were customized for certain types of media, including audio/video playback, Twitter tweets, Apple Maps links, and more.
iOS 13 and macOS 10.15 introduce new APIs that allow developers to put Rich Links in their own apps.
The video shows how to turn a table view of recipe links into Rich Links. Our starting point looks like this:
The LPMetadataProvider
class takes a URL and returns an LPLinkMetadata
object with the title and any available media.
Let's assume we're configuring a UITableViewCell
:
let metadataProvider = LPMetadataProvider()
let url = URL(string: "https://www.apple.com/ipad")!
metadataProvider.startFetchingMetadata(for: url) { 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
}
// Make use of the fetched metadata.
}
- Title, icon, image, and video are all optional.
LPLinkMetadata
is serializable withNSSecureCoding
. This means you can and should cache metadata locally as much as possible.- Can also be used for local file URLs. Quick Look provides the thumbnail for the file if possible.
Continuing the previous example, replace
// Make use of the fetched metadata
with the following
let linkView = LPLinkView(metadata: metadata)
cell.contentView.addSubview(linkView)
linkView.sizeToFit()
Our app now looks like this:
Note that LPLinkView
has an intrinsic size, but it also responds to sizeThatFits()
for an ideal size given the surrounding constraints, and it will try to present a layout that's reasonable at any size.
For existing apps that share URLs, the share sheet will automatically present a preview of the link at the top of the card.
However, this requires reaching out to the server to retrieve metadata once the share sheet is presented, so the title and icon show up asynchronously.
If you already have the metadata, you can send it to the share sheet and the preview will appear instantly:
// Provide prefetched metadata to UIActivityViewController in your implementation
// of UIActivityItemSource
func activityViewControllerLinkMetadata(_: UIActivityViewController) -> LPLinkMetadata? {
return self.metadata
}
Also, when the user chooses to pass that metadata on, say by sending a message, that preview appears instantly.
Lastly, you can provide custom or missing metadata information inside the activityViewControllerLinkMetadata(_:)
method:
func activityViewControllerLinkMetadata(_: UIActivityViewController) -> LPLinkMetadata? {
let metadata = LPLinkMetadata()
// `originalURL` and `url` fields are required. Everything else is optional.
metadata.originalURL = URL(string: "https://www.example.com/apple-pie")
metadata.url = metadata.originalURL
metadata.title = "The Greatest Apple Pie In The World"
metadata.imageProvider = NSItemProvider.init(
contentsOf: Bundle.main.url(forResource: "apple-pie", withExtension: "jpg")
)
return metadata
}