Is there a way to communicate between messages and my iOS app? - ios

I want to pre fill the verification code in my app's textfield once the user gets an SMS for verifying their number. But, due to security concerns, I don't think that feature is available on iOS. Now, I want to achieve something similar to WhatsApp. When I enter my number in WhatsApp, it sends me a verification code as well as a text that reads,"click here to proceed further". On clicking that link, I am redirected to WhatsApp and my mobile verification process is complete. I want to achieve something similar.

Yes, similar kind of thing can be achievable by using DeepLinking. You need to deep link the page to open particular screen of the app through link.
URLSchems also come in handy for this kind of requirement. For that your app has to whitelist the Scheme identifier it's going to use. So that through that URL scheme you OS will open your app. Send a message with URLScheme.
URLScheme looks like this: MyApp://myapp.com?VerificationCode="65636"
Now you need to get that parameter by using following methods:
func application(app: UIApplication, openURL url: NSURL, options: [String: AnyObject]) -> Bool {
scheme = url.scheme
path = url.path
query = url.query
return true
}
Now send that parameter to your server to verify. That's it.

Related

universal link goes to safari instead of the app that called it

I have a working universal link that works when used by another app. eg. if I write the link in notepad it will open app the app. But when I call the following inside the app that the universal link links to, it will open in safari. canOpenURL returns true.
have set up this .well-known/apple-app-site-association and also the correct intent-filter. I think its working because the links open the app when clicked outside of the app.
let url = Foundation.URL(string: "https://workingdeeplink.com/")!
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
This is expected behaviour. When an app passes its own universal link to open, iOS will open that link in Safari.
The purpose of this is to allow a fallback when an app cannot handle an incoming link. The logic for handling an incoming link is typically something like:
Parse the incoming link
Determine if the app can handle it
If it can, then handle the link (e.g. select a specific view or take some action)
If it can't, pass the link to open so that the user is redirected back to the web site, where the link can be handled.
This avoids the situation where a deep link opens your app and then nothing happens or an error is shown (because the app can't handle the url)
There shouldn't be a case where your app tries to open a deep link it can handle; it can simply bypass then whole deep link process and take the action that would result directly.

Empty Mobile Number is Callable in iOS?

When implementing call feature. Noticed that empty strings are returning true in call checking using canOpenURL
let mobile = ""
if let url = URL(string: "tel://\(mobile)"), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.openURL(url)
}
Above code works perfectly and instead of asking user confirmation for making call, an alert being displayed without any title or message from OS. Is it bug from apple?
Anybody has faced this issue before?
I'm using device without sim, that can be reason?
canOpenURL merely indicates whether there is an app on the device capable of handling the URL scheme (the tel: portion in this case).
It doesn't validate the URL in any way. Validation isn't possible since only the destination app knows what forms a valid URL (remember you can use this function with any app's URL scheme, not just well-known schemes like tel:).
Apple could perhaps handle the malformed URL more gracefully, but if there is a risk that the number is empty, you need to check for that condition on your side.

About custom URL scheme way of transferring data

I know how custom URL scheme works. Basically, I just need to define a custom URL scheme in Info.plist, and handle it like following:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// here I only printout
print("url host: \(String(describing: url.host))")
print("url path: \(url.path)")
return true
}
For example, if I define url as myapp://foo.com/bar , the above function would print out the host as foo.com and path as bar.
My question is, is it overall a secure way of transferring data between two apps saying another app opens the custom URL and use the path to transfer some sensitive information. e.g. myapp://foo.com/sensetive_data . Would the sensitive_data be caught by another app than mine or be leaked?
No, It's not safe to share sensitive data in custom URL scheme or Universal link.
It is possible to register two app with same custom URL scheme, at this point action is undefined which app will be open but let's suppose your is uninstalled and the fake app is installed in device then your custom URL scheme will open fake app and data can be easily read by that app.
And in Universal link when your app is not installed then it will open Safari and URL filed will contain full path which can be copied from there.
In my opinion the best way to share sensitive data between two or more app is to use Shared Keychain.
If you develop a family of apps, all of which rely on the same user
secret, you can use access groups to securely share that secret among
those apps. For example, you can share credentials, so that logging
into one of your apps automatically grants the user access to all of
your apps. This kind of sharing doesn’t require interaction with or
permission from the user, but limits sharing to apps that are
delivered by a single development team.
In my opinion it is not secure if your sensitive data is not encrypted.
To read your sensitive data I would just have to uninstall your second app, and install my own registering the same scheme than yours to access the data.
So, you may either:
encrypt your data (with all the restriction applied to encryption usage)
use some kind of a token that can be used to retrieve sensitive data from your server
EDIT:
For encryption you can use the Security framework: https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/using_keys_for_encryption

Redirects to app store if app is not installed

Scenario is user will get a link to his email. If user clicks on the link, If app is already installed, app should open and if app is not installed it should redirect to app store.
I've seen deeplinks implementation, but I believe it needs some more implementation in backend too. Can any one help on this?
Redirect to application if installed, otherwise to App Store
gone through this. Is there any better way?
added gif for one more scenario:
in the below gif, from email to app it navigates directly? how?
I'm assuming the link you want to pass by email is an https link. If that's the case, for iOS to be able to redirect it to your app, you'll need to implement universal links. This implementation requires you to register the domain you want to respond to on your entitlements file and add an apple-app-site-association file to your backend. This way Apple can verify the domain you're trying to respond to is really yours.
As a result, when the app gets installed, it can be invoked by your domain links via deeplinking.
Now when there's no installed app able to respond to a specific https domain link, the system will simply open it on a web browser. Consequently, you cannot force iOS to open such links on AppStore directly. What you can do is to check whether the running device is iOS when your website gets accessed and ask the system to show your app on AppStore.
And to request iOS to launch AppStore from a website you can use itms-apps:
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
if (iOS) {
// Just replace `https://` with `itms://` on your app's AppStore link.
window.location.href = "itms://itunes.apple.com/us/app/google-maps-transit-food/id585027354?mt=8";
}
// In this example I'm redirecting to Google Maps app page on AppStore.
Note: This is just a simple example used to demonstrate the concept. For a real application, you may want to use a device detection library for browsers, like mobile-detect.js
My suggestion is check iOS version
here Example
let url = URL(string: "www.stackoverflow.com")!
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}

How to use URL Scheme to share data between two apps without openURL method?

I have App A and App B. Here I just want to share text data from A to B and for that I doing following code.
In A :
UIApplication.sharedApplication().openURL(NSURL(string: "B://sample_text")!)
In B :
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
print(url)
return true
}
Output in B : B://sample_text
Using above code, I can able to send sample_text data from A to B. But App B is getting open that I don't want.
I want to share the same data and it should get in B when I launch B manually in future.
May be if there is any other method than openURL, then please suggest.
App Group can achieve this but it has limitation like you can only share data between applications that share a common app ID prefix.
You might want to check out App Groups to share data between your two apps instead of sharing data using a URL scheme.
An example can found at Sharing data in between apps in IOS.
The alternative is to store the data to, and read it from, a backend server.

Resources