Inconsistent ios app launch with same URL for app clips using NSUserAcitivty in AppDelegate - ios

Before App Clips, our app (if installed) could be launched by scanning a QR code. In such a case, AppDelegate would call NSUserActivity with the payload and we would extract QR code data for parsing and actioning.
After App Clip launched, the same behavior continued until recently (assuming before 14.4). Now, if the user has the app installed and they scan the QR code, they get the App Clip card to open the app. If the user taps on 'Open', the full app is launched. However, now the initial view controller launches before AppDelegate is able to receive and parse NSUserActivity data. This creates, I assume, some kind of a race condition where majority of the times initial root controller has malformed or no data.
My understanding is that NSUserActivity is the best way to handle application launches so I am not sure how to properly address this problem versus writing some hacky workarounds.
In our testing, we have noticed interesting situations where iOS would sometimes launch the full app without showing the app clip card (less frequently) and the full app would work fine. But majority of the times, it will show the app clip card and it would break our full app if it is installed.
Our full app and app clip use the same domains (universal applinks) and we do the decision making based on URL params within the app. Basically, our applink is configured to be example.com and within both apps (i.e. full and app clip), we extract business_name=FOO and item_id=BAR within AppDelegate (where full URL might be: example.com/buiness_name=FOO&item_id=BAR.
I am hoping someone can offer advice on how to solve/fix this problem.

Related

iOS migration from Website to app

iOS. I have a mobile web site and a mobile app for the same. i want the user to be able to navigate from web to my app through a link. Is it possible for this feature to be feasible when the app is not installed. I know i can use smart app banners when the app is already installed and this feature can be implemented then. But the main problem i am facing is when the user is asked to install the app (from smart app banners) for a particular page of my website. How can i automatically redirect the user to same page on my app from where he clicked the app banner on first launch of app ?
This is a problem that Branch, the company I'm working for, solves. It's actually fairly simple to explain, but quite a bit more tricky to implement yourself.
Apple doesn't currently allow you to persist information like that through an install (through the App Store), so you'll need an intermediate server. Now, depending on what devices you want to support, this gets more and more tricky. You mentioned you're only on iOS now, but if you expand to Android, this becomes even more complicated (with the fragmentation of Android devices and browsers, etc). For now, I'll just explain for iOS though. It's basically a two step process, starting with the smart banner on your mobile web page.
The smart banner, when clicked, will try to
* Launch the app if possible. We do this by trying to load via the app's URI scheme.
* If the URI Scheme fails (not installed), we send a device fingerprint to our servers based on IP, model, etc. and then send the user to the app store.
The second part is then within the app:
* When it launches, it needs to ask the server if it was launched via a link click. (whether directly into the app or through the app store and now into the app).
* It sends along a similar fingerprint, and then the server (if the device matches) will send back the relevant info (the page id, or whatever you use).
* If the page id is present, you need to present the view controller with that content to the user (you may need to persist this info in your app through a login, if it's behind an auth wall).

iOS Smart App Banner Enterprise

Can anyone provide some guidance regarding correct tag configuration for an enterprise Smart App Banner? The app does not appear in the Apple store; it is at a separate URL for enterprise members.
According to the docs, this can be accomplished with the addition of a meta tag, as follows:
What are each of these variables, and how are they typically set?
name: does this remain "apple-itunes-app" for an enterprise app?
app-id: I have a 19-digit number for this. Could that be right?
affiliate-data: What should this look like?
app-argument: URL of the app?
I got this working for an App that's in the Apple App store, for Angry Birds, with the meta tag below.
<meta name="apple-itunes-app" content="app-id=343200656">
Reference URL:
https://developer.apple.com/library/mac/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
Smart Banners are only for apps available in the App Store.
From Apple docs:
If the app is already installed on a user's device, the banner
intelligently changes its action, and tapping the banner will simply
open the app. If the user doesn’t have your app on his device, tapping
on the banner will take him to the app’s entry in the App Store.
When he returns to your website, a progress bar appears in the banner,
indicating how much longer the download will take to complete. When
the app finishes downloading, the View button changes to an Open
button, and tapping the banner will open the app while preserving the
user’s context from your website.
Been a while on this one, but if memory serves, I used a custom URL scheme.
In my particular situation, the requirement was to launch the app if it exists, and if not, display the smart app banner.
In a nutshell, here is how you do it:
Build your own smart app banner
Set up a custom URL scheme in your app
Call custom URL from Safari
If the App is installed, the App will launch; if not, it will hang.
If hung, cancel the request, and display the banner.
For example, imagine an new App called "happyBirds." In code, it looks something like this:
setTimeout(function () {
window.location = "#"; // Effectively cancels the following window.location command if the app is not installed.
$('#smartAppBanner').show(); // Make up your own smart app banner, and show it.
}, 100);
window.location = "happyBirdsCustomUrl://"; // If this is successful, the app will be launched, and the setTimeout will never fire
I was also toying with the idea of creating a custom URL scheme that simply returned "true" if the app was there, and also trying to launch the app from within an iFrame, but never got around to it. Maybe I'll give it a shot when I get a free hour or so.
Definitely take a look at the following posts for more info:
How to check if an app is installed from a web-page on an iPhone?
http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
Hope this helps!
Sincerely, Keith :)

Does app-argument on Apple Smart Banner get passed to app on install?

I've implemented a Apple Smart Banner for my app, including a app-argument with a URL I'd like the app to open on my site. I thought that would pass through when the user installs the app, but it doesn't seem to.
The steps - user visits page, doesn't have app installed, clicks View, goes to app store, installs app and then taps Open in the App Store. The app opens, but it doesn't appear to get the app-argument passed in. Note that if they then go back to the web page, the Smart Banner now says Open and that works and passes the app-argument, just not on the first install.
Have I misunderstood what is supposed to happen? If so, this makes the Smart Banner pretty much useless for me.
Gary
From the docs:
If the app is already installed on a user's device, the banner intelligently changes its action, and tapping the banner will simply open the app. If the user doesn’t have your app on his device, tapping on the banner will take him to the app’s entry in the App Store. When he returns to your website, a progress bar appears in the banner, indicating how much longer the download will take to complete. When the app finishes downloading, the View button changes to an Open button, and tapping the banner will open the app while preserving the user’s context from your website.
It only sends the URL param if the app is opened via the banner. If it's opened via AppStore or via SpringBoard, it won't send it.
You can do it with branch.io. More info here.
tl;dr
What Branch does is generate a custom URL specific for your device and uses the same unique configuration to fetch the data when the application is opened. Thus, you need to include their SDK into your app in order to get those arguments you want to send.
Maybe this is a bug?
From: http://developer.apple.com/library/ios/#documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
When the app finishes downloading, the View button changes to an Open button, and tapping the banner will open the app while preserving the user’s context from your website.

Launching another app in the background iOS

I am certain I already know the answer to this question, but I figured it was worth an ask.
I am working on an app that uses another app's custom URL Scheme to launch it, and then send the user to a specific page in the other app. I use:
[[UIApplication sharedApplication] openURL:URLScheme];
However, due to a bug in the other app (that I have no control over), if the app isn't running in the background, the URL will launch the app, and keep it on the home page rather than sending the user to the correct page within the app. If the app is running in the background, the process works as expected. I find this to be an unfortunate user experience that sometimes a link lands them on the home page and sometimes it lands them on the correct page.
I am using a way to detect if the app is running in the background or not which is working successfully. The question here is if the app is not running in the background can I make it launch without sending the user there until it launches. Or said differently send the user there (which puts my app into background) and once a user lands on the app, then send the request again to send them to the right page?
Again, I am sure I already know the answer to this, but thought I would see what you all thought.

iOS App: open a file, send it to a network location, then exit back to the calling app

Is there a way for an app which does this (and requires no UI) to be accepted by Apple's App Review process?
I know that simply putting exit(0) in applicationDidFinishLaunching:withOptions: will be rejected, but what if the exit(0) is called only upon completing a TCP transaction? Does Apple reject any attempt to exit your app?
Here's what I'm looking for. I make a file in some iOS app (a picture for instance) and I open it up in my app with "Open In...". I'd like for my app to perform a function which requires no user input (i.e., sending it to a preconfigured network location). Then I would like for my app to quit, returning to the app from which I used the "Open In..." feature.
I take it that if I am completely forbidden from exiting, then the most optimal possible workflow is probably the 4-finger swipe back to the calling app. It is also not very clear what my app would do when opened regularly (from the home screen), but that's not really a big problem.
What you want to do can't be done plus there is no point. Apple will never approve such an app. All apps must have a useful purpose in their own right. If the only use of your app is to send files from other apps to some server, it is of no use by itself. Apple expects each app to have a fully functional and useful user interface.
But all of that aside, here is why this can't be done - You are given no way to relaunch the calling app. When your app is launched, ultimately the UIApplicationDelegate method application:openURL:sourceApplication:annotation: will be called. This tells you what file to process and it gives you the bundle id of the requesting app. But there is no information that allows you to launch the app that launched yours. There is no API that let's you return to the previous app.
The only possibility is if the calling app explicitly launches your app and provides a return URL. But this eliminates and general use. Any app that would work with your app would need specific code in place to support your app. Obviously this is far from a general purpose solution.
BTW - having your app simply exit is of no benefit as that doesn't return the user to the previous app.
Assuming you own both apps, you don't have to exit your app at all. In fact, doing so wouldn't bring the other app back to the foreground anyway.
Just use the standard linking technique in both directions.

Resources