Moovit Deep Linking Fails,Swift - ios

did anyone successfully deep linked from his app to a directions to a place in moovit ? why can't i ?! it just opens the app and does nothing ....
if anyone successfully deep linked to a direction to anywhere please help.
if UIApplication.shared.canOpenURL(URL(string: "moovit://")!) {
// Moovit installed - launch app (with parameters)
let MoovitURL: String = "moovit://directions?dest_lat=40.758896&dest_lon=-73.985130&dest_name=TimesSquare&orig_lat=40.735845&orig_lon=-73.990512&orig_name=UnionSquare&auto_run=true&partner_id=<testApp2345>"
let escapedString = MoovitURL.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
UIApplication.shared.openURL(URL(string: escapedString!)!)
}else {
// Moovit not installed - send to store
UIApplication.shared.openURL(URL(string: "https://itunes.apple.com/us/app/id498477945")!)
}
}
even Moovit's own example isn't working for me....Whats wrong?

The problem is with the .urlHostAllowed parameter.
Using the .urlQueryAllowed parameter instead will only convert the parameters after '?'.
Fixed your code:
if UIApplication.shared.canOpenURL(URL(string: "moovit://")!) {
// Moovit installed - launch app (with parameters)
let MoovitURL: String = "moovit://directions?dest_lat=40.758896&dest_lon=-73.985130&dest_name=TimesSquare&orig_lat=40.735845&orig_lon=-73.990512&orig_name=UnionSquare&auto_run=true&partner_id=<testApp2345>"
let escapedString = MoovitURL.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
UIApplication.shared.open(URL(string: escapedString!)!, options: [:], completionHandler: nil)
}else {
// Moovit not installed - send to store
UIApplication.shared.open(URL(string: "https://itunes.apple.com/us/app/id498477945")!, options: [:], completionHandler: nil)
}

Try opening this url in Safari and see if it works (It does for me).
Looks like the problem is with the code, maybe try without addingPercentEncoding or use the new openURL API

Related

Open url tel scheme not working for some phone numbers

I am using the below code to dial a phone number that I get from contacts:
func dialNumber(number : String) {
let formatedNumber = number.components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")
print("formatedNumber:", formatedNumber)
if let url = URL(string: "tel://\(formatedNumber)"),
UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(url)
}
}
}
Additional info:
var urlTest = URL(string: "tel:+12345678900")!
print("UIApplication.shared.canOpenURL(url):", UIApplication.shared.canOpenURL(urlTest)) // Returns true
UIApplication.shared.open(urlTest, options: [:], completionHandler:nil)
var urlTest = URL(string: "tel:2345678900")!
print("UIApplication.shared.canOpenURL(url):", UIApplication.shared.canOpenURL(urlTest)) // Returns true
UIApplication.shared.open(urlTest, options: [:], completionHandler:nil)
The code works for numbers with Area code +1XXXYYYZZZZ and the phone number is dialed.
But it doesn't work for numbers like XXXYYYZZZZ.
If I open the contact using Address Book, the number XXXYYYZZZZ is recognized as a phone number. On clicking, the number gets dialed.
How can I get a similar behaviour as Address Book inside my app?
I do not want to add a region code +1 as the app will be used in other countries as well.
There are external libraries for identifying phone numbers but I'm trying to explore if there is a native solution.
If a number is not recognized, I even tried to open the contact in the address book so the user can dial the number from the contacts app, but it looks like address book is not a supported scheme.

WhatsApp VS WhatsApp Business in SWIFT

We would really appreciate any help on the following. Through our app, the user can initiate a WhatsApp message (what happens is that the WhatsApp client starts with the phone + text preloaded, so the user just needs to tap the "send" button from the WhatsApp application).
We have an Android and an iOS app. In Android we are using the following code to select between WhatsApp and WhatsApp Business.
String url = "https://api.whatsapp.com/send?phone=" + phoneNumberToUse + "&text=" +
URLEncoder.encode(messageText, "UTF-8");
if(useWhatsAppBusiness){
intent.setPackage("com.whatsapp.w4b");
} else {
intent.setPackage("com.whatsapp");
}
URLEncoder.encode(messageText, "UTF-8");
intent.setPackage("com.whatsapp");
intent.setData(Uri.parse(url));
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
} else {
Toast.makeText(this, "WhatsApp application not found", Toast.LENGTH_SHORT).show();
}
We are trying to achieve the same functionality on Swift for iOS, however, we did not find any way to programmatically define whether the OS should start WhatsApp or WhatsApp Business. The code listed below, always starts the one or other depending on which is installed. If both are installed, it starts the WhatsApp application.
let whatsApp = "https://wa.me/\(phoneNumber)/?text=\(shareableMessageText)"
guard let url = URL(string: whatsApp) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
So in simple words, is there any way, from our app, to select which WhatsApp application (WhatsApp or WhatsApp Business) is going to be launched?
Thanks
I have made some apps with WhatsApp but I had to use the web platform, not the business app.
You can check what app is installed in the device like this:
let app = UIApplication.shared
let appScheme = "App1://app"
if app.canOpenURL(URL(string: appScheme)!) {
print("App is install and can be opened")
} else {
print("App in not installed. Go to AppStore")
}
The 'App1' value must be changed for the app you want to check. WhatsApp App should use 'WhatsApp', and WhatsApp Business should use 'WhatsApp-Business'.
After that you can call the URL for each app, I mean, for WhatsApp you can use the URL with this format:
let whatsApp = "https://wa.me/\(phoneNumber)/?text=\(shareableMessageText)"
And for WhatsApp Business you have to use this format:
let whatsApp = "https://api.whatsapp.com/send?phone=\(phoneNumber)&text=\(shareableMessageText)"
It is possible too, that the first step was not necessary to do. Because of the call is made with the api, the device should open the Business app, and if it is made with the wa.me scheme, the device should open the WhatsApp as normal.
I am going to check my app to see if it is working or not.
UPDATE:
I have installed WhatsApp Business and I have made some test, with two different url calls.
The code I use is this:
let phoneNumber = "my_phone_number"
let shareableMessageText = "This_is_a_test_message"
let whatsApp = "https://wa.me/\(phoneNumber)/?text=\(shareableMessageText)"
if let urlString = whatsApp.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
if let whatsappURL = NSURL(string: urlString) {
if UIApplication.shared.canOpenURL(whatsappURL as URL) {
UIApplication.shared.openURL(whatsappURL as URL)
} else {
print("error")
}
}
}
Using this code you will see a prompt with a message giving you the option of send a message in WhatsApp or WhatsApp Business.
But if you use this other code:
let phoneNumber = "my_phone_number"
let shareableMessageText = "This_is_a_test_message"
let whatsApp = "whatsapp://send?phone=\(phoneNumber)&text=\(shareableMessageText)"
if let urlString = whatsApp.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
if let whatsappURL = NSURL(string: urlString) {
if UIApplication.shared.canOpenURL(whatsappURL as URL) {
UIApplication.shared.openURL(whatsappURL as URL)
} else {
print("error")
}
}
}
You will see a prompt asking you to open WhatsApp business. So the way to choose between WhatsApp and WhatsApp Business is the URL format. If you choose this format you will be ask to choose between one or another WA version:
let whatsApp = "https://wa.me/\(phoneNumber)/?text=\(shareableMessageText)"
But if you use this URL format, you will use WA Business directly:
let whatsApp = "whatsapp://send?phone=\(phoneNumber)&text=\(shareableMessageText)"

How can I open Apple Reminders app programmatically?

Is there a way to open the Apple Reminders app programmatically?
I have tried in Swift 5+ and iOS 13, you need to use the following url scheme.(Earlier x-apple-reminder:// was working but now it isn't)
x-apple-reminderkit://
if let url = URL(string: "x-apple-reminderkit://"), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:]) { (isDone) in
}
}
It will open the iOS Reminder App from your application.
Hope it may be helpful to other.
Try This
let url = URL(string: "x-apple-reminder://")
UIApplication.shared.open(url!, options: [:]) { (finish) in
}
Reference for all apple apps scheme :
https://ios.gadgethacks.com/news/always-updated-list-ios-app-url-scheme-names-0184033/
and if you use x-apple-reminderkit://today, you can open the Today "view" in Reminders.
Still trying to figure out how to open a specific list or the Flagged view, though.

open instagram post iPhone hook stopped working

In order to open instagram app with certain post I'm using following code:
func instaOpen(_ postId: String, _ postUrl: String){
let appURL = URL(string: "instagram://media?id=\(postId)")!
if UIApplication.shared.canOpenURL(appURL) {
UIApplication.shared.open(appURL, options: [:], completionHandler: nil)
} else {
// if Instagram app is not installed, open URL inside Safari
let webURL = URL(string: postUrl)!
let svc = SFSafariViewController(url: webURL)
present(svc, animated: true, completion: nil)
}
}
When instaOpen function called – instagram app opens, but login prompt forcefully pops over. Not matter what you do - close it or proceed with login, the queried post simply won't open(see gif).
This started happening recently, after I've updated my app and pushed deployment target to iOS12.
I do have instagram listed in my LSApplicationQueriesSchemes as well as I'm 100% positive that correct mediaID is being passed to instaOpen func (the code worked previously).
Let me know if there's any suggestions on how to fix this and actually open instagram post in instagram app.
Updated - Facebook developer fixed the issue.
Its instagram bug you can follow its progress from https://developers.facebook.com/support/bugs/290173615155052/?disable_redirect=0
Probably a bug, as that feature works on Android.
i manage to "fix" the problem on a pwa app using the Instagram web app.
let appURL = URL(string: "https://www.instagram.com/p/\(postId)")!
//https://www.instagram.com/p/insert here media id

How to check app is installed or not in phone

I don't know how to check if app is installed or not on phone! Or when App is installed, open the app, otherwise open the Appstore link to download the app. I'm using swift 3. I want to do it using app name or bundle identifier.
Thank You!
func openApp(appName:String) {
let appName = "instagram"
let appScheme = "\(appName)://app"
let appUrl = URL(string: appScheme)
if UIApplication.shared.canOpenURL(appUrl! as URL) {
UIApplication.shared.open(appUrl!)
} else {
print("App not installed")
}
}
After looking into so many answers, i am writing a common code which will help for new users. If you have two mobile apps as App1 and App2, if you want to check in App2 that App1 is already installed in his device or not, here is code below.
In App1 add this property in info.plist file
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.companyName.App1</string>
<key>CFBundleURLSchemes</key>
<array>
<string>App1</string>
</array>
</dict>
</array>
In App2 add this property in info.plist file
<key>LSApplicationQueriesSchemes</key>
<array>
<string>App1</string>
</array>
In App2 write the method to check if app is installed or not on phone! Or when App is installed, open the app, otherwise open the Appstore link to download the app as below.
func checkAndOpenApp(){
let app = UIApplication.shared
let appScheme = "App1://app"
if app.canOpenURL(URL(string: appScheme)!) {
print("App is install and can be opened")
let url = URL(string:appScheme)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
} else {
print("App in not installed. Go to AppStore")
if let url = URL(string: "https://apps.apple.com/us/app/App1/id1445847940?ls=1"),
UIApplication.shared.canOpenURL(url)
{
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
}
}
I hope it will help some one.
Between the other answers and their comments, I'm getting the impression that the asker wants to be able to see if any given app is installed.
Beginning with iOS 9.0, that is not possible.
Apps for iOS 9 and later must have a list of requested URL schemes in the Info.plist before being allowed to use canOpenURL:. This is to protect user privacy, as advertisers were abusing this functionality in an arguably invasive fashion. (See this excellent post for more details on those changes.)
Of course, that list is static and cannot be changed after build time or submission to the App Store. If Apple doesn't like the ones you chose, they have every right to reject it.
I'm afraid that what you're asking isn't possible within reason for iOS 9.0 and later.
Edit: I also want to make clear that an app's URL scheme may not necessarily match nicely with its name. (This is more of an issue of a badly named constant than a functional issue.) There used to be a giant list of known URI schemes with documentation for each, but poignantly and fittingly enough, it seems that the wiki hosting it has shut down.
Swift 4.1. One developer can have more than one app on AppStore. So, I need to check if user has installed other apps or not by the same developer. I had Bundle ID's of other apps. Although you can use Appname instead of Bundle Id. So I followed the following steps.
In your current app add LSApplicationQueriesSchemes key of type Array in your info.plist file. Make entry of bundle id or Appname of app there which you want to open from your app.
Other app should have their bundle id or Appname entry in that app URL Scheme.
In your current app check if that app in installed in iPhone or not and can open accordingly.
let app = UIApplication.shared
let bundleID = "some.Bundle.Id://"
if app.canOpenURL(URL(string: bundleID)!) {
print("App is install and can be opened")
let url = URL(string:bundleID)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
} else {
print("App in not installed. Go to AppStore")
}
You can also test it from Safari browser. Just type the following in search bar
URL_scheme:// or Bundle_Id://
If app is installed the it will show alert with Appname to open it in app.
This worked for me (Swift 3.0)
Below two inputs should be provided:
<APP URL SCEHME>: The URL Scheme of the app which you want to open
<YOUR APP URL>: The App Itunes URL
func openApp() {
let appURL = NSURL(string: "<APP URL SCHEME>")
if UIApplication.shared.canOpenURL(appURL as! URL) {
print("Opening App...")
}else {
UIApplication.shared.openURL(NSURL(string: "<YOUR APP URL>")! as URL)
}
}
first go to info.plist, add LSApplicationQueriesSchemes add an item and place instagram on that item. Now this code will run perfectly.
let appName = "instagram"
let appScheme = "\(appName)://"
let appUrl = URL(string: appScheme)
if UIApplication.shared.canOpenURL(appUrl! as URL)
{
UIApplication.shared.open(appUrl!)
} else {
print("App not installed")
}

Resources