cordova inappbrowser iOS issues - ios

I am working on an app for both android and iOS that will be opening external links. I am currently using cordova-plugin-inappbrowser 1.0.1 to open my links and it is working perfectly in Android, but I seem to be running into the same problem that many other people have. In iOS, I do not get a toolbar to appear and thus am stuck as I cannot click on the "done" button (or back/forward buttons for that matter.) I have built the app using both phonegap build online and through the command line tools, with the same behavior in each instance. It does not work in either an emulated environment or a native device environment. I have been searching online and this seems to be an extremely common problem, but none of the proposed solutions have worked over the past 2 days and ~15 hours of testing (for just a stupid little link!) I would like to remain in-app, but would not be opposed to going to safari if that is the only solution. My relevant code and versions:
Phonegap cli-5.1.1 (iOS 3.8/Android 4.02)
Cordova 3.5.0-0.2.7
cordova-plugin-inappbrowser 1.0.1
config.xml relevent code:
<plugins>
<plugin name="InAppBrowser" value="CDVInAppBrowser" />
</plugins>
<feature name="InAppBrowser">
<param name="ios-package" value="CDVInAppBrowser" />
</feature>
index.html:
<link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" />
<link rel="stylesheet" href="jquery/jquery.mobile.structure-1.4.5.min.css" />
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="jquery/jquery-2.1.4.min.js"></script>
<script src="jquery/jquery.mobile-1.4.5.min.js"></script>
<script src="phonegap.js"></script>
<script src="cordova.js"></script>
<script src="cordova_plugins.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
//
document.addEventListener("deviceready", onDeviceReady, false);
// Global InAppBrowser reference
var iabRef = null;
function iabLoadStart(event) {
alert(event.type + ' - ' + event.url);
}
function iabLoadStop(event) {
alert(event.type + ' - ' + event.url);
}
function iabClose(event) {
alert(event.type);
iabRef.removeEventListener('loadstart', iabLoadStart);
iabRef.removeEventListener('loadstop', iabLoadStop);
iabRef.removeEventListener('exit', iabClose);
}
// Cordova is ready
//
function onDeviceReady() {
alert('Device is ready!');
//iabRef = window.open('http://apache.org', '_blank', 'location=yes');
//iabRef.addEventListener('loadstart', iabLoadStart);
//iabRef.addEventListener('loadstop', iabLoadStop);
//iabRef.addEventListener('exit', iabClose);
}
</script>
<style type="text/css">
.centeredImage
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
body
{
background: #000 !important;
background-image:url(backgrounds/1080widephone.png) !important;
background-size:cover !important;
}
.ui-content{
background: transparent !important;
}
.ui-page{
background: transparent !important;
}
.ui-footer{
background: transparent !important;
}
</style>
</head>
Various links (all act as buttons):
window.open('url' ,'_blank')
(NOTE: This appears to open in the default WebView for iOS and the inappbrowser for Android)
cordova.InAppBrowser.open('url' ,'_blank', 'location=yes' , 'toolbar=yes', 'toolbarposition=top' , closebuttoncaption=Return'
(NOTE: Nothing happens when I use this in either iOS or Android builds. I based this syntax off of the description)
My kneejerk reaction is that the plugin isn't loading, but I don't see how that can be the case if it is clearly working in an android build but not an iOS build using exactly the same code on phonegap build. Any help would be greatly appreciated, I feel like I'm running around in circles here!

I know this is a late response but I’ve found one possible solution.
In my case, I was using ngCordova’s $InAppBrowser within the Ionic framework to open a file or url. To test this, I was using Xcode’s iPhone simulator as well as Ionic’s “Ionic View” app. Within both of these options, $InAppBrowser will NOT show a “Back” or “Done” button.
However, if you open your project’s .xcodeproj in Xcode and run your application on an actual iOS device, the InAppBrowser should work as expected.
I spent hours on this issue only to discover Ionic View restricts the options of $InAppBrowser. However, I’m still not 100% sure as to why this doesn’t work in the iOS emulator.
Note: I believe all of this applies even if you’re directly using Cordova and not ngCordova.

The values for the options string in
cordova.InAppBrowser.open
needs to be a single string of name=value pairs separated by ,
So try:
cordova.InAppBrowser.open('url' ,'_blank', 'location=yes,toolbar=yes,toolbarposition=top,closebuttoncaption=Return');
Additionally you should make sure your application's links open with the IAB by hijacking them and opening them in the IAB and suppressing the default event... for example with JQuery to hijack all the links in a div with id "infoExternalContent" and open them in the IAB with some options set for iOS only (using Cordova device platform to detect platform):
$('#infoExternalContent').find('a').each(
function() {
var href = $(this).attr('href');
var iabOptions = (device.platform === 'iOS' ? 'location=no,enableViewportScale=yes,transitionstyle=fliphorizontal' : '');
if (href.indexOf('http') === 0) {
$(this).click(function(e) {
e.preventDefault();
cordova.InAppBrowser.open(''.concat(this.href), '_blank', iabOptions);
});
}
}
);

I don't use phonegap build, but I can't imagine that it wants all of this loaded ...
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script src="jquery/jquery-2.1.4.min.js"></script>
<script src="jquery/jquery.mobile-1.4.5.min.js"></script>
<script src="phonegap.js"></script>
<script src="cordova.js"></script>
<script src="cordova_plugins.js"></script>
cordova.js is loaded twice, along with phonegap.js. Just sayin'

If you uncomment
iabRef = window.open('http://apache.org', '_blank', 'location=yes');
What happens?
I would also try
cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');
If neither of those open a window to apache, I would readd the plugin.

Related

ng-include not working on iOS

Please help me on this issue, The below code is working fine on Android but not working on iOS. Its returning the error
XMLHttpRequest cannot load file:///var/containers/Bundle/Application/16B00380-9909-4D99-B4CA-B02DA895431B/Pilot%20Forge.app/www/templates/Menu.html.
Cross origin requests are only supported for HTTP
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
var Appclaim = angular.module("app_forge", []);
Appclaim.controller("claimController", function ($scope) {
$scope.MenuTemplate = {
Name: "Menu.html",
Url: "templates/Menu.html"
}
});
</script>
<form name="form" ng-app="app_forge" ng-controller="claimController">
<div>{{MenuTemplate.Name}}</div>
<div ng-include="MenuTemplate.Url"></div>
</form>
</body>
</html>
Just ran into this today - adding this to the config.xml under the ios platform section fixed it for me.
<preference name="scheme" value="app" />
<preference name="hostname" value="localhost" />
That and making sure you have the newest version of the iOS platform added / and that you are using WKWebView instead of the UIWebView.
Here's a GitHub issue that helped to find the answer:
Cordova not allowing https cross origin requests.
And here's a link to the article on Cordova's site:
UPDATED: How to handle the 'Deprecated API Usage - UIWebView' warning while uploading to the App Store
I guess iOS treats all file:// protocols as cross origin now. (iOS is proving to be a real pain to develop for.)

react native webview load from device local file system

I'm trying to load .html, .js, .css files from device's local file system into React Native WebView component. I was able to get the path to the index.html file but specifying this as the url for the WebView simply throws an error. How would I go about this? Please help!
In react native it is now possible to require an HTML file and use it as the source for the web view like this (the path is relative to the react-native file you use it in):
const webapp = require('./webapp/index.html');
and the use it in the WebView like this:
<WebView source={webapp} />
Unfortunately this does not load CSS and JavaScript files, that are referenced in the HTML. A solution could be, to write all the CSS and JS inline (e.g. by using a build process).
I was able to include html5/javascript into project by using { html: , baseUrl: } as source.
But to be frank, it's more like a lucky shot.
<WebView source={{ html: HTML, baseUrl: 'web/' }} />
I have index.html, which require pano2vr_player.js and pano.xml to make this code work.
const HTML = `
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="mobile-web-app-capable" content="yes" />
<style type="text/css" title="Default">
body, div, h1, h2, h3, span, p {
font-family: Verdana,Arial,Helvetica,sans-serif;
}
</style>
</head>
<body>
<script type="text/javascript" src="pano2vr_player.js">
</script>
<div id="container" style="width:100%;height:100%;">
<br>Loading...<br><br>
This content requires HTML5 with CSS3 3D Transforms or WebGL.
</div>
<script type="text/javascript">
// create the panorama player with the container
pano=new pano2vrPlayer("container");
window.addEventListener("load", function() {
pano.readConfigUrlAsync("pano.xml");
});
</script>
</body>
</html>`;
class PanoView extends Component {
render() {
return (
<View>
<WebView
style={{ flex: 1, width: 1024, height: 768 }}
source={{ html: HTML, baseUrl: 'web/' }}
javaScriptEnabledAndroid={true} />
</View>
);
}
}
And finally add files/folder ('/web' same as baseUrl) to XCode project
And it works! But I'm not sure how...
I stumbled upon the same issue and, after running in circles for hours trying all sorts of solutions, I finally solved it by following this tutorial. Major kudos to the author.
In the article there's some extra info which is a bit outdated, so here's the concise version instead:
create a folder in your main project root (e.g. /html);
put all of your files in a folder (e.g. Web, with index.html being your WebView entrypoint), give it a .bundle extension (e.g. Web.bundle), and place it into /html;
Now you have to add these files to the project so they are recognized and bundled together in your next build, this process is done differently in iOS and Android:
iOS: open your project in Xcode, drag n drop Web.bundle into the project's main folder, and confirm the dialog with the "Copy items if needed" option left unchecked;
Android: open /android/app/build.gradle and add:
android {
...
sourceSets {
main { assets.srcDirs = ['src/main/assets', '../../html'] }
}
}
Now rebuild your project from scratch to have your changes take effect.
In your WebView file, calculate the path to index.html and feed it to the WebView:
const sourceUri = (Platform.OS === 'android' ? 'file:///android_asset/' : '')
+ 'Web.bundle/index.html';
return (
<WebView
source={{ uri: sourceUri }}
originWhitelist={['*']}
javaScriptEnabled={true}
allowFileAccess={true}
/>
);
This will load your index.html and all of its js and css files, as long as they're included in the bundle.
You may have to wrap your own Native Module to do this. React Native's WebView uses UIWebView, for info on loading a local file take a look here: https://gist.github.com/amster/9160860
However it is recommended you use WKWebView, you can wrap one yourself relatively easily. There is currently a repo that is WIP: https://github.com/qrush/react-native-wkwebview
Accomplishing loading local resources using WKWebView can be found in this answer: https://stackoverflow.com/a/28676439/398136
Place this script in any file of ReactNative or your code, recomended to first or top index file.
And it will fix problem, tested on RN0.39
import { Platform } from 'react-native';
import { setCustomSourceTransformer } from 'react-native/Libraries/Image/resolveAssetSource';
setCustomSourceTransformer(function (resolver) {
if (Platform.OS === 'android'
&& !resolver.serverUrl
&& !resolver.bundlePath
&& resolver.asset.type === 'html') {
resolver.bundlePath = '/android_asset/';
}
return resolver.defaultAsset();
});

Phonegap deviceready not working when page visited second time

i am trying to create a map with phonegap + google maps for ios. It works fine the first time but if I navigate to another page and then I return again to my maps page, nothing seems to happen, seems like deviceready is not fired. Any idea?
<script src="phonegap.js"></script>
<script src="maparestaurante.js"></script>
<link href="styles/retina.css" rel="stylesheet" type="text/css" media="only screen and (-webkit-min-device-pixel-ratio: 2)" />
</head>
<body onload="onLoad()">
and the javascript:
function onLoad() {
document.addEventListener("deviceready", onLoad2, true);
}
function onLoad2() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
error('not supported');
}
}
As I said, this works fine the first time, but if maps section visited again, it will never work, when testing it in the browser everyting worked fine
thx in advance
deviceReady will be fired only once. when the app is initialized. When you want to fire the load function when the page is visited again, you need to call the function again in the "page view " (which ever event supported by your SPA framework)event.

Checking for navigator.globalization on deviceready returns undefined on iOS

I am using PhoneGap 2.2.0 on iOS and binding to the devicready event to see if the navigator.globalization object is there. I am getting undefined.
My code looks like this:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady()
{
alert('deviceready');
navigator.globalization.getLocaleName(function(d)
{
window.localStorage.setItem('localeLanguage', d.value);
console.log('localeLanguage: is'+d.value);
},
function(error)
{
console.log('error getting locale language');
});
}
The alert('deviceready') never fires. I am really at a loss here. I'm setting up my scripts as follows.
<script src="js/jquery-1.8.2.min.js"></script>
<script src="js/jquery.mobile-1.2.0.min.js"></script>
<script type="text/javascript" src="cordova-2.2.0.js"></script>
<script type="text/javascript">
//alert(typeof navigator.globalization);
</script>
<script src="js/jquery.ui.map.full.min.js"></script>
<script src="js/jquery.ui.map.services.min.js"></script>
<script src="js/jquery.i18n.min.js"></script>
<script src="js/languages.js"></script>
<script src="js/oakglobalization.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
<script type="text/javascript" src="js/custom.js"></script>
Any ideas would be helpful as this is a showstopper now.
Try :
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
to add you event listener.
And maybe try to update your cordova version. The current version is the 2.6.0.
Another point : with phonegap, use the Navigator.notification.alert method instead of the native javascript alert. More info here.
Hope this helps ! Bye !
Not sure if you solved it or not, but at least for me ( PG 3.3.0 ) using navigator.globalization I had to install the cordova plugin and change the XML accordingly.
command-line> cordova plugin add org.apache.cordova.globalization
config.xml>
<feature name="Globalization">
<param name="ios-package" value="CDVGlobalization" />
</feature>
On that note, it didn't work on browser emulators ( ie.: ripple ) only on the real iOS xcode emulator ...
Backup your project just in case ;)

jquery mobile + phonegap onclick

I've been trying to figure this out but still stuck.
so I'm using PhoneGap for iOS and JQueryMobile.
I'm trying to show alert when a button is clicked.
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here -->
<script type="text/javascript" charset="utf-8" src="cordova-1.6.1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js">
</script>
and I have
this
Login
$(document).ready("#button").click(function() {
alert('button clicked');
});
when I tried to launch this in chrome, this works fine.
however, when I used iphone simulator, it doesnt show anything.
For a normal web application you would use dom ready i.e.
$(function(){ // <-- this is a shortcut for $(document).ready(function(){ ... });
$('#button').click(function(){
alert('button clicked');
});
});
However in a JQM application it is much more useful to bind to 'pageinit' i.e.
$(document).on('pageinit','[data-role=page]',function(){
$('#button').click(function(){
alert('button clicked');
});
});
Binding to pageinit works better because JQM inserts new pages into the same dom as the first page. Because of this all of your code in dom ready doesn't get called again. So that first bit of code i put above will only work for that first page in your JQM application. The second will work no matter what page your button is in. Let me know if I can clarify this further for you.

Resources