button / deeplinkkit Goto Github PK
View Code? Open in Web Editor NEWA splendid route-matching, block-based way to handle your deep links.
License: MIT License
A splendid route-matching, block-based way to handle your deep links.
License: MIT License
We build a deep link routing mechanism to route incoming URIs to states within our apps, delegating responsibility to handlers for fetching and processing data and ViewControllers for presenting the resources we request.
Ideally we create and maintain one navigation system and this should be the URI -> app state mapping mechanism that we current delegate only to deep link handling.
Would love any comments on this... currently thinking something like:
The term SDK isn't really a good description of the 'weight' of this library so we wanted to drop it.
I use git clone
, pod install
; and then I have a proplem as below:
[!] Invalid `Podfile` file: [!] Unsupported options `{:exclusive=>true}` for target `SenderDemo`..
# from /private/var/folders/3y/q_lrv8s56wlc5kv0r8g_35nh0000gn/T/CocoaPods/Try/DeepLinkKit/Podfile:5
# -------------------------------------------
#
> target 'SenderDemo', :exclusive => true do
# pod 'DeepLinkKit', :path => '.'
# -------------------------------------------
A a few hours, I got a solution,it's a problem of cocoapods version.
Here is the solution of the issue.
I followed the step,change the podfile like below, it works. Maybe help others.
xcodeproj 'DeepLinkKit.xcodeproj', 'Test' => :debug
inhibit_all_warnings!
use_frameworks!
target 'SenderDemo' do
pod 'DeepLinkKit', :path => '.'
end
target 'ReceiverDemo' do
pod 'DeepLinkKit', :path => '.'
end
target 'ReceiverDemoSwift' do
pod 'DeepLinkKit', :path => '.'
end
target 'Tests' do
pod 'Spectra'
pod 'Expecta'
pod 'OCMock'
pod 'KIF'
end
What can i do if i want make a url pass by multiple router handler? A router handler can pass openURL request to another router handler?
Is it possible to use a regex in the scheme? Specifically to match:
one://www.host.com/callback
and
two://www.host.com/callback
but not
three://www.host.com/callback
I expected this to work but it doesn't:
(one|two)://www.host.com/callback
There seems to be a commit that added this but no mention in the docs.
Great framework, thanks! Is there a Swift demo or examples anywhere? It would be immensely appreciated and a step in the right direction for better Swift support.
Using the ReceiverDemo project as an example, which supports the scheme dpl://
, registering a route with a single, variable component, e.g. : log_message
causes a false match for this route when the URL dpl://
with nothing after the scheme is opened.
This is caused by the URL having a nil
host
and a nil
path
, and not accounting for that possibility in -[DPLRouteMatcher deepLinkWithURL:]
.
The following route registration in ReceiverDemo can demonstrate the issue:
self.router[@":log_message"] = ^(DPLDeepLink *link) {
NSLog(@"%@", link[@"log_message"]);
};
With this route registered, opening the URL dpl://hello
from e.g. Mobile Safari will cause the message hello
to be logged to the console, which works as expected. However, when opening the URL dpl://
from Mobile Safari, the same route is still matched, and (null)(null)
is logged to the console.
I have a fix incoming for this.
I have been upgrading to swift 3 for the passed hours i have put everything to work, except for DeepLinkKit. I am not able to find the function registerHandlerClass
anymore. The weird thing is it is in the DPLDeepLinkRouter.h
but when i command click on DeepLinkKit within my own code i get the following:
I am not sure that this is a problem I have or this is a problem in the pod. I have deleted the pods, deleted Podfile.lock, deleted derived data, cleaned my project, everything, but it still doesn't show up. Does anyone know what to do?
@import DeepLinkKit;
FTW
Hey guys,
First of all, thank you very much for this framework. It saves us so much time I can't thank you enough.
I know this is a delicate subject, there are those that are forward and against this, but do you guys plan on doing a Swift port of the framework?
I'd be surprised if this wasn't a common point of confusion... when looking at the sample project, and code such as:
self.router.registerHandlerClass(DPLMessageRouteHandler.self, forRoute: "/say/:title/:message")
Most will presume this translates to an URL such as my-app://say/someTitle/someMessage
... but in reality you must register the route without the leading slash
I'd propose making examples and README more explicit by showing corresponding external URL for each and every registration example, including, perhaps, comments in the sample source itself.
This is mostly a question (you can tag it as question), on what's the best approach to route a deeplink to an already instantiated UIViewController
.
Like having N
viewControllers on a UITabBarController
, I would like to have one of them to present itself or push another one to the stack.
I guess this could be done with a block like this, where I have available the existingTargetVC
:
self.router[@"link"] = ^(DPLDeepLink *link) {
[weakself.existingTargetVC doSomeForwardNavigation];
};
but I can't see any way to do it in a DPLRouteHandler
subclass. I would prefer to have that logic separated.
Any ideas?
Hi,
I would like to track a campaign code in the deep link to see where some of the users come from.
So I can have something like @"/account" but also @"/account/:campaign_code".
It would be nice to do that !
Use of the ivar in objectForKeyedSubscript
causes it to not work on the mutable subclass as the property is redefined to be mutable.
e.g...
DPLMutableDeepLink *mutableDeeplink = [[DPLMutableDeepLink alloc] initWithString:@"scheme://some/link"];
mutableDeepLink.queryParameters[@"this"] = @"that";
NSString *that = mutableDeepLink[@"this"];
// that is nil
On Xcode 8.3 beta (8W109m) compilation fails with the following error :
redefinition of module 'DeepLinkKit'
not sure if it is a DeepLinkKit issue or a Cocoapods issue ..
I was using this in my app, and I was having difficulties with using the subscripting to get/set block route handlers. This is because the subscript method returns id
, which in Swift was coming up as AnyObject
. It wasn't let me cast the return value to DPLRouteHandlerBlock
, because closures aren't objects.
There is probably some elegant solution that I didn't think of, but I just ended up writing a wrapper around it
I see this is written in Obj-C and all the documentation is in Obj-C. Does anybody know if there are swift 3 API's for this library? If not does anybody recommend any other libraries?
It would be better if there is support for multiple routes as array when defining routes, in case there are multiple ways to reach a url.
So a situation i came across is my domain.com/contact
was the same route as support.domain.com/request/new
so i had to create two routes like this.
self.router[@"contact"] = ^(DPLDeepLink *link) {
NSLog(@"DeepLink: Opening Support Page");
[weakself feedbackAction];
};
self.router[@"/requests/new/"] = ^(DPLDeepLink *link) {
NSLog(@"DeepLink: Opening Support Page");
[weakself feedbackAction];
};
If it was possible to create to something like this would be awesome:
self.router[@"contact", @"/requests/new/"] = ^(DPLDeepLink *link) {
NSLog(@"DeepLink: Opening Support Page");
[weakself feedbackAction];
};
The documentation mentions this protocol but it seems to be gone. =(
Please add Carthage support to your open source.
see Carthage/
Just a question to understand
According apple documentation we don't need to handle URL in both places openUrl
and didFinishLaunch
. Have you any trouble if using only openUrl
? Don't you have duplicated reaction if using both?
Your implementation of this method should open the specified URL and update its user interface accordingly. If your app had to be launched to open the URL, the app calls the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods first, followed by this method. The return values of those methods can be used to prevent this method from being called. (If the app is already running, only this method is called.)
Clean up DPLRegularExpression to know less about routes & delegate responsibility for pre-cleanup to DPLRouteMatcher (?)
CFURLCreateStringByAddingPercentEscapes
and CFURLCreateStringByReplacingPercentEscapesUsingEncoding
are deprecated as of iOS 9.0. The recommended replacements are -[NSString stringByAddingPercentEncodingWithAllowedCharacters:]
and -[NSString stringByRemovingPercentEncoding]
which are both available starting in iOS 7.
RFC 3986 Section 2.3 specifies the unreserved characters for URIs, namely ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~
. This is probably a reasonable set to pass to -stringByAddingPercentEncodingWithAllowedCharacters:
.
Pull request forthcoming…
hi, there is a such url
mailto:[email protected]?cc=[email protected]&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!
how to get the attributes
This may or may not be a controversial request, but it would be nice to have a handler for an empty path.
In my app, because of reasons, we have a url like http://ourapp.com/?certainId={id}
come in. I thought I could handle it with self.router.registerBlock(block, forRoute: "")
but it didn't catch it...
In the SenderDemo project, I had to replace the URLString with the payload target URL to trigger the alert modal in ReceiverDemo.
what do you think about creating chatting room here ?
I try to registering routes for this url http://www.mydomain.com/compare?ids=12345,67891
I register it as
router[@"http://www.mydomain.com/compare?ids=:firstID,:secondID"] = ^() {}
but it always gives me The passed URL does not match a registered route
The method - (void)placeTargetViewController:(UIViewController *)targetViewController inNavigationController:(UINavigationController *)navigationController
in DPLRouteHandler.m
prevents having multiple instances of the same view controller type in a navigation stack. It does that by popping all view controllers above a certain type of controller, and then replacing that controller with the new one.
Doing this messes up the navigation stack for the user when it comes to the back button. If they are looking at a controller, then they hit a deep link, and then hit back, they are not where they started before they hit the deep link.
Why not just always present the targetViewController() in top, or at least have an option to not wipe the navigation stack before presenting the targetViewController?
Queries may contain parameters like the following:
items[]=item1&items[]=item2
This should be interpreted as
NSArray *items = @[ @"item1", @"item2"];
Currently it is represented as:
@{ @"items[]" = @"item2" }
Related: #15
I want to pass an object that may used by more then one owners, like one model, in the parameter, observed by multiple view controller and all view controller should know the model changed.
Given 2 'host' routes "me" and "home":
self.router[@"me"] = ^(DPLDeepLink *link) { .. }
self.router[@"home"] = ^(DPLDeepLink *link) { .. }
entering via [protocol]://home
actually matches the first handler for "me" (since ho[me])
This can be worked around by swapping the order of the route handlers, but I figured it would be a good thing to fix the matching regexp.
➜ ios-deeplink-sdk git:(master) ✗ pod try DeepLinkSDK
Updating spec repositories
Trying DeepLinkSDK
Analyzing dependencies
Fetching podspec for `DeepLinkSDK` from `.`
Pre-downloading: `Specta` from `https://github.com/specta/specta.git`, commit `16949f4021a5560b1c78c439ad07d596c36cbac3`
[!] Unable to satisfy the following requirements:
- `DeepLinkSDK (from `.`)` required by `Podfile`
- `DeepLinkSDK (from `.`)` required by `Podfile`
- `DeepLinkSDK (= 0.1.0)` required by `Podfile.lock`
Opening '/private/tmp/CocoaPods/Try/DeepLinkSDK/DeepLinkSDK.xcworkspace'
The demo project will not build even after running this command.
This occurs both when running the command in an empty folder, and when running it in a cloned copy of the repo.
Please provide installation instructions for use without CocoaPods
Hi, first of all your library is great and now we are using it in second project, and we are more than happy.
But I have first problem, and I would like you to ask if I am doing something wrong or this type of route is not possible.
I have several deep links that look like application://something?somethingElse=value
and i wanted to handle route like ":type?:parameter"
, and extract value by using query.parameters
. But this block never gets called. It is ok when I do something?:parameters
something2:parameters
...
but it is quite too much code in my opinion.
Using 1.2.1
, I’m noticing an issue with routes that consist of a single path component failing to be handled when a trailing slash is included in the URL. This issue is not present when there is more than one path component in the registered route.
In Info.plist
, I have the following scheme, test
, set up so that my test app opens from Mobile Safari for URLs that begin with test://
.
This is the entirety of AppDelegate.m
in an otherwise empty test project, in which I demonstrate the issue:
#import "AppDelegate.h"
#import <DeepLinkKit/DeepLinkKit.h>
@interface AppDelegate ()
@property (nonatomic) DPLDeepLinkRouter *router;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.router = [[DPLDeepLinkRouter alloc] init];
self.router[@"search"] = ^(DPLDeepLink *link) {
// Called for `test://search`
// Not called for `test://search/` <-- THE ISSUE
NSLog(@"Handled Search Link");
};
self.router[@"settings/about"] = ^(DPLDeepLink *link) {
// Called for `test://settings/about`
// Called for `test://settings/about/`
NSLog(@"Handled settings/about Link");
};
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [self.router handleURL:url withCompletion:NULL];
}
@end
In summary, the issue shown in this example is that when attempting to open test://search/
in Mobile Safari the handler that logs the message "Handled Search Link" is not called.
There is a workaround to the issue, and that is to specify /?
to the end of the registered route to allow for an optional trailing slash. In the example above, that’d change the registration of search
to be:
self.router[@"search/?"] = ^(DPLDeepLink *link) {
// Called for `test://search`
// Called for `test://search/`
NSLog(@"Handled Search Link");
};
However, this is not ideal as it requires treating routes with different numbers of components differently.
I would like to use this library as an internal router, too. Has anyone used for this yet?
In my view, for this use case, it would be nice to have a method in DPLDeepLinkRouter
that returns the configured ViewController for a URL. To make it easier customizing transitions or even setting cached values on the target ViewController.
Another thing that may help is to separate the logic for matching and creating the DPLDeepLink
. With this I could subclass the DPLDeepLinkRouter
to make the above mentioned functionality available much easier.
Any thoughts on this? I could do it and create PR.
it seems that the first path component is stripped out in the route matcher, which is not what I would expect
i.e. given a route declared as
self.router[@"routeA/:param1/:param2/:param3"] = ^(DPLDeepLink *link) {
};
I would expect a URL in the form
scheme://routeA/param1/param2/param3
scheme://x/routeA/param1/param2/param3
Using v0.1.1 from cocoapods
Apparently @"".stringByRemovingPercentEncoding
returns nil
on iOS7. The following lines:
NSString *key = [[pairs firstObject] DPL_stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
paramsDict[key] = @"";
crash for e.g. customscheme:/whatever?#
for obvious reasons.
Is it possible to DeepLink to Apps which are not Installed yet?
while creating a DPLMutableDeepLink it's route parameters are null.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.