{"id":768,"url":"https://github.com/MaksimKurpa/Linker","last_synced_at":"2025-08-06T12:31:59.523Z","repository":{"id":56919828,"uuid":"121300249","full_name":"MaksimKurpa/Linker","owner":"MaksimKurpa","description":"🎯 Your easiest way to handle all URLs.","archived":false,"fork":false,"pushed_at":"2018-05-04T16:51:58.000Z","size":137,"stargazers_count":139,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-21T00:02:01.211Z","etag":null,"topics":["closure","deeplinks","ios-developer-tools","ios-swift","linker","scheme","swift-library"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MaksimKurpa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-12T20:50:50.000Z","updated_at":"2024-05-27T06:28:01.000Z","dependencies_parsed_at":"2022-08-20T21:50:18.126Z","dependency_job_id":null,"html_url":"https://github.com/MaksimKurpa/Linker","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaksimKurpa%2FLinker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaksimKurpa%2FLinker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaksimKurpa%2FLinker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaksimKurpa%2FLinker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MaksimKurpa","download_url":"https://codeload.github.com/MaksimKurpa/Linker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228898284,"owners_count":17988652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["closure","deeplinks","ios-developer-tools","ios-swift","linker","scheme","swift-library"],"created_at":"2024-01-05T20:15:30.911Z","updated_at":"2024-12-09T13:30:35.518Z","avatar_url":"https://github.com/MaksimKurpa.png","language":"Swift","funding_links":[],"categories":["App Routing","Libs","Architecture and State","App Routing [🔝](#readme)"],"sub_categories":["App Routing","Other free courses","Getting Started"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"Linker/Configs/logo.png\"/\u003e\n  \u003ch3 align=\"center\"\u003eLinker\u003c/h3\u003e\n  \u003cp align=\"center\"\u003eLightweight way to handle internal and external deeplinks in Swift for iOS.\u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://swift.org\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/aa026700c1aea948646712ee9108a663aa59941b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53776966742d342e782d626c75652e737667\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/MaksimKurpa/Linker\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/p/Linker.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://travis-ci.org/MaksimKurpa/Linker\"\u003e\u003cimg src=\"https://travis-ci.org/MaksimKurpa/Linker.svg?branch=master\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/MaksimKurpa/Linker\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/v/Linker.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\"\u003e\u003c/a\u003e\n\t\u003ca href=\"https://raw.githubusercontent.com/Linker/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/l/Linker.svg\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\n---\n\n\n## Installation\n\n### Dependency Managers\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eCocoaPods\u003c/strong\u003e\u003c/summary\u003e\n\n[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:\n\n```bash\n$ gem install cocoapods\n```\n\nTo integrate Linker into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '8.0'\nuse_frameworks!\n\npod 'Linker'\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eCarthage\u003c/strong\u003e\u003c/summary\u003e\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.\n\nYou can install Carthage with [Homebrew](http://brew.sh/) using the following command:\n\n```bash\n$ brew update\n$ brew install carthage\n```\n\nTo integrate Linker into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"Linker\"\n```\n\n\u003c/details\u003e\n\n## Usage\n\n(see sample Xcode project Demo)\n\nThe 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 `path`, `fragment`.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eRealization details\u003c/strong\u003e\u003c/summary\u003e\nOn 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.\n\nSwizzled functions:\n\n`UIApplication.shared - openURL:options:completionHandler:`\n\n`UIApplication.shared - openURL:` (deprecated since iOS 10.0)\n\n`UIApplication.shared.delegate - application:openURL:options:`\n\n`UIApplication.shared.delegate - application:openURL:sourceApplication:annotation:` (deprecated since iOS 9.0)\n\n`UIApplication.shared.delegate - application:handleOpenURL:` (deprecated since iOS 9.0) \u003c/details\u003e\n\n\nFor complience with URL style, use format:\n\n`your_app_url_scheme://inapp_am/buy_subscription?type=subscription\u0026productID=com.yourapp.7days_trial#test`\n\nwhere:\n\nscheme   - `your_app_url_scheme`,\n\nhost     - `inapp_am`,\n\npath     - `buy_subscription`\n\nquery    - `type=subscription\u0026productID=com.yourapp.7days_trial`\n\nfragment - `test`\n\nIf you don't need configuration with complexed behavior, you can use URL just with `host`:\n\n`your_app_url_scheme://some_host_from_your_app`\n\nOne 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.\n\n```Swift\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool \n{\n    let launchURL = URL(string: \"linker://launchURL\")!\n    \n    //if launchUrl equal launchOptions?[UIApplicationLaunchOptionsKey.url] -\u003e this closure will be handled after app launch\n    Linker.handle(launchURL, closure: { url in\n\tprint(\"Your URL has been handle!\")\n    })\n        return true\n    }\n```\nIn 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`.\n\n\n\u003ch5\u003e (!) Notice: Only the last sent closure for a unique URL (scheme + host) will be executed.\u003c/h5\u003e\n\n```Swift\nclass ViewController: UIViewController {\n    \n    let sourceURL = URL(string: \"linker://viewcontroller?title=ExampleAlert\u0026description=ExampleDescriptionAlert\")!\n\n    @IBAction func action(_ sender: Any) {\n        UIApplication.shared.open(sourceURL, options: [:], completionHandler: nil)\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        Linker.handle(sourceURL) { url in\n        \n            guard let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems! else {\n                return }\n            var title : String? = nil\n            var description: String? = nil\n            \n            for item in queryItems {\n                if item.name == \"title\" {\n                    title = item.value\n                }\n                if item.name == \"description\" {\n                    description = item.value;\n                }\n            }\n            \n            if let name = title, let message = description {\n                let alertVC = UIAlertController(title: name, message: message, preferredStyle: UIAlertControllerStyle.alert)\n                alertVC.addAction(UIAlertAction(title: \"Cancel\", style: UIAlertActionStyle.cancel, handler: {action in\n                    alertVC.dismiss(animated: true, completion: nil)\n                }))\n                self.present(alertVC, animated: false, completion: nil)\n            }\n        }\n    }\n}\n```\nYou can also find Objective-C version of this [here](https://github.com/MaksimKurpa/DeepLinksHandler).\n\n## Contributing\n\nIssues and pull requests are welcome!\n\n## Author\n\nMaksim Kurpa - [@maksim_kurpa](https://twitter.com/maksim_kurpa)\n\n## License\n\nThis code is distributed under the terms and conditions of the [MIT license](https://raw.githubusercontent.com/MaksimKurpa/Linker/master/LICENSE). \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMaksimKurpa%2FLinker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMaksimKurpa%2FLinker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMaksimKurpa%2FLinker/lists"}