Permanently Redirect iOS Home Screen Web Apps - ios

I have a single-page web app using Sencha Touch that has been added to the home screen on about 2000 iPads. I am looking to change the URL of the web app without requiring all of those users to delete the launch icon from the home screen, go to the new URL, and add it to home screen again. The app also uses a cache manifest to cache the HTML, CSS, JavaScript, and images, and the app is capable of working entirely offline.
Web pages added to home screen in iOS do seem to respond to HTTP 301 (permanent redirect) as expected, but I have found the behavior to be quirky in iOS 8 on iPad 2 devices as I will describe. I created an ASP.NET MVC website that I deploy under the same URL, replacing the Sencha Touch app in order to accomplish the permanent redirect. Here is the process I'm using and the behaviors I'm seeing:
When the app is launched from the old URL, it requests only the cache.manifest, and I return HTTP 404 to make the app stop caching.
The app loads and I have an event handler in the app's JavaScript for the applicationCache "obsolete" event that will call window.location.reload(true). The app will then reload and this time will ask for the previously cached HTML page (which is hosted at the URL root), and my ASP.NET MVC site will then return HTTP 301 to permanently redirect to the new URL.
Once the app hits the new URL, it begins downloading the resources from the cache.manifest at the new URL. I have an event handler on the "updateready" applicationCache event that will call window.location.reload(true) and reload the app. Once the app reloads, it will then request all resources (XHR requests to services) from the new URL as expected.
When I test this on an iPad 1 running iOS 5, this works exactly as I would expect. Once the resources from the new URL are downloaded and cached, it always makes every request from the new URL from that point. I can put the device in airplane mode and the app will work just fine offline.
This is where the quirky behavior begins, and I only see this on my iPads that are running iOS 8.x (I don't have any devices running iOS 6 or 7). I then close the app by pressing the home button and relaunch it from the home screen icon. When I relaunch the app, it will always initially go back to the old URL (iOS 5 always goes to the new URL), which is strange because the HTTP 301 from before should have prevented this. From here, there are two possible behaviors:
5a. Sometimes, it will ask for only the HTML page from the old URL (root URL), and in that case, it will get another HTTP 301 and will then redirect to the new URL, ask for the cache manifest, then load the app. From there and onward, it will never make requests to the old URL again when I open and close the app. When I put the device in airplane mode, the app works just fine offline. I have two iPad 2s running iOS 8.3 and 8.4, and this will happen about 50% of the time on these devices.
5b. Other times, it doesn't work so well. When relaunching the app after downloading the cached resources from the new URL, it will go back to the old URL and will not request the HTML page, and will instead request the cache.manifest along with the CSS and JavaScript. The the cache.manifest request will be result in another HTTP 404, but if I continue closing and re-opening the app, it will never consider the cache to be obsolete and will not request the HTML page again. Interestingly, I am only able to reproduce this on the iPad 2s. I have an iPad Air 1 running iOS 8.3 and I only ever see 5a on that device.
For the case described in 5b, it does request the JavaScript files. So, I went into one the JavaScript files and put in window.location.reload(true), which causes it to request the HTML page, which results in another HTTP 301. Now when this scenario occurs, it does send it to the new URL, but every time I close and re-open the app, it repeats the whole cycle. It goes to the old URL, gets the JavaScript, reloads, gets a 301, then goes to the new URL. When I put the device in airplane mode and open the app, it doesn't work.
I found that if I put the iPad 2s in airplane mode and run the app in the old URL, then run it again and do the 404 for the cache.manifest and the 301 for the HTML, then 5a will always occur. This sounds like a bug in iOS 8 (that possibly also exists in 6 and 7), and I'm trying to figure out a workaround that I can implement in my ASP.NET MVC website to redirect to the new URL that will work 100% of the time.
Any insights would be greatly appreciated.

I figured out how to avoid the quirky behavior. As I mentioned above, the app is listening to the "obsolete" event on applicationCache and is then calling window.location.reload(true) to grab the page again and get the 301. I found that if instead of reloading the same page, I redirect to a different page and back again, it works perfectly 100% of the time. It redirects to the new URL, caches the resources, then never asks for the old URL again. I also discovered that closing the app and opening it again after the cache is obsoleted has the same effect.

Related

everytime favicon loads, browser loading old one initially and then new one

In my rails app, I am managing two favicons based on a condition.
Below is the code in my application layout
- if <condition>
= favicon_link_tag "favicon1.ico"
- else
= favicon_link_tag "favicon2.ico"
Its working fine as per condition but when I switch from favicon1 to favicon2, on page load browser loading favicon1 initially and then loading favicon2, and same is happending whenever favicon is loading in browser.
Browser: Chrome
Version: 105.0.5195.102 (Official Build) (x86_64)
Browser is not sending two requests
Browser cache enabled, but even if I disable it, issue still occurs.
My suspicion is that, when I click on any link in my app, browser is requesting for favicon, until the response comes back, browser loads previous favicon and once the response comes back, loads the correct favicon.
Browser is not requesting favicon everytime when I click a link but it's calling randomly and requesting frequently on few links.
Is there a way to stop browser from requesting favicon unless it's a whole page load?

Launching an App from Custom URL from Safari not working as intended in iOS >12.3

We share the App deeplinks (Universal links) with our users over email, sometimes they get wrapped by email service providers for safety.
When user taps on these wrapped deeplinks, instead of opening the App directly it opens the url in Safari.
We have a page hosted on that url. We capture the deeplink there and try to open the App using Custom URL scheme (myurlscheme://). But if the App is not installed, we try to redirect the user to the App Store page.
It all worked okay until now, but seems like Apple made some changes in Safari in the new versions of iOS (>12.3).
What’s happening now is, if the App is installed and we open the App from Safari (from Custom URL), the App Store page opens in a split second after opening our App.
This is the Javascript code that we are using:
window.location.href = 'myurlscheme://';
setTimeout(function() {
window.location.href = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8";
}, 500);
Is anyone else experiencing this. If yes, were you able to find any solution?
Update:
If we set the timeout to 4000 (i.e. 4 seconds), then it does not redirect to the App Store after launching the App.

Do Universal Links hit my server?

I've set up Universal Links on my iOS app using an aliased subdomain of my backend with a scheme like sudomain.mydomain.com. I want users that DON'T have the app installed to be redirected to our page in the App Store rather than hitting some nonexistent endpoint on our server (we don't have a webapp only a mobile backend).
I was thinking about doing something like this:
app.get('*', (request, response) => {
const domain = request.headers.host,
subdomain = domain.split('.');
if ( subdomain[0] === 'subdomain'){
response.redirect('www.linktoappstore.com');
}
...
});
However I don't want this to interfere with Universal Linking for people who DO have the app installed. Are Universal Link get requests sent to my server or does iOS intercept them before that happens?
This should work just fine.
When Universal Links are configured and your app is installed, the device does NOT hit the server before launching the app. This is because iOS caches the apple-app-site-association file when the app is initially installed, and if the URL being opened matches a path defined there, Universal Links kick in. In that situation, iOS completely bypasses any web request and immediately launches your app.
Of course, this means you can't track Universal Link traffic, which can become a major pain point. To work around this, you need something like Branch.io (full disclosure: I'm on the Branch team) to fill in the missing data.
Separately, if you're proxying the subdomain, make sure iOS doesn't see that as any sort of redirect. Otherwise the apple-app-site-association file won't be scraped at all (common Universal Link implementation issue).

Close in app browser after a redirect

We have an ad partner that is redirecting users to the app store after an ad in our app is tapped. We load an in-app browser which does the redirect. Nothing in the browser ever loads, it is just a white screen. Once the user returns to our app they are looking at that empty browser. Is there anyway to dismiss or close that browser once the redirect is completed?
We don't have any control over the server side.
What kind of in-app browser you are using in your app? Like a library or an UIWebView? If it's an UIWebView, there's a callback method when the webpage is loaded (and probably, redirected the link):
- (void)webViewDidFinishLoad:(UIWebView *)webView;
If you're using a library, I'm pretty sure it also has a method like that.
I fixed this by skipping the in-app browser and used Safari instead. App store re-directs are happening without showing the browser window and all the other ads are working as expected.
Plus I got to delete a bunch of old code.

Links in remote JQueryMobile sites in a PhoneGap app open safari

I'm having quite a peculiar problem with PhoneGap and JQuery Mobile, using the latest versions of both frameworks as of this writing.
My phonegap app has some pages 'local' to the app, and other pages that are loaded directly from a remote site. Going between the local and remote pages is fine (there is no transition but that can't exactly be helped). However, once I'm on the remote pages, any link I click on the remote pages opens Safari with the page I requested. This is not desirable functionality, as I would like it all to be within the UIWebView, and none of my links are marked with anything special that would cause Safari to open.
It gets weirder. If I then switch from Safari back to the program, the remote page I requested appears in the UIWebView, however pressing the back button leads me not to the first remote page, but the first local page.
The phonegap app right now is quite bare, very close to the default except with JQM css + js loaded. This happens even if I create a simple test app that has one local JQM page, one remote JQM page and then a remote page that is linked to from a JQM remote page.
I'm stumped. What's going on here?
The default behavior for PhoneGap is to open external links in Safari unless they are added to the ExternalHosts property in PhoneGap.plist.
Try adding the external hosts and PhoneGap should behave correctly and load the external locations inside of the application.
(source: tumblr.com)
Here also is a post about using iFrames and ExternalHosts that could be of some help as well.

Resources