{"id":763,"url":"https://github.com/button/DeepLinkKit","last_synced_at":"2025-07-30T19:32:07.198Z","repository":{"id":24339086,"uuid":"27736734","full_name":"button/DeepLinkKit","owner":"button","description":"A splendid route-matching, block-based way to handle your deep links.","archived":false,"fork":false,"pushed_at":"2024-05-30T14:20:30.000Z","size":478,"stargazers_count":3443,"open_issues_count":22,"forks_count":281,"subscribers_count":113,"default_branch":"master","last_synced_at":"2024-10-29T15:34:10.129Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","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/button.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2014-12-08T21:44:58.000Z","updated_at":"2024-10-27T02:26:20.000Z","dependencies_parsed_at":"2022-08-08T08:15:36.107Z","dependency_job_id":"bb865dfe-88ef-4b63-8f22-77f0eb99db19","html_url":"https://github.com/button/DeepLinkKit","commit_stats":{"total_commits":266,"total_committers":38,"mean_commits":7.0,"dds":0.5451127819548872,"last_synced_commit":"6eaecd70a52a0077b8eca643b91539a6f4420d30"},"previous_names":["usebutton/ios-deeplink-sdk"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/button%2FDeepLinkKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/button%2FDeepLinkKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/button%2FDeepLinkKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/button%2FDeepLinkKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/button","download_url":"https://codeload.github.com/button/DeepLinkKit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224880425,"owners_count":17385370,"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":[],"created_at":"2024-01-05T20:15:30.799Z","updated_at":"2024-12-04T19:31:54.285Z","avatar_url":"https://github.com/button.png","language":"Objective-C","funding_links":[],"categories":["App Routing","Objective-C","URL Scheme","Foundation","iOS"],"sub_categories":["Other free courses","Getting Started","Deeplink"],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://cloud.githubusercontent.com/assets/10621371/7642874/8c90f72a-fa62-11e4-9092-dfff96c24f01.png\" width=\"392\"/\u003e\n\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eDeepLink Kit\u003c/h1\u003e\n\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://travis-ci.org/button/DeepLinkKit\"\u003e\u003cimg src=\"http://img.shields.io/travis/button/DeepLinkKit.svg?style=flat\" alt=\"CI Status\" /\u003e\u003c/a\u003e\n\u003ca href='https://coveralls.io/github/button/DeepLinkKit?branch=master'\u003e\u003cimg src='https://coveralls.io/repos/github/button/DeepLinkKit/badge.svg?branch=master' alt='Coverage Status' /\u003e\u003c/a\u003e\n\u003ca href=\"http://cocoadocs.org/docsets/DeepLinkKit\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/v/DeepLinkKit.svg?style=flat\" alt=\"Version\" /\u003e\u003c/a\u003e\n\u003ca href=\"http://cocoadocs.org/docsets/DeepLinkKit\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/l/DeepLinkKit.svg?style=flat\" alt=\"License\" /\u003e\u003c/a\u003e\n\u003ca href=\"http://cocoadocs.org/docsets/DeepLinkKit\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/p/DeepLinkKit.svg?style=flat\" alt=\"Platform\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Overview\n\nDeepLink Kit is a splendid route-matching, block-based way to handle your deep links. Rather than decide how to format your URLs, parse them, pass data, and navigate to specific content or perform actions, this library and a few lines of code will get you on your way.\n\n[Full Documentation](https://github.com/button/DeepLinkKit/wiki/DeepLink-Kit-Integration-Guide)\n\n[Guide to add Universal Links to your app](https://www.usebutton.com/developers/universal-links/)\n\n## Check it out\n\nTry the `DeepLinkKit` sample project by running the following command:\n```ruby\npod try \"DeepLinkKit\"\n```\n\n## Installation\n\n### CocoaPods\nDeepLinkKit is available through [CocoaPods](http://cocoapods.org). To install\nthe library, simply add the following line to your Podfile:\n\n```ruby\npod \"DeepLinkKit\"\n```\n\n### Carthage\nTo install via Carthage, add the following line to your `Cartfile`:\n\n```text\ngithub \"button/DeepLinkKit\"\n```\n\n### Other\nIf you don't use CocoaPods or Carthage, you can include all of the source files from the [DeepLinkKit directory](https://github.com/button/DeepLinkKit/tree/master/DeepLinkKit) in your project.\n\n## Usage\nAdd deep link support to your app in 5 minutes or less following these simple steps.\n\n\u003cem\u003e\u003cstrong\u003eNote:\u003c/strong\u003e As of `1.0.0`, all imports should be updated to import `\u003cDeepLinkKit/DeepLinkKit.h\u003e`.\u003c/em\u003e\n\n\n\n**1. Make sure you have a URL scheme registered for your app in your Info.plist**\n\u003cimg src=\"https://cloud.githubusercontent.com/assets/1057077/5710380/8d913f3e-9a6f-11e4-83a2-49f6564d7a8f.png\" width=\"410\" /\u003e\n\n**2. Import DeepLinkKit**\n\n```objc\n#import \u003cDeepLinkKit/DeepLinkKit.h\u003e\n```\n\n**3. Create an instance of `DPLDeepLinkRouter` in your app delegate**\n\n````objc\n- (BOOL)application:(UIApplication *)application\n        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n\n  self.router = [[DPLDeepLinkRouter alloc] init];\n\n  return YES;\n}\n````\n\n**4. Register a route handler**\n\nObjective-C\n````objc\nself.router[@\"/log/:message\"] = ^(DPLDeepLink *link) {\n  NSLog(@\"%@\", link.routeParameters[@\"message\"]);\n};\n````\n\nSwift\n````swift\nself.router.register(\"/log/:message\") { link in\n    if let link = link {\n        print(\"\\(link.routeParameters[\"message\"])\")\n    }\n}\n````\n\n**5. Pass incoming URLs to the router**\n\n```objc\n- (BOOL)application:(UIApplication *)application\n            openURL:(NSURL *)url\n  sourceApplication:(NSString *)sourceApplication\n         annotation:(id)annotation {\n\n  return [self.router handleURL:url withCompletion:NULL];\n}\n```\n\n**6. Passing `NSUserActivity` objects to the router** (optional)\n\n_**Note:** If your application supports [Apple's new universal links](https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html#//apple_ref/doc/uid/TP40016198-DontLinkElementID_2), implement the following in your app delegate:_\n\n```objc\n- (BOOL)application:(UIApplication *)application\n        continueUserActivity:(NSUserActivity *)userActivity\n          restorationHandler:(void (^)(NSArray *))restorationHandler {\n\n    return [self.router handleUserActivity:userActivity withCompletion:NULL];\n}\n```\n\n\n\nLearn more about the DeepLinkKit by reading our [Integration Guide](https://github.com/button/DeepLinkKit/wiki/DeepLink-Kit-Integration-Guide).\n\n## Route Registration Examples\n\nURLs coming into your app will be in a similar format to the following:\n`\u003cscheme\u003e://\u003chost\u003e/\u003cpath-component\u003e/\u003cpath-component\u003e`\n\nWhen registering routes, it's important to note that the first forward slash in your registered route determines the start of the path to be matched. A route component before the first forward slash will be considered to be the host.\n\nSay you have an incoming URL of `twitter://timeline`\n\n```objc\n\n// Matches the URL.\nrouter[@\"timeline\"] = ^{ … }\n\n// Does not match the URL.\nrouter[@\"/timeline\"] = ^{ … }\n```\n\nIn another example, a URL of `twitter://dpl.com/timeline`\n\n```objc\n// Matches the URL.\nrouter[@\"/timeline\"] = ^{ … }\n\n// Does not match the URL.\nrouter[@\"timeline\"] = ^{ … }\n\n```\n\nYou can also be scheme specific. If you support multiple URL schemes in your app, you can register routes specific to those schemes as follows:\n\nAn incoming URL of `scheme-one://timeline`\n\n```objc\n// Matches the URL.\nrouter[@\"scheme-one://timeline\"] = ^{ … }\n\n// Does not match the URL.\nrouter[@\"scheme-two://timeline\"] = ^{ … }\n```\n\n### Regex Route Matching\nYou can use regex in your route patterns as well to give you maximum flexibility.\n\n**Match any url**\n\n_The following will match all incoming urls_\n```objc\nrouter[@\".*\"] ^(DPLDeepLink *link){\n  // This will match all incoming links\n}\n```\n_**Note:** Routes are matched in the order they're registered so registering this route first will prevent all other more specific routes from matching._\n\n**Match any url with a given scheme**\n\n_The following will match all incoming links with the scheme, `myscheme://`_\n```objc\nrouter[@\"myscheme://.*\"] ^(DPLDeepLink *link){\n  // matches all urls with a scheme of `myscheme://`\n}\n```\n\n**You can name your regex groups too**\n\n_The following will match any url with a `host` of `trycaviar.com` and hand you `:path` in the route params._\n```objc\n// Given the url ‘https://trycaviar.com/manhattan/nicoletta-297`\nrouter[@\"trycaviar.com/:path(.*)\"] ^(DPLDeepLink *link){\n  // `link[@\"path\"]` =\u003e @\"manhattan/nicoletta-297\"\n}\n```\n\n**Match multiple path components**\n\n_In this example, you'll get `:city` and `:restaurant` in the route params._\n```objc\n// Given the url ‘https://trycaviar.com/manhattan/nicoletta-297`\nrouter[@\"trycaviar.com/:city([a-zA-Z]+)/:restaurant(.*)\"] ^(DPLDeepLink *link){\n  // `link[@\"city\"]` =\u003e @\"manhattan\"\n  // `link[@\"restaurant\"]` =\u003e @\"nicoletta-297\"\n}\n```\n_If the restaurant ids are numbers, you could limit your matches as follows._\n```objc\n// Given the url ‘https://trycaviar.com/manhattan/297`\nrouter[@\"trycaviar.com/:city([a-zA-Z]+)/:restaurant([0-9])\"] ^(DPLDeepLink *link){\n  // `link[@\"city\"]` =\u003e @\"manhattan\"\n  // `link[@\"restaurant\"]` =\u003e @\"297\"\n}\n```\n\n**Name some groups and not others**\n```objc\n// Lets say the url is ‘https://trycaviar.com/manhattan/pizza/nicoletta-297`\nrouter[@\"trycaviar.com/:city([a-zA-Z]+)/[a-z]+/:restaurant(.*)\"] ^(DPLDeepLink *link){\n  // `link[@\"city\"]` =\u003e @\"manhattan\"\n  // `link[@\"restaurant\"]` =\u003e @\"nicoletta-297\"\n}\n```\n_The above would match ‘https://trycaviar.com/manhattan/pizza/nicoletta-297’ but not ‘https://trycaviar.com/manhattan/PIZZA/nicoletta-297’ or ‘https://trycaviar.com/manhattan/pizza-places/nicoletta-297’, etc_\n\n## AppLinks Support\n\nDoes your app support AppLinks? You can easily handle incoming AppLinks by importing the AppLinks category `DPLDeepLink+AppLinks`. The AppLinks category provides convenience accessors to all AppLinks 1.0 properties.\n\n```objc\nrouter[@\"/timeline\"] = ^(DPLDeepLink *link) {\n  NSURL *referrerURL  = link.referralURL;\n  NSString *someValue = link.extras[@\"some-key\"];\n}\n```\n\n## Running the Demo\n\nTo run the example project, run `pod try DeepLinkKit` in your terminal. You can also clone the repo, and run `pod install` from the project root. If you don't have CocoaPods, begin by [follow this guide](http://guides.cocoapods.org/using/getting-started.html).\n\nThere are two demo apps, `SenderDemo`, and `ReceiverDemo`. `ReceiverDemo` has some registered routes that will handle specific deep links. `SenderDemo` has a couple actions that will deep link out to `ReceiverDemo` for fulfillment.\n\nRun the`SenderDemo` build scheme first, then stop the simulator and switch the build scheme to `ReceiverDemo` and run again. Now you can switch back to the `SenderDemo` app in the simulator and tap on one of the actions.\n\n\n## Creating Deep Links\n\nYou can also create deep links with `DPLMutableDeepLink`. Between two `DeepLinkKit` integrated apps, you can pass complex objects via deep link from one app to another app and easily get that object back on the other end.\n\nIn the first app:\n\n```objc\n\nDPLMutableDeepLink *link = [[DPLMutableDeepLink alloc] initWithString:@\"app-two://categories\"];\nlink[@\"brew-types\"] = @[@\"Ale\", @\"Lager\", @\"Stout\", @\"Wheat\"]\nlink[@\"beers\"] = @{\n  @\"ales\": @[\n    @{\n        @\"name\": @\"Southern Tier Pumking Ale\",\n        @\"price\": @799\n    },\n    @{\n        @\"name\": @\"Sierra Nevada Celebration Ale\",\n        @\"price\": @799\n    }\n  ],\n  @\"lagers\": @[\n     ...\n  ],\n  ...\n}\n\n[[UIApplication sharedApplication] openURL:link.URL];\n\n```\n\nIn the second app:\n\n```objc\nrouter[@\"categories\"] = ^(DPLDeepLink *link) {\n  NSArray *brewTypes  = link[@\"brew-types\"];\n  NSDictionary *beers = link[@\"beers\"];\n}\n```\n\n\n## Authors\n\n[Wes Smith](http://twitter.com/ioswes)\u003cbr /\u003e\n[Chris Maddern](http://twitter.com/chrismaddern)\n\n## License\n\nDeepLinkKit is available under the MIT license. See the LICENSE file for more info.\n\n## Contributing\n\nWe'd love to see your ideas for improving this library. The best way to contribute is by submitting a pull request. We'll do our best to respond to you as soon as possible. You can also submit a new Github issue if you find bugs or have questions. :octocat:\n\nPlease make sure to follow our general coding style and add test coverage for new features!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbutton%2FDeepLinkKit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbutton%2FDeepLinkKit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbutton%2FDeepLinkKit/lists"}