Linker
  • September 13, 2023

Linker

Lightweight way to handle internal and external deeplinks in Swift for iOS.

Installation


Dependency Managers

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate Linker into your Xcode project using CocoaPods, specify it in your Podfile:

source ‘https://github.com/CocoaPods/Specs.git’
platform :ios, ‘8.0’
use_frameworks!

pod ‘Linker’

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Linker into your Xcode project using Carthage, specify it in your Cartfile:

github “Linker”

Usage


(see sample Xcode project Demo)

The main thought of this framework is useful and convenient handling of external and internal URLs in your iOS application. Linker provides only one function to install your own handler to specific URL. A dependency between specific URL and your closure is based on scheme and host of each URL. That is you can configure miscellaneous behavior for different components of specific URL. You can split handling by query with different parameters and/or by pathfragment.

Realization details

On start of your application occurs swizzling methods in `UIApplication` and `UIApplicationDelegate` of your application. Original implementation exchanged on Linker’s implementation, where occur handle process. If Linker can’t handle specific URL, original implementation of this method will be called.

Swizzled functions:

UIApplication.shared - openURL:options:completionHandler:

UIApplication.shared - openURL: (deprecated since iOS 10.0)

UIApplication.shared.delegate - application:openURL:options:

UIApplication.shared.delegate - application:openURL:sourceApplication:annotation: (deprecated since iOS 9.0)

UIApplication.shared.delegate - application:handleOpenURL: (deprecated since iOS 9.0)

For complience with URL style, use format:

your_app_url_scheme://inapp_am/buy_subscription?type=subscription&productID=com.yourapp.7days_trial#test

where:

scheme – your_app_url_scheme,

host – inapp_am,

path – buy_subscription

query – type=subscription&productID=com.yourapp.7days_trial

fragment – test

If you don’t need configuration with complexed behavior, you can use URL just with host:

your_app_url_scheme://some_host_from_your_app

One special case – handle external URLs when app isn’t launched. You should install closure for specific URL and if this url will be in pair with UIApplicationLaunchOptionsKey in launchOptions – this url will be handled.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
let launchURL = URL(string: “linker://launchURL”)!

//if launchUrl equal launchOptions?[UIApplicationLaunchOptionsKey.url] -> this closure will be handled after app launch
Linker.handle(launchURL, closure: { url in
print(“Your URL has been handle!”)
})
return true
}

In other cases of usage you should set your handle closure for special URL before calling its from somewhere. If you have a few places where you need handle one specific url, you should reassign closure where latest set closure should have right context.

(!) Notice: Only the last sent closure for a unique URL (scheme + host) will be executed.

class ViewController: UIViewController {

let sourceURL = URL(string: “linker://viewcontroller?title=ExampleAlert&description=ExampleDescriptionAlert”)!

@IBAction func action(_ sender: Any) {
UIApplication.shared.open(sourceURL, options: [:], completionHandler: nil)
}

override func viewDidLoad() {
super.viewDidLoad()
Linker.handle(sourceURL) { url in

guard let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems! else {
return }
var title : String? = nil
var description: String? = nil

for item in queryItems {
if item.name == “title” {
title = item.value
}
if item.name == “description” {
description = item.value;
}
}

if let name = title, let message = description {
let alertVC = UIAlertController(title: name, message: message, preferredStyle: UIAlertControllerStyle.alert)
alertVC.addAction(UIAlertAction(title: “Cancel”, style: UIAlertActionStyle.cancel, handler: {action in
alertVC.dismiss(animated: true, completion: nil)
}))
self.present(alertVC, animated: false, completion: nil)
}
}
}
}

You can also find Objective-C version of this here.

GitHub


View Github

#closure #deeplinks #iosdevelopertools #iosswift #linker #scheme #swiftlibrary
YOU MIGHT ALSO LIKE...
CameraBackground

Features Both front and back camera supported. Flash modes: auto, on, off. Countdown timer. Tap to focus. Pinch to zoom. Usage  

DKCamera

Description A light weight & simple & easy camera for iOS by Swift. It uses CoreMotion framework to detect device orientation, so ...

HorizonSDK-iOS

Horizon SDK is a state of the art real-time video recording / photo shooting iOS library. Some of the features ...

LLSimpleCamera

LLSimpleCamera: A simple customizable camera - video recorder control LLSimpleCamera is a library for creating a customized camera - video ...

RSBarcodes_Swift

RSBarcodes allows you to read 1D and 2D barcodes using the metadata scanning capabilities introduced with iOS 7 and generate ...