-
Notifications
You must be signed in to change notification settings - Fork 142
Support mobile-specific functionality #156
Comments
Hi Matt,
As you can see, it takes a little bit of work, but once this is done, you can do all your updates from the web server, and never need to deploy again (until you change domain useage :) ) |
Thanks for that response Jeff. I am indeed thinking about Ios / android mainly (as I suspect most developers will be too). Your steps make sense - and like you said once done it should be possible for all updates to come from the web server, which is a massive win :) I think for me, client detection on the server seems like a nice solution, would certainly be the one that I'd look into. I'm using asp.net, so I don't think it's too much trouble for me to do some detection on the server which will then allow me to conditionally serve the right file - I like this also because it means I don't need to worry about serving cordova.js files for "normal" desktop browser clients that don't want it. |
If your interested in colaboraing on this let me know. I bet it would be beneficial to the community. Maybe we can do an asp.net and node.js versions of it. I can probably find a person or two who knows asp.net :) |
Time permitting, I'd like to try and help out if I can :) On Tue, Sep 15, 2015 at 9:52 PM, Jeff Burtoft notifications@github.com
Matt Roberts e: roberts.mattroberts@gmail.com |
I was thinking about this a bit and was wondering if the setup ends up getting complicated when time goes by. You may update Cordova to a newer version in the app package you have in stores. That would mean that you would have to host different Cordova (and plugin) JavaScript to different platforms, but also for all the app package versions you have deployed via stores (because not all of the end users update at the same time). From this perspective, a better approach would be to load Cordova from the local folder where there already is the correct version of the JavaScript files. As a proof-of-concept of this model, I implemented an example at https://github.com/vjrantal/manifoldjs-cordova-example that conditionally loads Cordova and uses functionality from a plugin. The biggest limitation I see at the moment is on iOS 9.0 the case where you need to serve your site over a secured connection. I am still trying to find a workaround, but no luck so far. The case works on iOS version < 9.0, but that doesn't help since an app must work with the latest. As a side note, I think this same limitation would be there even if you host the Cordova files in your Web server. @boyofgreen Let me know how you feel about the approach described above. If you agree that it is a good model, I'll try to get a required commit upstreamed and some further documentation (as a blog post) to make it easier for someone to adapt the approach. |
We actually talked about this tool. The idea we had was to do them as js injection into the page. I'll email you the POC one of the developers started working on. If we did injection (copy js code, concat, inject) in place of your flie load: |
I didn't actually expect it would, but based on the my testing, this would get around the limitation. The limitation was that on iOS 9.0, a |
A fairly decent workaround (that at least buys some time) is to use an older SDK. |
@boyofgreen Right - I'm farily new to this - so what you're saying is that you check on the client what version of cordova is running, and based off that you then inject the required scripts, pretty much like @vjrantal has done, but sourcing the extra scripts from the server, right? |
I'm playing with this now.. in a simple test I'm serving the cordova files from the server, based on inspecting the user agent strings. An issue I have with this solution is that I want to send the cordova files ONLY if the web pages are being served via the cordova app - I don't want to do this if they're requested from the mobile browser. I think to solve that, I need to set a custom user agent string for the webview in cordova, which itself is tricky, because I'm working with a I'll keep digging away at this .. |
@mattwoberts : Instead of looking for the custom user agent, I think it might be better in a live environment to point another domain/subdomain to the same www/public_html folder on your web-server, and then check for the domain name in the host [window.location.hostname in JavaScript] / [$_SERVER['HTTP_HOST']) in PHP]. So www.domain.com can render the site without cordova js and app.domain.com can render the site with the cordova js injected dynamically. |
@yasin-siddiqui Hmm, that sounds reasonable - it would also allow me to do the "am i running in the mobile app" check both on the server and on the client easily enough.. Assuming there's not too many hard coded links in the app to worry about, I'll try that... |
+1 The use case above is extremely interesting because IMHO it is the "normal" progression if using this approach (making use of existing investments in a web site/application). My n00b tinkering with the approach so far has me hitting this behavior described on SO which I believe underscores the importance of detecting and loading (only) for the right platform (including desktop, mobile browser). The behavior is also reproducible by loading the generated @vjrantal - your post/sample is illuminating - thank you. @yasin-siddiqui - being the noob, I'm likely very wrong here, but IINM, |
@EdSF Ya, if you try to load the cordova files and you're not running in the webview (in the packaged app) then you get all sorts of horrible errors like that. That's why we need to only load the cordova.js files when we're being run inside the packaged app. The suggestion made by @yasin-siddiqui is a simple "hack" - have a different subdomain that just points to the regular app. That way, in the server-side code, you can check the host - if it's "mobile.myapp.com" then you write the script tags for the cordova.js files, otherwise you skip 'em. It's a good suggestion, but not one that's going to work for me (SSL issues, I'd need to buy additional SANs), so I'm mulling over alternatives.... I either go back to the user agent, or I do something like pass a querystring in the webview URL (something like www.myapp.com?mobile=true) - and then set something on the session when that's set - but then sessions expire so that's not good, plus sessions are generally evil. |
We're working on a few ideas here as well. We think we can make some decisions on the client to inject the proper version of the cordova.js file so that the hard part of determining the os is done for you. we just need to get enough time to do some research and testing. |
@boyofgreen Any idea on timeframes for that - also, is there anything I can do to help? |
@boyofgreen Could you give a TL;DR for how you're approaching this - I need to do something similar pretty soon so a brief description of how you're going about this would be awesome :) |
We've already made some progress that will allow the use of Cordova plugins in a hosted web app. We now support injecting Cordova and the plugin interface scripts into the pages of the hosted site. We're still working on this feature and it's not published yet, but if you're interested, you can start playing with it right now if you're willing to follow a few manual steps. You can find detailed information about the new plugin support in this wiki article. We implemented two different plugin modes: server and client. In 'client' mode, the cordova.js file and the plugin interface script files are retrieved from the app package. In 'server' mode, these files are downloaded from the server along with the rest of the app's content. We also implemented a mechanism for injecting scripts that can be used, among other things, to consume the plugins added to the app. Imported scripts can be retrieved from the app package or downloaded from a remote source. Until ManifoldJS is updated to use the new features, you will need to manually replace the hosted web app plugin in your app. The wiki article provides a Quick Start that explains the process. Very briefly, these are the steps that are needed to use plugins:
To inject scripts into the hosted web content:
|
@f2bo This sounds brilliant, thanks - you saved me from a world of pain trying to sniff UA strings ;) I actually met @boyofgreen yesterday in Manchester, UK, and he told me you were working on this :) I'll be sure to check it out soon |
👍 I must play with this in the next few days @f2bo - thank you! |
I find the "server" vs "client" a bit confusing... why not just call it "locally" "remotely" or local/remote Or give it a baseurl which could be a msapp-x: url (or what it is called) for local plugins |
Agree that "server" and "client" might cause some confusion, but wondering if "locally" and "remote" will cause a similar effect. Perhaps the confusion is not in the values of the setting, but rather in its name ( In any case, this setting is only required to override the default value, which is "client". We believe that most developers will stick with "client" mode and this setting will not be used frequently. |
"self-distributed": false? |
I don't like "source", as "source" or "src" normally expects a url as value. |
So, you fetch the cordova plugin before packaging the app, or are they downloaded when running the app first time, or how does it work? |
"So, you fetch the cordova plugin before packaging the app, or are they downloaded when running the app first time, or how does it work?" Plugins are installed at design time using the regular Cordova mechanism (i.e. cordova plugin add cordova-plugin-xxxx). This embeds the plugin's native code and its Javascript interface files in the app's package. So far, this is standard Cordova. At runtime, a stub loader is injected into the hosted web pages where API access has been enabled. Depending on the configured plugin mode, the loader injects cordova.js into pages by retrieving it from the app's package (client mode) or by downloading it from the site (server mode). Once Cordova is loaded into a page, it also loads any plugins that were added to the app. The stub loader also intercepts the loading of these plugin interface files and handles them in the same way as cordova.js, retrieving them from the app package or the site depending on the mode. There's additional information in the wiki. |
Retrieved from which server? The Cordova repo? At least to me it sounds like something people would rarely change and my suggestion would then be to turn it into a boolean instead. like
or "fetch_scripts_from_server" Then even if people also distribute the scripts in their package, it will always go out and refetch them from the repo (makes it easy to do experimentation" |
..."Retrieved from which server?"... That would be whatever server you specify in the baseUrl setting. Typically, this setting will contain a relative path pointing to the location of the Cordova files in the hosted site, though it can also be a full URL pointing to a different origin. Even if you assume that the Cordova files are always stored in the hosted site, in 'server' mode you still need the baseUrl setting to specify the path to these files. |
This is working well for me - thanks for the efforts 👍 IMHO, I'm also happy with the server/client distinction in the manifest |
Then why not let it be "client" if no (or a local url) is defined as the baseUrl? I mean, you can infer it from that. |
That´s how it works. If you don't specify a plugin_mode, it defaults to client. The base_url is not used in this mode (you don't need to specify a local URL), so you can skip the entire mjs_cordova section for client mode. |
Then why do you need plugin_mode at all? :-) if base_url is set, you can easily infer whether the plugin_mode should be server. |
closing old issues, looks like it was solved for those who needed itt |
A common scenario would be to create a wrapper for a hosted web app, and then compliment that by adding some additional things like push notifications support etc). I'm unsure what the process is when you want to do this - you can add for example the plugin for push notifications, and then add the code to allow this to www/js/index.js, but this code won't fire, since the launch URL is the hosted web app URL itself...
From what I can see from reading around (http://code.tutsplus.com/tutorials/build-a-hosted-web-app-on-android-ios-and-windows-using-manifoldjs--cms-24444) it seems that the way to do this is to just add the cordova js files that are required directly to your web site, and then include them as script files in your html - am I on the right track here?
The text was updated successfully, but these errors were encountered: