Titanium.Network.HTTPClient caches responseData. How do I prevent that? - android

I was wondering how to prevent Titanium.Network.HTTPClient from caching my responseData? This is happening on android in the directory /sdcard/Android/data/com.packagename/cache/_tmp the files follow this pattern for their filename tihttp-XXXXXXXXXXXtmp. I've already implemented a custom cache in the apps private data directory. So I don't need it to happen twice and waste the users precious data space on their sdcard. Plus the cache in the sdcard isn't always there.

var client = Ti.Network.createHTTPClient({
onload : function(e) {
Ti.API.info("Received text: " + this.responseText);
alert('success');
},
timeout : 5000,
cache : false,
});
The above works for iPhone only after a bit of looking, but if you set the headers directly to the request, it should work for both iPhone and Android:
client.setRequestHeader('Cache-Control','no-cache');
client.setRequestHeader('Cache-Control','no-store');
This must be called after open, but before the request is sent, i.e.:
var client = Ti.Network.createHTTPClient();
client.open('GET','http://google.com/');
client.setRequestHeader('Cache-Control','no-cache');
client.setRequestHeader('Cache-Control','no-store');
client.send('nice');

Related

Uploadprogress in Ionic

I have a form in which user can add information and add images. The images are base64 encoded so everything is stored in a json object. This object is sent to the server (with $resource) when the user submits it.
If a user adds for example 3 Images with about 2MB per Image, has a shitty connection like Edge, and wants to upload it it seems like it's taking forever. The user just sees the $ionicLoading overlay without information how long it will take or how much % are already uploaded.
The UX is bad because the user could assume, that the app froze or is in an endless loop and that it's just a bad app.
I have the following ideas but no idea if they are possible or
Is there a way in angular, cordova or ionic to get the browserinformation how much % are already uploaded?
Is there a way to get the current uploadspeed? I could get the size of my object by getting the length of my stringified JSON Object, divide it 1024 to get the kB. Then i would check the current uploadSpeed every second and add the current uploadspeed to a variable. With this information i could calculate the uploaded % approximately
JQuery ajaxForm Plugin?
Sounds like what you are looking for is progress events from XHR2.
Assuming your server is setup to handle XHR2 and return content-length, In plain JavaScript:
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function(e) { ... };
// Listen to the upload progress.
var progressBar = document.querySelector('progress');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
}
};
xhr.send(blobOrFile);
}
upload(new Blob(['hello world'], {type: 'text/plain'}));
Upload speed is also calculable using the information returned in the progress event, as you described.
As for this implementation in AngularJS/Ionic, it seems like this is a longstanding issue within the framework that $http doesn't really support progress events.
I have seen implementations that utilize a special angular directive written for this, or even utilize a jQuery file upload implementation.

Catching errors loading Remote Images in Titanium ImageView

I'm using Titanium SDK 3.4.0 GA, developing an Android app that load remote images from my web server to an ImageView.
The problem comes when the device lost connectivity during the load of that images, so, what I need is a way to catch that error (timeout, 404...) and set an "imageNotAvailable".
I'm using Network Link Conditioner for MacOSX to reproduce that scenario, with low latency, lost of packets...
To prove this I use the following code in my test.js (Alloy Controller) and a simple view with an ImageView with id='imageView' in my test.xml.
Sometimes, throws an exception:
TiDownloadManager: (pool-4-thread-1) [45929,118581] Exception downloading http://...
but not always (remote connection timeout seems infinite), anyway with this exception and without this I can't catch this (probably due to the asynchronous request) nor fires the ERROR event.
function imageNotAvailable(e)
{
Ti.API.info('Error loading image:'+JSON.stringify(e));
$.imageView.image = "/imageNotAvailable.png";
}
function onLoad(e)
{
Ti.API.info('Image Loaded:'+JSON.stringify(e));
}
function setImageAndroid(image)
{
try{
$.imageView.image = 'http://....';
}catch(e){
$.imageView.fireEvent("error");
}
$.imageView.addEventListener("error", imageNotAvailable);
$.imageView.addEventListener("load", onLoad);
}
Excuse my bad English! Thanks!
Have you tried adding your event listeners before setting the imageView's image property?
i can suggest a way around using http request
create a function in some library class which accepts the url that you are supposed to hit
Connection.getImage = function(link){
var xhr = Titanium.Network.createHTTPClient({
onload : function(e) {
var responseResult = this.responseText;
callback(responseResult);
},
// function called when an error occurs, including a timeout
onerror : function(e) {
callback("fail");
// Ti.API.info('IN ERROR ' + e.error);
},
timeout : 5000
});
xhr.open("GET", link);
xhr.send();
};
// ps you will receive a blob in response which you can attach to imageView.blob property , an it would suggest using a default image which will act as placeholder until you get the success response.

Setting dajax cache false

I'm using django v.1.6 and dajaxice v.0.6. I've run into a problem with ajax not functioning on some android devices running Chrome.
From what I understand, this is a caching problem. People using ajax on it's own seem to be getting round the problem by setting the cache to false within the ajax function. An example from here shows how you might normally go about this with ajax.
$.ajax({
url: "yoururl.html",
context: document.body,
cache : false,
data: {
username : $('#username').val(),
password : $('#password').val(),
},
success: function ( data ) {
// do something
}
});
And apparently that doesn't always work as in a reply to the previous code segment, someone has responded that after jQuery 1.7.1 you may need to add a timestamp like so:
$.ajax( { url: "someserver/somepath/blah" + "?_=" + jQuery.now(), type: "PUT", data: somedata});
Here is an example of the code I'm trying to get to work:
function refresh_word(){
Dajaxice.game.refreshWord(Dajax.process,{'game_id':{{game.id}},'player_id':{{player.id}}});
}
Like I said, this works on iPhones and desktop browsers but fails on some android devices.
I'm clutching at straws, I tried disabling the cache for the entire page but it still doesn't seem to work.
$(document).ready(function() {
$.ajaxSetup({ cache: false });
});
Is there a way to do this with dajax?
Thanks in advance for any help!

Cookie corruption with multiple createHTTPClient Titanium calls

While creating an Android app in Appcelerator's Titanium that involves both webView and background calls, I ran into a problem / bug where the cookies were getting corrupted on multiple createHTTPClient calls.
Cookies were originally obtained from the webView:
var webview = Ti.UI.createWebView();
webview.url = 'http://www.example.com';
window.add(webview);
webview.addEventListener('load', function(e) {
cookies = e.source.evalJS("document.cookie");
Titanium.App.Properties.setString('cookies',cookies);
}
window.open({modal:true});
and then later used with a background call:
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();
The first time the above createHTTPClient chunk of code was called, everything worked, but subsequent runs of the above code would send corrupted cookies. In Google App Engine (gae), printing out the request headers would look like this (broken):
logging.info('Request:\n%s' % self.request)
broken response (only the cookie portion of the request header is shown)
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7", auth=eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357225569|7a469fab7a38a437649c25620729e07c4607f617
Cookie2: $Version=1
working response
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7"
...
I suspect the issue has something to do with unicode characters or something inside createHTTPClient. Two auth= statements are shown in the corrupted cookie.
In summary, when the app first launches, the background Titanium.Network.createHTTPClient call works, and any calls after that appear to send corrupted cookies.
The HTTPClient documentation says "object is intended to be used for a single request," so I assumed everything would reset after multiple calls. But something was different after the first call.
Adding loader.clearCookies(base_url); to the code before setting the cookies seems to fix the issue.
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.clearCookies(base_url); // THE FIX.
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();

timeout parameter does not make any effect on Titanium.Network.createHTTPClient

I want user to wait for specified time(4seconds) to get connected to server. If it cannot connect within the specified time period, application should get closed.
Here is what I have coded:
var downloadDataReq = Titanium.Network.createHTTPClient({timeout :4000});
downloadDataReq.onload = function() { //some code }
downloadDataReq.onerror = function(event) { //some code }
var urlToDownloadData = 'http://www.google.com';
downloadDataReq.open("POST", urlToDownloadData);
downloadDataReq.send();
The Problem is that app waits for fix time (timeout parameter does not effect at all).
P.S.: making an app for android using Titanium.
Try to use method like this:
downloadDataReq.setTimeout(4000);
For me, timeout on HTTP requests aren't working as it should. I had very weird issues, such as:
If I put 1000ms timeout, it'll be called on 2 or 3 seconds.
If I put 2000ms timeout or above, it'll never be called.
I'm using Android ICS and JB, and on both I get the issues above. Seems that timeout parameter is buggy.
As a workaround, I'm doing checks inside onload (example: if I'm downloading a file, I compare the checksum of local file, with the checksum of the same file on the server), and I'm simulating timeouts with JavaScript's setTimeout. It's working to an extend.
The code below demonstrate how to simulate a request timeout, with JS's setTimeout command:
var downloadDataReq = Titanium.Network.createHTTPClient();
downloadDataReq.onload = function() {
clearTimeout(timeout);
alert('loaded');
}
downloadDataReq.onerror = function(e) {
clearTimeout(timeout);
alert('error: ' + e.error);
}
var urlToDownloadData = 'http://10.1.1.183/maquina_local/arquivos/FirefoxPortable_12.0_PortugueseBR.paf.exe';
downloadDataReq.open("GET", urlToDownloadData);
var timeout = setTimeout(function(){
downloadDataReq.onload = function(){
downloadDataReq.onerror({'error': 'timeout'});
};
downloadDataReq.abort();
}, 4000);
downloadDataReq.send();
On timeout, I'm changing onload event to onerror one, because if you try aborting a running request, it'll trigger 'onload' event, not 'onerror'. If you don't do it, this issue can give you corrupted files (ex: a 20mb file that, when request is aborted, file will be incomplete, with a size smaller than 20mb).
I'm still testing this solution, but at least for now, it solved a few bugs for me.
Try this.
Ti.App.timeOut = 99000; //declare in app.js
then use anyWhere in your project.But make Sure every time when you create a httpClient.
dont recreate or redefine in Code or through out the page.
this works fine for me.
//HAVE A LOOK OVER THE USE OF THIS
var xhr = Titanium.Network.createHTTPClient({timeout:Ti.App.timeOut});

Categories

Resources