Hi there, I’ve been working towards migrating my v1 app to WKWebView. There are several issues I need to figure out a solution for, but here are a few I am hoping others have faced (and solved):
-
Due to enforced CORS issue, several well known APIs don’t work anymore with browser http. Here are some examples https://api.github.com/repos/pliablepixels/zmNinja/releases/latest
as well as https://medium.com/zmninja/latest?format=json
- all from popular sites, don’t work due to missing Access-Control-Allow-Origin
headers. It’s unreasonable to expect them to insert a localhost:8080
- why would they do that? How have others solved these issues?
-
I realize there is a cordova-advanced-http
plugin that can sidestep this. Is anyone aware of a angularjs wrapper that switches between this and browser $http - my app needs to work in both desktop and mobile. There is a wrapper written by a contributor, but that’s for Angular, not AngularJS. If there isn’t one, can someone point me to some simple template that can help me start writing one? I don’t want to replace all code elements around my codebase. Would prefer to keep $http
everywhere
-
Here is the zinger. Even if I use cordova.plugin.http
for regular APIs, I need to use the browser <img src>
tag to display images that need to borrow credentials from these API calls. Will it work - because img src
always uses a browser http function. I know there are several replacements to img
but none of the handle streaming images. Thanks.
Understandably, ionic v1 has more or less become an echo chamber now.
Anyway, I’ve made progress and figured out how to write what I need. It needs cleanup and error/fixing which I will do over the next few days but in general it involves:
- using a decorator
- Making sure you ignore local template/url/asset requests
- parse response to JSON or not, depending on
responseType=='text'
- Make sure we don’t use
.success
& .error
and use .then()
instead
- Convert
cordova-plugin-http
into one that returns promises
- encode the URLs before passing it
// Wraps around $http that switches between browser XHR
// or cordova-advanced-http based on if cordova is available
// credits:
// a) https://www.exratione.com/2013/08/angularjs-wrapping-http-for-fun-and-profit/
// b) https://gist.github.com/adamreisnz/354364e2a58786e2be71
$provide.decorator('$http', ['$delegate', '$q', function($delegate, $q) {
// create function which overrides $http function
var $http = $delegate;
var wrapper = function () {
var url;
var method;
url = arguments[0].url;
method = arguments[0].method;
var isOutgoingRequest = /^(http|https):\/\//.test(url);
if (window.cordova && isOutgoingRequest) {
console.log ("**** -->"+method+"<-- using native HTTP with:"+url);
var d = $q.defer();
var options = {
method: method,
data: arguments[0].data,
headers: arguments[0].headers,
timeout: arguments[0].timeout,
responseType: arguments[0].responseType
};
cordova.plugin.http.sendRequest(encodeURI(url),options,
function (succ) {
// automatic JSON parse if no responseType: text
// fall back to text if JSON parse fails too
if (options.responseType =='text') {
// don't parse into JSON
d.resolve({"data":succ.data});
return d.promise;
}
else {
try {
d.resolve({"data":JSON.parse(succ.data)});
return d.promise;
}
catch (e) {
d.resolve({"data":succ.data});
return d.promise;
}
}
},
function (err) {
console.log ("*** Inside native HTTP error");
d.reject(err);
return d.promise;
});
return d.promise;
}
else { // not cordova, so lets go back to default http
console.log ("**** "+method+" using XHR HTTP for "+url);
return $http.apply($http, arguments);
}
};
// wrap around all HTTP methods
Object.keys($http).filter(function (key) {
return (typeof $http[key] === 'function');
}).forEach(function (key) {
wrapper[key] = function () {
return $http[key].apply($http, arguments);
};
});
// wrap convenience functions
$delegate.get = function (url,config) {
return wrapper(angular.extend(config || {}, {
method: 'get',
url: url
}));
};
$delegate.post = function (url,data,config) {
return wrapper(angular.extend(config || {}, {
method: 'post',
url: url,
data:data
}));
};
$delegate.delete = function (url,config) {
return wrapper(angular.extend(config || {}, {
method: 'delete',
url: url
}));
};
return wrapper;
}]);
3 Likes
Hi there,
First of all thank you for your thoughts and the snippet. I just have this problem because itunes dont accept anymore the old WebView and I need to adapt a old Ionic V1 App to work with WKWebView.
How ever I have not really an idea about this changes and I am not sure how to use/work with your snippet in my project. I would be happy if you can help me understand a little bit more what I need to change in my old Ionic App to make this work? How I use this snippet exactly, what else I might need to change?
thank you in advance