It makes a preview from an URL, grabbing all the information such as title, relevant texts and images.

Overview

Swift Link Preview

Link Previewer for iOS, macOS, watchOS and tvOS

It makes a preview from an URL, grabbing all the information such as title, relevant texts and images.

Platform CocoaPods Carthage Compatible Swift Package Manager Build Status

Index


Visual Examples

UTF-8 Extended UTF-8 Gallery
UTF-8 Extended UTF-8 Gallery
Video Websites Images
Video Websites Images

Requirements and Details

  • iOS 8.0+ / macOS 10.11+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 8.0+
  • Built with Swift 3

Installation

CocoaPods

To use SwiftLinkPreview as a pod package just add the following in your Podfile file.

	source 'https://github.com/CocoaPods/Specs.git'
	platform :ios, '9.0'

	target 'Your Target Name' do
	  	use_frameworks!
	  	// ...
	  	pod 'SwiftLinkPreview', '~> 3.3.0'
	  	// ...
	end

Carthage

To use SwiftLinkPreview as a Carthage module package just add the following in your Cartfile file.

  	// ...
	github "LeonardoCardoso/SwiftLinkPreview" ~> 3.3.0
  	// ...

Swift Package Manager

To use SwiftLinkPreview as a Swift Package Manager package just add the following in your Package.swift file.

import PackageDescription

let package = Package(
  name: "Your Target Name",
  dependencies: [
  	// ...
    .Package(url: "https://github.com/LeonardoCardoso/SwiftLinkPreview.git", "3.3.0")
  	// ...
  ]
)

Manually

You just need to drop all contents in Sources folder, but .plist files, into Xcode project (make sure to enable "Copy items if needed" and "Create groups").

Usage

Instatiating

import SwiftLinkPreview

// ...

let slp = SwiftLinkPreview(session: URLSession = URLSession.shared,
			   workQueue: DispatchQueue = SwiftLinkPreview.defaultWorkQueue,
			   responseQueue: DispatchQueue = DispatchQueue.main,
		           cache: Cache = DisabledCache.instance)

Requesting preview

let preview = slp.preview("Text containing URL",
                          onSuccess: { result in print("\(result)") },
                          onError: { error in print("\(error)")})
// preview.cancel() to cancel it.

result is a struct Response:

Response {
	let url: URL // URL
	let finalUrl: URL // unshortened URL
	let canonicalUrl: String // canonical URL
	let title: String // title
	let description: String // page description or relevant text
	let images: [String] // array of URLs of the images
	let image: String // main image
	let icon: String // favicon
	let video: String // video
	let price: String // price
}

Cancelling a request

let cancelablePreview = slp.preview(...,
				    onSuccess: ...,
				    onError: ...)

cancelablePreview.cancel()

Enabling and accessing cache

SLP has a built-in memory cache, so create your object as the following:

let slp = SwiftLinkPreview(cache: InMemoryCache())

To get the cached response:

if let cached = self.slp.cache.slp_getCachedResponse(url: String) {
    // Do whatever with the cached response
} else {
	// Perform preview otherwise
	slp.preview(...)
}

If you want to create your own cache, just implement this protocol and use it on the object initializer.

public protocol Cache {

    func slp_getCachedResponse(url: String) -> SwiftLinkPreview.Response?

    func slp_setCachedResponse(url: String, response: SwiftLinkPreview.Response?)
}

FLOW

flow

Important

You need to set Allow Arbitrary Loads to YES on your project's Info.plist file.

app security

If you don't want to use the option above and you are using SwiftLinkPreview for services of your knowledge, you can whitelist them on Info.plist file as well. You can read more about it here, here and here.

app security

Tips

Not all websites will have their info brought, you can treat the info that your implementation gets as you like. But here are two tips about posting a preview:

  • If some info is missing, you can offer the user to enter it. Take for example the description.
  • If more than one image is fetched, you can offer the user the feature of picking one image.

Tests

Feel free to fork this repo and add URLs on SwiftLinkPreviewTests/URLs.swift to test URLs and help improving this lib. The more URLs the better the reliability.

Information and Contact

Developed by @LeonardoCardoso.

Contact me either by Twitter @leocardz or emailing me to [email protected].

Related Projects

License

The MIT License (MIT)

Copyright (c) 2016 Leonardo Cardoso

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Follow me for the latest updates

Comments
  • Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range<String.Index>)' in func substring(start:end:)

    Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range)' in func substring(start:end:)

    
    func substring(_ start: Int, end: Int) -> String {
    return String(self[Range(self.index(self.startIndex, offsetBy: start) ..< self.index(self.startIndex, offsetBy: end))])
    
        }
    

    the above function contains a method resulting in the following error:

    Cannot invoke initializer for type 'Range<_>' with an argument list of type '(Range<String.Index>)' in Xcode 10 beta 1.

    I appreciate this is a very early report, but does seem to be a swift version issue.

    opened by boywithaxe 7
  • Is SwiftLinkPreview compatible with Xcode 10?

    Is SwiftLinkPreview compatible with Xcode 10?

    I updated to Xcode 10 but my project won't compile. SwiftPreviewLink seems to be a problem, I have this issue:

    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    I have searched but didn't find any solution yet.

    I use Cocoapod.

    opened by mariedm 6
  • Cache response is not called on UITableView

    Cache response is not called on UITableView

  • Xcode 8.2
  • Swift 3
  • ios 9x - 10x

    Everytime I call swift link preview it always call and set the data, how can I get the cache response, I am loading the preview data on UITableview so what should I do to get response from cache data when cell is recycled ` slp.preview(

                LinkObj.path,
                onSuccess: { result in
                //print("\(result)")
    
                cell.linkTitle.text = result[.title] as? String
                cell.linkURL.text = result[.canonicalUrl] as? String
                cell.linkDescription.text = result[.description] as? String
                
                let imageURL = result[.image] as? String
                print(imageURL!)
                cell.linkImage.kf.setImage(with: URL(string: imageURL!), placeholder: UIImage(named:""), options: [.transition(ImageTransition.fade(1))], progressBlock: nil, completionHandler: nil)
                
                cell.linkBtnRef.layer.setValue(result[.url], forKey: "linkURL")
                cell.linkBtnRef.addTarget(self, action: #selector(self.linkClickedOnLinkCell), for: .touchUpInside)
                
        },
            onError: { error in
                print("\(error)")
        }
        )`
    
  • opened by dev-abdul02 6
  • some bit.ly Links causes the app to lag (until the url gets loaded)

    some bit.ly Links causes the app to lag (until the url gets loaded)

    I think this is some kind of small problem for the dispatch or thread, but I'm still not really adept at that part of coding so I don't know.

    http://bit.ly/2dIBlR6 here's the link btw

    But once again. This project is so kickass awesome. Thanks :)

    opened by kuyazee 6
  • Github Repository Image not parsed properly

    Github Repository Image not parsed properly

    Using:

    SwiftLinkPreview 3.3.0
    Xcode 12.4
    

    Issue:

    Invalid response image attribute in case of any GitHub URL.
    

    Reproduce By:

    Request URL:
    
      https://github.com/LeonardoCardoso/SwiftLinkPreview
    
    Response Wrong Attribute:
    
      image: Optional("https://github.githubassets.com/images/search-key-slash.svg")
    
    Should be:
    
      image: Optional("https://opengraph.githubassets.com/ff9150cfc28a8413bb2fc25c4b82ebf0539
    				 7aa3e51e0642527dc68aabdeb1368/LeonardoCardoso/SwiftLinkPreview")
    
    

    Reason:

    Failing to parse the content of this tag <meta property="og:image" content=""> for opengraph image.
    
    opened by MuhtasimTanmoy 5
  • use data detector to extract URLs from text so that plain urls will b…

    use data detector to extract URLs from text so that plain urls will b…

    replaced link detection with NSDataDetector was seeing situations where app was unable to load previews for text containing links of the form "text text github.com" for example

    opened by vinnyt 5
  • Hangs when crawling for description

    Hangs when crawling for description

    The URL I'm crawling is: https://www.flickr.com/explore/

    I stepped through the source and see that it's hanging in crawlDescription() at the crawlCode() call.

    I see this in the debugger console: SendDelegateMessage(NSInvocation *): delegate (<CFNotificationCenter 0x6080000aed60 [0x108679df0]>) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode

    opened by taykay08 5
  • Update user-agent String to imitate iMessage's

    Update user-agent String to imitate iMessage's

    Changes

    • Changed the user-agent string to receive better responses from some sites

    The user-agent string I used is the same (or extremely similar) to the one Apple sends to receive metadata for their link previews in iMessage. After changing to this user-agent string Tweets (which were previously not loading correctly) stopped warning about needing Javascript.

    opened by bdhazman 4
  • Fix for youtube url fetch metadata issue

    Fix for youtube url fetch metadata issue

    This pull request fixes youtube url fetch metadata issue. adding just a user-Agent field in the request header fixes the issue. i don't think it will break anything. if anything breaks please comment here

    opened by nafis042 4
  • Not able to use SwiftLinkPreview on Wix hosted sites

    Not able to use SwiftLinkPreview on Wix hosted sites

    Whenever I attempt to run SwiftLinkPreview on a website that is hosted by Wix.com I receive Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service in the console, the callback on the preview function never returns, and the CPU usage drives up like crazy.

    Is there a way to add/change request headers for the request?

    Some examples for you guys to try: https://www.yourgesture.com/ https://www.monicapackpilates.com/ https://www.yourgesture.com/ http://www.adammccain.org/

    opened by halinebr 4
  • A few questions + Example issues

    A few questions + Example issues

    Hello, Currently your example project seems to rely on 3 pods, but I was only able to find that out by looking at the readme file on that directory. It would be a lot easier if you provided a pod file, did basic integration with cocoa pods and then provided an .xcworkspace that people could use to run the sample project out the box.

    Also, i noticed you pushed a release removing the dependency on Alamofire, but the sample code still requires a pod that deals with alamofire and use it (for example: if let source: AlamofireSource = AlamofireSource(urlString: image) { on ViewController.swift:125).

    I've noticed that you have been very active recently on this project though so I'm just assuming it's still a work in progress. I am very interested in using this in a project I am working on but because you are in the process of making changes I wanted to ask you your opinions first.

    Seeing as you are in currently making changes, is it at a place where it would be ok to integrate now and update as you make changes, or are there things you are getting to or want to check out first? We are getting very close to testing the app for a production release, and want to get a sense if we should delay integration for a few days/a week until its a little more stable?

    P.S.: It's on obj-c project and some of my pods don't play nicely together with use_frameworks! so i'd have to manually integrate it, which is why I ask

    opened by gadu 4
  • Branch IO link is not working for URL Preview

    Branch IO link is not working for URL Preview

    @LeonardoCardoso I have implemented Branch IO Library for shorten URL. But when i am trying to generate preview using branch io link, it is not giving me original image in return. Can you please look into it.

    opened by MatellioDharmesh 0
  • fix/session-delegate

    fix/session-delegate

    Fixed f84740e01002e6806c03984b19bef0bb2d85e893

    SwiftLinkPreview destroys and recreates the URLSession, causing the user to lose control over the session he gave to SwiftLinkPreview (ie. his delegate will stop working & his session invalidation will be ignored).

    opened by lhunath 1
  • fix/base-url

    fix/base-url

    Fixed

    When a base URL and an image URL are combined but there is no trailing / in base and no leading slash in image, they get mashed together badly: https://base.comimages/image.jpg

    opened by lhunath 1
  • SwiftLinkPreview not providing image url for my URL

    SwiftLinkPreview not providing image url for my URL

    It works for some urls but it's failing to provide image url (sadhguru's photo) for below link. It randomly works sometimes.

    https://m.economictimes.com/news/politics-and-nation/its-about-going-global-not-just-about-counting-money-sadhguru/articleshow/71322013.cms

    opened by VickyiOSDeveloper 0
  • FIXED: Amazon links did not contain og tags with the default user agent

    FIXED: Amazon links did not contain og tags with the default user agent

    Action

    ADDED: 'userAgent' with a default value to preserve current behavior ADDED: 'googleBotUserAgent' static which can be used to override the default ADDED: unit tests for Amazon links and tested across several other major ecommerce sites

    NOTE: Not only does this fix OG tags for amazon.com links but the pages are way smaller due to Amazon optimizing for google search indexing (huge performance boost for preview response times)

    • Made user agent a configurable property to optimize for some websites (Amazon was the driver for this)
      • Issues: none
      • Commits: 546b86e12ca38617483c922d1d355fe0e785ff40
    opened by chadpav 1
Releases(3.4.0)
Generate and Preview Passbook Passes

Note: This project is no longer being maintained. Passbook is an iOS 6 feature that manages boarding passes, movie tickets, retail coupons, & loyalty

Nomad CLI 324 Dec 21, 2022
DGPreview - Make UIKit project enable preview feature of SwiftUI

DGPreview Make UIKit project enable preview feature of SwiftUI Requirements iOS

donggyu 5 Feb 14, 2022
Implementation of x-callback-url (Inter app communication) in swift

CallbackURLKit - Inter app communication Starting to integrate URL scheme in an app, why not be compliant with x-callback-url. CallbackURLKit.register

Eric Marchand 318 Nov 14, 2022
Swift implementation of the package url spec

PackageURL Swift implementation of the package url specification. Requirements Swift 5.3+ Usage import PackageURL let purl: PackageURL = "pkg:swift/a

Mattt 21 Jun 14, 2022
SMAP: Swiss Topo Map URL Generator

smap - Swiss Topo Map URL Generator Usage: smap [-b] <image-file-path> Reads fil

Jean-Nicolas 0 Dec 29, 2021
A Swift wrapper for URL bookmarks which allow a file to be located regardless of whether it is moved or renamed.

Bookmark A Swift wrapper for URL bookmarks which allow a file to be located regardless of whether it is moved or renamed. This class wraps Swift's URL

Darren Ford 8 Nov 3, 2022
Highlighter will magically find UI objects such as UILabel, UITextView, UITexTfield, UIButton

Highlighter Updates See CHANGELOG for details Intoduction ?? Highlight whatever you want! Highlighter will magically find UI objects such as UILabel,

Kyle Yi 932 Dec 12, 2022
Weather and forecasts for humans. Information you can act on.

Tropos Weather and forecasts for humans. Information you can act on. Most weather apps throw a lot of information at you but that doesn't answer the q

thoughtbot, inc. 1.5k Dec 28, 2022
Swift APIs for getting book information from popular web services

Swift APIs for getting book information from popular web services

Brian Dewey 1 Sep 25, 2021
FluxCapacitor makes implementing Flux design pattern easily with protocols and typealias.

FluxCapacitor makes implementing Flux design pattern easily with protocols and typealias. Storable protocol Actionable protocol Dispatch

Taiki Suzuki 123 Aug 23, 2022
RandomKit is a Swift framework that makes random data generation simple and easy.

RandomKit is a Swift framework that makes random data generation simple and easy. Build Status Installation Compatibility Swift Package Manager CocoaP

Nikolai Vazquez 1.5k Dec 29, 2022
Strong typed, autocompleted resources like images, fonts and segues in Swift projects

R.swift Get strong typed, autocompleted resources like images, fonts and segues in Swift projects Why use this? It makes your code that uses resources

Mathijs Kadijk 8.9k Jan 4, 2023
This is a app developed in Swift, using Object Oriented Programing, UIKit user interface programmatically, API Request and Kingfisher to load remote images

iOS NOW ⭐ This is a app developed in Swift, using Object Oriented Programing, UIKit user interface programmatically, API Request and Kingfisher to loa

William Tristão de Paula 1 Dec 7, 2021
Repository for all the programs and Code I would write in Swift.

Swift Programming Language This repository contains the program and codes I write in Swift About Swift Swift is a general-purpose, multi-paradigm, com

Kannan Jayachandran 2 Sep 21, 2022
All the reusable code that we need in each project

SwiftyUtils SwiftyUtils groups all the reusable code that we need to ship in each project. This framework contains: Extensions Protocols Structs Subcl

Tom Baranes 529 Dec 25, 2022
Returns true for all possible feature flags within the Twitter Mac app!

twitterinject Returns true for all possible feature flags within the Twitter Mac app! On Apple platforms, the default feature flags are present within

Spotlight 9 May 4, 2022
All the reusable code that we need in each project

SwiftyUtils SwiftyUtils groups all the reusable code that we need to ship in each project. This framework contains: Extensions Protocols Structs Subcl

Tom Baranes 529 Dec 25, 2022
Zip - A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip.

Zip A Swift framework for zipping and unzipping files. Simple and quick to use. Built on top of minizip. Usage Import Zip at the top of the Swift file

Roy Marmelstein 2.3k Jan 3, 2023