Updating Ionic Apps on the fly


#1

Hey guys,

New to app development on the mobile web and I had assumed that I can update my app on the backend (like a website) without having the user redownload the app. As the html / js / css resources are bundled with the app I’m realizing that I’m not quite sure how to do this.

Is there a way to update the app on the backend without reinstalling? This was the biggest draw for me to use mobile web - otherwise what’s the benefits in terms of updates vs a native app.

Thanks for the response - I’ve built part of an ionic app (love the framework and angular) and I’m trying to decide whether to continue or just build in native.


Is it possible to update Ionic application
#2

It really depends on your desired distribution. If you want to get paid for an “app”, you will likely need to bundle it with Phonegap and distribute it via app stores.

If your “app” is free to use and you aren’t trying to monetize, then you can just make it available via the web.

As far as Apple is concerned, your app cannot self update. They will not allow that. It’s general structure and functionality must be fixed. You can update content over the air, but not the look and feel of the app.


#3

Apple does have a enterprise developer license where you can host the app on your own server, outside of the app store, then manage everything on your own terms.

Downside is you do not have the app store to showcase your app, but you can set your app up so that way all your files could be pull can be from a server and update when ever its opened.

Your best bet is to distribute through the app store and let Google/Apple handle updates and such.


#4

Its really easy, i’ve done it in production for a large corporation. Thats also how Financial Times updates their webapp inside their native wrapper.

  • develop as usual
  • use grunt-manifest to automate creating an appcache manifest file
  • point index.html to remote host instead of local machine, place all assets on remote host

on first launch, the app will download the app remotely and as soon as you update one of the files on the remote server, it will be updated in the webapp. boom - store-independent, realtime native app updates.


Cordova-app-loader
#5

Yep, like @Calendee said, there are definitely some grey areas here, but technically it’s very possible.

No specifics yet, but this is definitely something we will release for the Ionic services stuff in the future… :slight_smile:


#6

I knew it was possibly, but I was under the impression Apple would reject any such apps. Very interesting. Thanks for the info.


#7

I was under the impression they would as well, but it actually sounds as if they specifically allow for it. I swear that wording has changed since I last looked into it:

3.3.2 An Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple’s built-in WebKit framework, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.


#8

The generate assets of ios and android are different, So, the server side asset should also be different, how did you do that?

The ios is easy just copy the cordova.js, cordova_plugins.js and plugins folder and other static files, but android I don’t know copy which files to the server.


#9

@SidneyS And the index.html should also be different, the server side should render different html by the client type, It seems not easy to do this, am I do something wrong?


#10

@Lagoonwish

1 . Rename cordova.js to cordova.ios.js.
2. Replace all references to cordova_plugins.js within cordova.ios.js to cordova_plugins.ios.js. Then, rename cordova_plugins.js to cordova_plugins.ios.js.
3. Do the same for the android cordova files, just use .android" suffix instead of “.ios”.
4. Configure your cordova_plugin files for each platform accordingly to your needs.

The grunt script should then be modified to contain two more build targets: grunt build ios and grunt build android. In each of those, the “copy” task for the cordova files should just contain the required files (wildcard pattern: “.ios” for iOS, etc). Boom, you got a solution.


#11

@Lagoonwish

To your second question: the index.html should never differ no matter what the target. All of that decision making should either take place on build time or on runtime via CSS media queries or javascript platform detection, or a combination. For example, we check the system and its version via JS on startup and inject a CSS class to the body tag accordingly, e.g. <body class="android-4-4">. Within CSS, you can then target specific platforms in one file using scss:

body.ios-7 {
        .header {
            height: 64px;
        }
    }

body.android-4-0 {
        .header {
            height: 48px;
        }
    }

#12

@SidneyS Thanks for your response, It is a great solution, and I have try it like you said.

The next step, I will remove the notification plugin by cordova, using the ionic popup to replace it.

You know, If we host the assets in server side, we should make it light weight in possible, reduce the requests.


#13

@SidneyS I found this error in PC browser, HEAD http://localhost:8080/!gap_exec?1395717083888 404 (Not Found)

I don’t know whether this error exit on mobile client, do you have the same error?

The cordova.js:

// Changing this to a GET will make the XHR reach the URIProtocol on 4.2.
            // For some reason it still doesn't work though...
            // Add a timestamp to the query param to prevent caching.
            execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);

#14

@Lagoonwish

That’s of course your choice, but i’d always prefer a native modal over a HTML5-based one. The added payload size is negligible.


#15

@Lagoonwish

That’s normal if you try to load cordova js using a standard desktop browser environment. You should only load cordova if a mobile device has been detected (do that before the body-tag):

<script>
if (navigator.userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i)) {
   console.log("iOS UIWebview detected, trying to launch Cordova.");
   document.write("<script charset='utf-8' src='cordova.ios.js'><\/script>");
} else if (navigator.userAgent.match(/Android/)) {
   console.log("Android Webview detected, trying to launch Cordova.");
   document.write("<script charset='utf-8' src='cordova.android.js'><\/script>");
} else {
   console.log("No Webview detected. Skipping Cordova/PhoneGap launch.");
}
</script>

#16

SydneyS - Could you give me an example of what you mean by “point index.html to remote host instead of local machine.” I’m not understanding what you mean by that. I’m looking to do almost exactly what you mentioned, only on Android. How do I point to a remote html file?


#17

Check out Cordova Loader https://github.com/andrewreedy/cordova-loader for Cordova asset compiling and serving with Express / Connect middleware


#18

Does this work with no internet connection? I mean, I run the app first time, it downloads it content, then I disconnect of the internet, will the content retain in the app?


#19

Hi @SidneyS - ionic adds classes to the body of index.html depending on the platform platform-ios or platform-android.

Any suggestions for handling this?


#20

What’s the status now?
2y ago when I was using Sencha Touch, I had to publish the app only once to the stores and then I could push new versions of the HTML5/JS to the clients without having to go through all the process of publishing a new app on the stores.
It was checking new versions and upgrading at application start-up, built into the framework.
Looking forward to seeing something similar in Ionic !