This is a fairly straightforward one: to date, can an iOS app deep link or in any way launch Amazon Music to play a specific song/load an artist or album? How much of this can be done?
If you're feeling really generous, could you describe how to find the URLs to deep link to third party apps like AM, Facebook, Twitter and Spotify?
So I opened up the "Amazon Music" .ipa file (it's basically just a .zip file you can unzip) and in the app's Info.plist file I see a URL scheme that the app answers to:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.amazon.mp3</string>
<key>CFBundleURLSchemes</key>
<array>
<string>amznmp3</string>
</array>
</dict>
</array>
Unfortunately, this is not a public scheme. That is, there's no documentation available for it that can be googled (or I would have expected to have found it on a page like this).
This means you will probably have do additional research to figure out what kind of parameter to pass along with the scheme. For example, on this page I see a potential parameter of "fb164734381262". Perhaps it's a mp3 file identifier?
My application is a little different, but may be helpful. I am using the Workflow app to automate several things. I can interact with the Amazon Music app through the URL below.
https://music.amazon.com/playlists/B0797C4SN9?do=play
When the URL is opened in Workflow, it causes the Amazon Music app to open. A specific playlist is opened, then it starts playing.
You can create others by opening the app, sharing the playlist to notes. Deleting all of the information after the ? from the URL. Then add do=play to the end of the URL.
I think this would apply to songs and albums as well.
I would really like to know how to get the shuffle playlist from URL, so if somebody figures that out, let me know.
The answer by #Kyle365 works with iOS Shortcuts as well, was able to play a private and public playlist by copying the playlist’s url (share > copy) and changed the url to include ?do=play at the end. I created a shortcut that opens this url and Shortcuts recognizes the url as an Amazon Music url and opens it directly in the Amazon Music app and starts playing it.
Example of Url:
https://music.amazon.com/user-playlists/somePlaylistId?do=play
Related
The Problem:
I am building an app that uses PayPal for payments, and I set up universal links so that the user gets redirected into the app after the user has confirmed the payment at PayPal's site.
Universal links are working in general. But here is what I have discovered:
The following scenario works:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User has to log in and presses the login button.
User presses the confirmation button on the PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser closes, and the user gets redirected into the app.
Now when the user has just recently logged into PayPal then PayPal does not show the login page, instead the user has to only press one button. This scenario fails:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User does not have to log in and presses the confirmation button on PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser opens the website behind the universal link instead of redirecting to the app.
This scenario also works:
App opens the nextActionUrl from PayPal using SFSafariViewController.
User does not have to log in, but actively logs out.
User has to log in and presses the login button.
User presses the confirmation button on the PayPal site.
PayPal redirects to the return_url that was provided when creating the payment intent.
The browser closes, and the user gets redirected into the app.
This happens consistently and reproducible.
Some additional details:
I am developing the App using Flutter
I set up the Runner.entitlements as follows:
...
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:sub.example.com</string>
</array>
...
I set up the Info.plist as follows for deep links with different schema:
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>sub.example.com</string>
<key>CFBundleURLSchemes</key>
<array>
<string>web+example</string>
</array>
</dict>
</array>
...
I set up the apple-app-site-association file on the website at https://sub.example.com/.well-known/apple-app-site-association as follows:
{
"activitycontinuation": {},
"webcredentials": {},
"applinks": {
"apps": [],
"details": [
{
"appID": "XXXXXXXXXX.com.example.example",
"paths": [ "/*" ]
}
]
}
}
To open the urls from Flutter I am using the package url_launcher and simply call await launchUrl(nextActionUrl)
What I've tried and what I've learned:
I tried many things, before I discovered this consistent behavior. For example:
I connected my device to the mac and opened the console for it in xcode to see how the logs look like when it works and how it looks like when it does not work. I found out that when it works there is a log entry that requests the switch to my App from the SpringBoard-process: [Received trusted open application request for <applicationId> from <FBProcess: ...], but in the cases where it does not work there isn't a rejected request or anything. The SafariViewController does not even seem to try to go the universal link route and instead opens the link as a website directly.
For even more logs, I pressed and hold the volume buttons and clicked the lock screen button until a haptic feedback occurred. After that, I extracted the syslogs that were generated from the settings/privacy section via AirDrop on to the mac. I took a look at the swcutil_show.txt file and the universal link is definitely set up correctly there. I also skimmed around in the other logs, but I couldn't find anything helpful.
I have inspected the url_launcher package to see how it works for iOS and if there may be something wrong, but I didn't really find a problem. I only discovered that the package is using the SFSafariViewController and after some googling I've read the WKWebView would be more suitable, but it didn't seem to be the problem.
I googled a lot and found many problems related with setting up universal links correctly, but no topics about universal links sometimes working and sometimes not. The only thing close I found was that a universal link won't redirect you to your app if you type it into safari directly but if you click it for example from an email.
The workaround that works...
After I confirmed that it consistently works after logging in first, my theory was that it needs at least one navigation between opening the PayPal site in the browser and PayPal redirecting to the universal link.
To confirm my theory I created an intermediate page that redirects the user immediately after the load event to the PayPal site and I was disappointed. It didn't change anything.
Then I thought: Maybe it's the User-Interaction that is needed, and I change the intermediate page to only redirect if the user presses a button. And from there on, redirecting to the App using a universal link always worked.
But this isn't a nice solution - at max, this is an ugly workaround that may help someone.
My question(s)
Now I am not sure if this is a bug on Apple's side since I didn't find anything on the web or maybe even something strange on PayPal's side?
Am I doing something wrong?
Did someone experience the same thing and has a solution?
Thank you for your time and hopefully for your input on this!
I have a WKWebView, the webview will load a link like https://qr.payme.hsbc.com/2/XXXXYYYZZZ.
And there two possible results when the link is loaded,
case 1 is an app called Payme will be opened when user has installed Payme app;
case 2 is webview will be redirected to a static page https://payme.hsbc.com/ when user has not installed Payme app.
My question is how can I know if the Payme app is opened?
You could use deep linking or the apple recommended universal linking to check if an app is installed in a device. With deep linking what you need to do is to acquire a schema of the app that the app has already added. And you could check if the schema can be opened just like you would do for any other type of URLs. Here is an example:
let appSchemeString = "com.myAppScheme://"
let url = URL(string: appSchemeString)!
if UIApplication.shared.canOpenURL(url) {
print("App is present")
} else {
print("App is not")
}
You need to update your info.plist file to include the schemes you'll be opening in the application. You should append this:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.myAppScheme</string>
</array>
Here is an entire youtube video link regarding this.
Also, checkout universal-linking.
Before Xcode 7, it was working fine. When I post link like "myapp://mylink?id=1" on Facebook and Twitter for social media sharing, the users can click on it and it will open my own iOS app if it is installed. I know xcode 7 put limit of 50 url schemes that any app can ask "canOpenUrl" before actually proceeding with "openUrl". Apparently Facebook and Twitter both still checking canOpenUrl before opening the link (they open in a UIWebView inside their apps), and since they can't add all the world's apps' custom url schemes into their app plist because of the 50 limit, my app now can't be opened from FB and Twitter with my custom url scheme. Log shows following on the console:
Twitter[827] <Warning>: -canOpenURL: failed for URL: "myapp://mylink?id=1" -
error: "This app is not allowed to query for scheme myapp"
Now the question is, is there any way I can have it working like before, where users can click on some link (myapp://mylink?id=1) on FB and Twitter, then that opens my own app through custom url scheme?
FYI, I actually post link like http://myweb.com/link?id=1 on those sites, and the link is processed on my webserver based on the HTTP header request to decide to redirect to actual web, or if iOS then redirect to myapp://mylink?id=1, and if Android then redirect to another url scheme for android app etc. I tested with just posting myapp://mylink?id=1 link directly on Facebook and Twitter, and it's still not working giving same error.
Add on:
The iOS9 new rules is that you need to add following, up to 50 of them, to your app plist so that your app can query the OS for canOpenURL, but it also renders unusable for big apps like FB & Twitter:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>myapp-custom-url-scheme</string>
</array>
To me from my reading around researching this issue, the solution is:
either Apple should change this restriction to more rate limit based, so that abusing apps (like Amazon something) wouldn't use it to scan for all known url schemes to build statistics of app installs,
or Facebook and Twitter etc big social media sites should stop checking canOpenURL, and just go ahead and openURL without verifying.
or even better, we should build some centralized database for custom URL scheme name spaces, and both iOS and the other apps should use it for this kind of general purposes.
OK, Facebook and Twitter recently released updates that have fixed this issue now.
Seems like they are not checking canOpenURL anymore, and letting any app's custom url scheme to open, unless they are doing some other ways to validate it.
I am writing a Xamarin iOS app and having difficulty integrating Facebook SSO, though I don't think my problem is necessarily Xamarin-specific, just a lack of understanding of how to integrate Facebook SSO without the benefit of the Facebook iOS SDK.
I have followed the various guides and have done the following:
1) Have a Facebook App set up:
a) iOS Platform added with bundle id matching my app's bundle id
b) Single sign on enabled
2) Set up my info.plist as follows:
raw text:
<key>CFBundleDisplayName</key>
<string>[company]</string>
<key>CFBundleIdentifier</key>
<string>com.[company].ios.app</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb123490xxx</string>
</array>
<key>CFBundleURLName</key>
<string>com.[company].ios.app</string>
</dict>
</array>
<key>FacebookAppID</key>
<string>123490xxx</string>
<key>FacebookDisplayName</key>
<string>[company] Staging</string>
3) Implemented the following code in my app:
FacebookLoginButton.TouchUpInside += (sender, e) =>
{
var urlWithAppProtocol = new NSUrl("fb123490xxx://");
UIApplication.SharedApplication.OpenUrl(urlWithAppProtocol);
};
I have not overriden AppDelegates methods (OpenUrl and HandleOpenUrl) yet because as far as I can see those handle incoming redirects to my app; I will get that working next.
To be clear, what I'm expecting to see is the FB iOS App equivalent of this screen (from Mobile Safari)
However, if I redirect to:
"fb://[appid]" I get redirected to the FB app but just to the news feed page (or whatever screen I was on last when I was using the FB app)
"fb[appid]://" I get nothing happening, .OpenUrl() does nothing;
"fb://profile/[appid]" as an experiment, I get the following (notice the "app isn't available for your phone"); this could be because you're supposed to use the PageID with /profile.
What am I missing here?
Ok, in the end it was simply using fbauth://authorize in conjunction with the normal query string parameters in the oauth url. The redirect url needs to be fbconnect://success
I found this by reading the source code of the FB iOS SDK:
https://github.com/keithpitt/DKSocial/blob/72cd77bc15ca1a307b92aff8382f2c71a97da7de/External/FBConnect/Facebook.m
There might be a lesson here to use the Xamarin bindings of the official Facebook iOS SDK, which offers this functionality. I've ended up going down the manual route because I started with the Facebook .NET SDK, which doesn't seem to offer this App-based SSO functionality.
I'm currently work on a iOS/Phonegap app, I want to have it respond to a custom URL scheme, so that when a person clicks on a link in the regular browser it will open the app to a specific page, where said page is actually an external page. The app thus far essentially acts as a web browser where external (web) content is displayed in ChildBrowser.
I am 95% certain I need to use the following method in AppDelegate.
- (BOOL) execute:(InvokedUrlCommand*)command{}
And I know I need to use the following to create my command.
+ (InvokedUrlCommand*) newFromUrl:(NSURL*)url;
My problem is that I've been unable to find any examples online of doing this. I know the url passed to newFromUrl needs to be in the format of yourscheme://<sessionKey>#<Class>.<command>/[<arguments>][?<dictionary>] But in this case, my [<arguments>] would be a regular url of the form "http://www.google.com".
Can some one give a concrete real-world example?
This is implemented in current versions of PhoneGap so that all you need to do is add you custom URL to the App-info.plist file. Here is a sample of the XML:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.cams.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myApp</string>
</array>
</dict>
</array>
You should use the Property editor to edit this file and get the format correct.