I would like to handle a url like: http://www.something.com/product/3/ in this way:
If you have the App installed => handle it with the App.
Else => handle it with safari.
Is it this possible?
The idea is I can send that url via email and if the receiver has the app installed, then the app raises up and do something, and if not installed just open it via safari.
I know about the custom schemes, which work fine in the app but they obviously don't work in safari because they are not http protocol.
1) Create a custom URL scheme in your app. Follow the link if you don't know how to create a custom URL scheme: http://www.idev101.com/code/Objective-C/custom_url_schemes.html
2) Then add following script to the URLs that you want your app to open.
<script language="javascript" type="text/javascript">
var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
var appUrlScheme = "myappscheme://" + document.URL;
if (iOS) {
window.open(appUrlScheme, "_self");
}
</script>
The script is self explanatory, if its an iOS device then it simply tries to open current url with your custom url scheme i.e. myappscheme://whateverurl.com'. If you app is installed on the device then iOS is going to launch your app and pass this URL tohandleOpenURLfunction, otherwise mobile safari will silently ignorewindow.open` call and your webpage will load as normal:
3) Implement handleOpenURL callback method in your AppDelegate to handle the URL:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSLog(#"url: %#", url);
NSLog(#"query string: %#", [url query]);
NSLog(#"host: %#", [url host]);
NSLog(#"url path: %#", [url path]);
//REDIRECT USER TO A VIEW CONTROLLER
return YES;
}
Yes you can do by using URL Scheme,
First create your own custom url scheme in Info.plist file
Add a new row by going to the menu and clicking Editor > Add Item. Set up a URL Types item by adding a new item. Expand the URL Types key, expand Item 0, and add a new item, “URL schemes”. Fill in “readtext” for Item 0 of “URL schemes” and your company identifier for the “URL Identifier”.
Then parse your url for different url for same url scheme to open your app with different screens.. Here i have shown only alert, use to open your specific page as per your link.. And if the app is not installed then it will open in web browser.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// Display text
UIAlertView *alertView;
NSString *text = [[url host] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
alertView = [[UIAlertView alloc] initWithTitle:#"Text" message:text delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
return YES;
}
application:handleOpenURL: (used for earlier iOS 4.1)
application:openURL:sourceApplication:annotation: (used for later iOS 4.1).
No that is not possible.
However you can include in the mail both links:
To open it in safari as normal website: http://www.somewebsite.com
To open the app using custom urls: yourapp://
Related
I have some functionality in my app. If user clicks on referral link from outside of the app(from messages,whatsapp etc), it will navigating to app and I am making register url with reference code. After that I am navigating to register screen and loading that register url in web view and it displaying referral code in required field.(this is all happening if our app installed in iPhone device)
But what I need is when app is not installed and we click on referral link-
If app is not installed then it should redirect to appstore and once the app is installed it should redirect to register screen with referral code in it.
-(void)handelReferral:(NSString *)strReferral{
if ([[SuperClass sharedSingletonSuperClass] checkifStringNotNull:strReferral]) {
NSString *strReferralCode;
if ([strReferral rangeOfString:#"ref/"].location != NSNotFound) {
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:[NSURL URLWithString:strReferral]
resolvingAgainstBaseURL:NO];
NSArray *queryItems = urlComponents.queryItems;
if (queryItems.count > 0) {
NSString *queryValue = [self valueForKey:#"al" fromQueryItems:queryItems];
strReferralCode = [queryValue lastPathComponent];
} else {
strReferralCode = strReferral.lastPathComponent;
}
NSString *strRegisterUrl = [ConfigurationManager shared].data.strRegisterUrl;
NSString *finalRefUrl = [NSString stringWithFormat:#"%#?utm_campaign=app_refferal_ref/ref/%#&utm_medium=app&utm_source=app_refferal",strRegisterUrl,strReferralCode];
if ([self.ReferralDelegate respondsToSelector:#selector(userClickedOnReferralDelegate)]) {
[self.ReferralDelegate userClickedOnReferralDelegate];
} else {
if ([[SuperClass sharedSingletonSuperClass]isPhoneNumberIsAvailable] == false) {
NSLog(#"finalRefUrl=====%#",finalRefUrl);
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"isComingFromRef"];
[[NSUserDefaults standardUserDefaults] setValue:finalRefUrl forKey:#"finalRefUrl"];
[[NSUserDefaults standardUserDefaults] synchronize];
[ServiceGeneralNotifications sharedSingleton].isUserTryingToLogin = YES;
[[SuperClass sharedSingletonSuperClass] pushToLoginScreen];
}
}
}
}
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
[self callServiceToPostCampaignDataWithURL:userActivity.webpageURL];
if ([[SuperClass sharedSingletonSuperClass]checkifStringNotNull:[userActivity.webpageURL absoluteString]]) {
[self handelReferral:[userActivity.webpageURL absoluteString]];
}
Use Firebase Dynamic links
With Dynamic Links, your users get the best available experience for the platform they open your link on. If a user opens a Dynamic Link on iOS or Android, they can be taken directly to the linked content in your native app. If a user opens the same Dynamic Link in a desktop browser, they can be taken to the equivalent content on your website.
In addition, Dynamic Links work across app installs: if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link.
I followed the dynamic link for ios video and tutorials. After everything is setup, when I click on the dynamic link https://a75xd.app.goo.gl/2rkG , I get null in the completion method of the handleUniversalLink:userActivity.webpageURL.
But when I use the full URL as found in link details in firebase console, I get the link parameters perfectly.
https://a75xd.app.goo.gl/?link=http://onesnaps.com&isi=999758235&ibi=com.onesnaps&ius=osScheme&utm_source=google&utm_medium=cpc&utm_campaign=spring
i faced this issue and resolve it by the following steps
1- delete the app
2- open the dynamic link from massages or email or note
3- the dynamic link should be go to the app store
4- go to Xcode and rebuild the app
5- reopen the dynamic link and the dynamicLinks.url will return value
Try this one.
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
NSURL *url = userActivity.webpageURL;
FIRDynamicLinks *links = [FIRDynamicLinks dynamicLinks];
if([links matchesShortLinkFormat:url])
{
[links resolveShortLink:url completion:^(NSURL * _Nullable url, NSError * _Nullable error)
{
NSString *message =
[NSString stringWithFormat:#"Deep link \n:%#",
url];
[[[UIAlertView alloc] initWithTitle:#"Deep-link Data"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] show];
}];
return YES;
}
return false;
}
I have imported liveSDK with pods, my app is set.
This is how I login in swift (I've implemented LiveAuthDelegate too):
var live = LiveConnectClient(clientId: ClientID, delegate: self)
live.login(self, scopes: Scopes, delegate: self)
I get the login and password screen, I sign in with my credentials.
I get the permissions view where I can say yes or no to the asked permissions
I click yes
I get blank page... instead of being redirected back to my app
Any ideas ?
please help
EDIT: i think i am redirected to some page like https://login.live.com/oauth20_desktop.srf?error=server_error&lc=1033 this site and its blank? what could be the reason ?
I tried logging the url in the LiveSDK, but its crashing the app on NSLog
#pragma mark UIWebViewDelegate methods
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest: (NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
NSLog([url absoluteString]);
if ([[url absoluteString] hasPrefix: _endUrl])
{
[_delegate authDialogCompletedWithResponse:url];
}
// Always return YES to work around an issue on iOS 6 that returning NO may cause
// next Login request on UIWebView to hang.
return YES;
}
In the end i happened to add a retaint:
_liveConnectClientCore = [[[LiveConnectClientCore alloc] initWithClientId:clientId
scopes:[LiveAuthHelper normalizeScoers:scopes]
delegate:delegate
userState:userState] retain];
I have three apps that upload files to Dropbox. Same code for all three. They all share the same folder so I've used same secret key etc
Heres where it gets weird
1. All was fine for few months
2. Now on apps 2 and 3 when the user tries to log in it opens the first app?
3. Logging out and in, no help, just says Theres a an error connecting to Dropbox and to try later
What ive tried
Creating seprate secret keys etc for all three apps rathe rthan sharing the same, still get the same behaviour?
Some research on this suggested that Dropbox has changed the way it links to users accounts through applications and remins linked even if you delete the app? Has anyone else got any experience with this?
Appdelegate
NSString* appKey = #"00000000000";
NSString* appSecret = #"0000000000";
NSString *root = kDBRootAppFolder;
DBSession* session =
[[DBSession alloc] initWithAppKey:appKey appSecret:appSecret root:root];
session.delegate = self; // DBSessionDelegate methods allow you to handle re-authenticating
[DBSession setSharedSession:session];
[DBRequest setNetworkRequestDelegate:self];
Button Handler in viewController
LogCmd();
self.publishButtonPressed = YES;
if (![[DBSession sharedSession] isLinked]) {
[self loginLogoutButtonPressed:nil];
} else {
DBRestClient *restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
restClient.delegate = self;
NSError *error = nil;
NSString *filePath = [ICUtils pathForDocument:self.fileName];
[self.pdfData writeToFile:filePath options:0 error:&error];
if (nil == error) {
[restClient uploadFile:self.fileName
toPath:#"/"
withParentRev:nil
fromPath:filePath];
} else {
[ICUtils raiseAlertWithTitle:#"An error occurred" message:[error localizedDescription]];
}
}
}
Note works ok on the simulator, problem is only present on device
That is because you are using the same key for multiple applications. The Dropbox app is communicating with your app through a custom URL scheme - to launch your app (because there is no other way to launch apps programmatically on iOS).
In other words, the Dropbox app tells the system to open "db-yoursecretkey://somemessage" which opens the registered app for that custom URL scheme. Unfortunately, all of your apps use the same custom scheme as they are all using the same key, so the system just picks one: most likely the first one.
However, you can grant your apps access to all folders in dropbox, thus effectively sharing folders. So it's not really necessary to have all three apps using the same key.
Is it possible to download and add a passbook from within a webview without modifying the app to support the new MIME type or unknown MIME types like Sparrow did?
I have a news ios app with a webview. In the webview I display the news items and a banner. When you click the banner I want to open a url to a .pkpass file and add it to my passbook. Instead I get a FrameLoadInterrupted error and nothing visible happens.
If I open the url from safari this works fine, chrome, since earlier this week (version 23) also opens the url like intended.
Is this some weird strategy from Apple maybe? not allowing this MIME type to properly open from a webview?
My best bet is that the UIWebView is just not capable of handling the Passbook passes. You could however try and catch the downloading in the UIWebViewDelegate method -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType.
What I mean to say is that you have to handle this part your self, since the http://passkit.com/samples/ I used does not return an url which ends pkpass thus it is totally depended on how you request the passbook files.
If you do in include the .pkpass extension you can check for the extension in the request.
If you know what kind of URL the passbook file is at you write your own download code here and pass it to passbook via the passbook api.
There does not seem to be any great on fix for this, you could load the failed ULR in safari:
- (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"Webview: %#", error);
if ([error.domain isEqualToString:#"WebKitErrorDomain"] && error.code == 102) {
NSString *failedURL = [error.userInfo objectForKey:NSURLErrorFailingURLStringErrorKey];
if (failedURL == nil) {
return;
}
NSURL *url = [NSURL URLWithString:failedURL];
[[UIApplication sharedApplication] openURL:url];
}
}
But this is just really bad coding.
Okay, talked to the engineers at WWDC and this is a know bug in UIWebView but Apple probably won't fix it because they're encouraging people to adopt the new SFSafariViewController. We did come up with a hack to fix it should you need to support iOS 6-8:
Add the PassKit framework to the project if it isn't already.
#import <PassKit/PassKit.h>
Set up a delegate for the UIWebView (for example the view controller launching the UIWebView)
<UIWebViewDelegate>
Add a class variable to cache the UIWebView requests
NSURLRequest *_lastRequest;
Set the delegate
self.webView.delegate = self;
Add the callback to grab all requests and cache in case of failure
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
_lastRequest = request;
return YES;
}
Add the failure callback and re-fetch the URL to see if it is a pass and if so, present the pass to the user
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
// try to get headers in case of passbook pass
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:_lastRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// check for PKPass
if ([response.MIMEType isEqualToString:#"application/vnd.apple.pkpass"]) {
NSError *error;
PKPass *pass = [[PKPass alloc] initWithData:data error:&error];
if (error) {
NSLog(#"Error: %#", error);
} else {
PKAddPassesViewController *apvc = [[PKAddPassesViewController alloc] initWithPass:pass];
[self presentViewController:apvc animated:YES completion:nil];
}
}
}];
}
It's a horrible hack for what should be supported, but it works regardless of the extension and should support re-directs. If you want to pile on the bug train, you can reference radar://21314226