Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/button/DeepLinkKit

A splendid route-matching, block-based way to handle your deep links.
https://github.com/button/DeepLinkKit

Last synced: about 1 month ago
JSON representation

A splendid route-matching, block-based way to handle your deep links.

Awesome Lists containing this project

README

        


DeepLink Kit


CI Status
Coverage Status
Version
License
Platform

## Overview

DeepLink 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.

[Full Documentation](https://github.com/button/DeepLinkKit/wiki/DeepLink-Kit-Integration-Guide)

[Guide to add Universal Links to your app](https://www.usebutton.com/developers/universal-links/)

## Check it out

Try the `DeepLinkKit` sample project by running the following command:
```ruby
pod try "DeepLinkKit"
```

## Installation

### CocoaPods
DeepLinkKit is available through [CocoaPods](http://cocoapods.org). To install
the library, simply add the following line to your Podfile:

```ruby
pod "DeepLinkKit"
```

### Carthage
To install via Carthage, add the following line to your `Cartfile`:

```text
github "button/DeepLinkKit"
```

### Other
If 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.

## Usage
Add deep link support to your app in 5 minutes or less following these simple steps.

Note: As of `1.0.0`, all imports should be updated to import ``.

**1. Make sure you have a URL scheme registered for your app in your Info.plist**

**2. Import DeepLinkKit**

```objc
#import
```

**3. Create an instance of `DPLDeepLinkRouter` in your app delegate**

````objc
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

self.router = [[DPLDeepLinkRouter alloc] init];

return YES;
}
````

**4. Register a route handler**

Objective-C
````objc
self.router[@"/log/:message"] = ^(DPLDeepLink *link) {
NSLog(@"%@", link.routeParameters[@"message"]);
};
````

Swift
````swift
self.router.register("/log/:message") { link in
if let link = link {
print("\(link.routeParameters["message"])")
}
}
````

**5. Pass incoming URLs to the router**

```objc
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {

return [self.router handleURL:url withCompletion:NULL];
}
```

**6. Passing `NSUserActivity` objects to the router** (optional)

_**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:_

```objc
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *))restorationHandler {

return [self.router handleUserActivity:userActivity withCompletion:NULL];
}
```

Learn more about the DeepLinkKit by reading our [Integration Guide](https://github.com/button/DeepLinkKit/wiki/DeepLink-Kit-Integration-Guide).

## Route Registration Examples

URLs coming into your app will be in a similar format to the following:
`:////`

When 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.

Say you have an incoming URL of `twitter://timeline`

```objc

// Matches the URL.
router[@"timeline"] = ^{ … }

// Does not match the URL.
router[@"/timeline"] = ^{ … }
```

In another example, a URL of `twitter://dpl.com/timeline`

```objc
// Matches the URL.
router[@"/timeline"] = ^{ … }

// Does not match the URL.
router[@"timeline"] = ^{ … }

```

You can also be scheme specific. If you support multiple URL schemes in your app, you can register routes specific to those schemes as follows:

An incoming URL of `scheme-one://timeline`

```objc
// Matches the URL.
router[@"scheme-one://timeline"] = ^{ … }

// Does not match the URL.
router[@"scheme-two://timeline"] = ^{ … }
```

### Regex Route Matching
You can use regex in your route patterns as well to give you maximum flexibility.

**Match any url**

_The following will match all incoming urls_
```objc
router[@".*"] ^(DPLDeepLink *link){
// This will match all incoming links
}
```
_**Note:** Routes are matched in the order they're registered so registering this route first will prevent all other more specific routes from matching._

**Match any url with a given scheme**

_The following will match all incoming links with the scheme, `myscheme://`_
```objc
router[@"myscheme://.*"] ^(DPLDeepLink *link){
// matches all urls with a scheme of `myscheme://`
}
```

**You can name your regex groups too**

_The following will match any url with a `host` of `trycaviar.com` and hand you `:path` in the route params._
```objc
// Given the url ‘https://trycaviar.com/manhattan/nicoletta-297`
router[@"trycaviar.com/:path(.*)"] ^(DPLDeepLink *link){
// `link[@"path"]` => @"manhattan/nicoletta-297"
}
```

**Match multiple path components**

_In this example, you'll get `:city` and `:restaurant` in the route params._
```objc
// Given the url ‘https://trycaviar.com/manhattan/nicoletta-297`
router[@"trycaviar.com/:city([a-zA-Z]+)/:restaurant(.*)"] ^(DPLDeepLink *link){
// `link[@"city"]` => @"manhattan"
// `link[@"restaurant"]` => @"nicoletta-297"
}
```
_If the restaurant ids are numbers, you could limit your matches as follows._
```objc
// Given the url ‘https://trycaviar.com/manhattan/297`
router[@"trycaviar.com/:city([a-zA-Z]+)/:restaurant([0-9])"] ^(DPLDeepLink *link){
// `link[@"city"]` => @"manhattan"
// `link[@"restaurant"]` => @"297"
}
```

**Name some groups and not others**
```objc
// Lets say the url is ‘https://trycaviar.com/manhattan/pizza/nicoletta-297`
router[@"trycaviar.com/:city([a-zA-Z]+)/[a-z]+/:restaurant(.*)"] ^(DPLDeepLink *link){
// `link[@"city"]` => @"manhattan"
// `link[@"restaurant"]` => @"nicoletta-297"
}
```
_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_

## AppLinks Support

Does 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.

```objc
router[@"/timeline"] = ^(DPLDeepLink *link) {
NSURL *referrerURL = link.referralURL;
NSString *someValue = link.extras[@"some-key"];
}
```

## Running the Demo

To 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).

There 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.

Run 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.

## Creating Deep Links

You 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.

In the first app:

```objc

DPLMutableDeepLink *link = [[DPLMutableDeepLink alloc] initWithString:@"app-two://categories"];
link[@"brew-types"] = @[@"Ale", @"Lager", @"Stout", @"Wheat"]
link[@"beers"] = @{
@"ales": @[
@{
@"name": @"Southern Tier Pumking Ale",
@"price": @799
},
@{
@"name": @"Sierra Nevada Celebration Ale",
@"price": @799
}
],
@"lagers": @[
...
],
...
}

[[UIApplication sharedApplication] openURL:link.URL];

```

In the second app:

```objc
router[@"categories"] = ^(DPLDeepLink *link) {
NSArray *brewTypes = link[@"brew-types"];
NSDictionary *beers = link[@"beers"];
}
```

## Authors

[Wes Smith](http://twitter.com/ioswes)

[Chris Maddern](http://twitter.com/chrismaddern)

## License

DeepLinkKit is available under the MIT license. See the LICENSE file for more info.

## Contributing

We'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:

Please make sure to follow our general coding style and add test coverage for new features!