How to offer files for download? - sencha-touch

I have a problem. In my sencha touch application I have list items like .pdf, .png, ... If user taps on one of them file should be download on his mobile device.
How can I do this? I have no idea :-)
Thanks for help.

You can use phonegap file api to download files, If you are using sencha touch 2.3 or above just follow the bellow steps.
Install phonegap in sencha project by executing following command at the project root and this command creates phonegap folder inside project root.
sencha phonegap init
You need to install two phonegap plugins to work with file api by executing two following commands inside phonegap folder.
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git
Now you can start working file api in sencha touch and you can follow below code i used for one of my project.
If you want to download file, first you need to read device file system and then using file system you can download files.
getFileSystem : function(){
var me =this;
Ext.Viewport.mask({
xtype: 'loadmask',
message: 'Downloading files..'
});
var extfs = Ext.create("Ext.device.filesystem.Cordova");
extfs.requestFileSystem({
type: window.PERSISTENT,
size: 1024 * 1024,
success: function(fSys) {
window.fileSys = fSys;
Ext.Viewport.unmask();
me.fileDownload("myfolder/filename.png","http://someurl");
},
failure: function(error){
alert(error);
Ext.Viewport.unmask();
}
});
}
I am passing fileLocation(location you want to store file inside phone) & url in above function.
fileDownload: function(fileLocation,Url){
Ext.Viewport.mask({
xtype: 'loadmask',
message: 'Downloading files..'
});
var me = this;
var fSys = window.fileSys
if(fSys){
var file = Ext.create('Ext.device.filesystem.FileEntry',
fSys.fs.root.toURL() + fileLocation, fSys);
file.download({
source: Url,
success: function(entry){
Ext.Msg.alert('SUCCESS', 'Image successfully downloaded');
Ext.Viewport.unmask();
},
failure: function(error){
Ext.Msg.alert('ERROR', 'Download failed');
Ext.Viewport.unmask();
}
});
}
}
Now can see image at internalMemorycard/myfolder/filename.png
Sencha docs
Ext.device.filesystem.Cordova
Ext.device.filesystem.FileEntry
If you are using sencha touch 2.2 or below only change is instead of using sencha class you need to directly use phonegap api.
For reading file system & File download follow phonegap documentation.

Sencha basically operates over HTML, CSS & JS. Rather than doing this using Sencha just implement it similar to how you would do it in HTML then integrate into your application.
Eg: Homework

Try this
document.location= url;

Try the following code it may help you.
var newWindow = window.open('filepath', '_self'); //were filepath is the path of file with extension.

Related

how to upload a file with karate?

I know the question has already been asked, but I’m having trouble uploading a file with karate.
I have a file called "example.pdf" in my project. I put this document in a "assets" folder
I tried to build on the example of the documentation here.
https://github.com/karatelabs/karate/tree/master/karate-core#file-upload
and here’s my code:
* configure driver = { type: '#(driverType)', executable: '#(driverExecutable)', addOptions: #(driverOptions), headless: #(driverHeadless), webDriverSession: #(webDriverSession), showDriverLog: true }
Given waitFor('#upload)
And driver.inputFile('#upload', '../assets/pdf-exemple.pdf')
My browser is chrome
what am I missing ?
Thanks for your help
EDIT:
Thank you for your feedback, I’ll try to clarify.
Meanwhile I have some details. In fact the browser is chromedriver and geckodriver
const drivers = {
path: "./src/test/java/drivers/",
chromedriver: "95.0.4638.69",
geckodriver: "0.30.0",
};
So I think I have to use the approach "multipart file".
I tried this code, and my test passes without error, but does not handle the expected functionality (uploading an attachment)
And url 'https://url file file to upload/test' //page where is the area to upload a file
And waitFor(data.inputPJ).click() //area where you click on the application to upload a file
And multipart file file = { read: '../../assets/pdf-exemple.pdf', filename: '../../assets/pdf-exemple.pdf' }
And method post
But in my application this code has no effect, in the application I should have :
But the uploaded file doesn't appear, and I have:
The difficulty here is that I have no mistake. I will continue to try to understand the doc
I am at your disposal to provide more information

React-native packager configuration - How to include .zip file in bundle?

My problem:
I have a zip file that contains a firmware update for my company's device
I want to be able to access it using react-native-fs with the code below
.
export function readAssetFile(name) {
if(Platform.OS === 'ios') {
return RNFS.readFile(`${RNFS.MainBundlePath}/assets/data/${name}`);
} else {
return RNFS.readFileAssets(`raw/${name}`, 'base64');
}
}
My project structure looks like:
ProjectDir
android
data
image1.png
image2.png
firmwarefile.zip
ios
The android branch works, because I added a build step in my .gradle to copy firmwarefile.zip into ProjectDir/android/app/src/main/assets/raw. So I can call readAssetFile('firmwarefile.zip'), and it returns the data.
On iOS, all the image files (Image1.png, Image2.png) are included in MyProject.app/assets/data/ without me having to do anything, but the zip file that sits beside them is not.
Looking into the actual packager code (from the metro project), it seems (based on metro/src/defaults.js) that zip files aren't included by default by the packager, but the packager can be configured to include other file types. But I can't find any documentation for how I'd go about doing that configuring.
Sorry for what feels like a really simple question, but I've been trying to get this zip included in my bundle for ~4 hours now. I'm resorting to manually putting in console.logs and error-throws to trace things inside metro to try and find where I should be sending in my config.
Versions:
React-native: 0.55.3
Metro: 0.30.2
This is a hack, but it gets it done:
Convert your zip binary to a base64 string
Stick it in a .js file, a la module.exports = "<your base64 data goes here>"
In your file that needs the zip file, use import myZipFileAsBase64 from './hacky-base64-file.js';
Here's a quick script to make your base64 files:
var fs = require('fs');
function prepareZip(file, outJs) {
const b64 = fs.readFileSync(file, 'base64');
fs.writeFileSync(outJs, `module.exports = ${JSON.stringify(b64)};`);
}
prepareZip('./data/myFirmware.zip', './hacky-base64-file.js');

Sencha Touch [APPNAME].app is undefined only when testing with Jasmine

I'm trying to set up some test cases for a view using the Jasmine 2.3.4 assertion library for my Sencha Touch 2.4 app. Things seem great (I see the view rendered to a div) except the browser does not know what MyApp.app is. I have this line at my onContainerInitialize function from my view/container code:
var controller = MyApp.app.getController('loginController');
which gives this Jasmine error:
TypeError: Cannot read property 'getController' of undefined
At the time the Jasmine tests are called, from my console I do have a MyApp global object with the following structure (attached). If you expand app you will see the class name of the controller listed in an array under _controllers. The line that causes this error in my spec file is:
var myView = new MyApp.view.someViewName({ renderTo: 'test' });
I modeled my setup after a few tutorials, one of which is Sencha's https://docs.sencha.com/extjs/4.2.5/#!/guide/testing
(wish there was one for a recent version of Touch). I think my problem may be related to this note midway down that page:
Note: this Application definition is not a copy and paste of your
regular Application definition in your app.js. This version will only
include the controllers, stores, models, etc and when launch is called
it will invoke the Jasmine tests.
It may be related, but I also couldn't follow their:
ctrl = newMyApp.controller.MyController();
where I would get this error:
TypeError: app.getRouter is not a function at Ext.define.applyRoutes (http://localhost:8080/touch/sencha-t...ug.js:45800:26)
Instead, I had to add in this argument like this:
var ctrl = new Kaacoo.controller.loginController({ application : app });
Additionally, my launch file is set up like this:
Ext.require('Ext.app.Application');
Ext.Loader.setConfig({
enabled: true,
disableCaching: true
});
Ext.Loader.setPath('MyApp', '../../app');
// this file is a couple levels deep from the root of my project
Ext.application({
name : 'MyApp',
extend: 'MyApp.Application',
autoCreateViewport: true,
controllers: [
'loginController'
],
requires : [
],
launch: function() {
// Jasmine is bootstrapped with boot.js referenced in the html runner, so nothing here. My test specs are being called after this launch function is executed.
}
});
The order I have listed my resources in my html runner are: Jasmine Library with boot.js> Touch All Debug Library > Project Source Files > Spec Files > Launch file
Building and simulating the app is fine, so why can't I also have access to MyApp.app.getController('loginController') as well in my test environment?
Thanks!

I want to open a PDF file within the application in titanium studio

I have URL of PDF file and want to open within the application so that i can navigate back to application. I don't want to go to browser. Can anyone help?
Check this out:
iOS:
http://docs.appcelerator.com/titanium/3.0/#!/api/Titanium.UI.iOS.DocumentViewer
Android
http://developer.appcelerator.com/question/72361/open-pdf-file-on-android
Or you could try and show it in a webview:
var pdfViewer = Ti.UI.createWebView({
url: "url.pdf",
width:1000,
height:1000
});

Ensure phonegap and plugins load before Sencha loader

I have written an application in Sencha Touch 2.1, of which I embed a package build into Cordova/PhoneGap 2.5.0 and compile in xCode to run on iOS Simulator / iOS. I have added the PGSQLite plugin to PhoneGap, and built my own PhoneGap/SQLite Proxy for Sencha, which I used on a few of my Stores.*
Problem: When I embed a package build into PhoneGap and run in iOS Simulator, I see that Cordova does not load before Sencha initializes. I see this because my calls in my Sencha app to Cordova.exec that I make in my Proxy initialization result in an error telling me that the Cordova object cannot be found.
I do successfully use Cordova.exec later in my application to run things like the Childbrowser plugin for PhoneGap, and it works. But using Cordova.exec at an early stage in the app's execution, i.e., initialization, is too soon to guarantee that the Cordova object will have been instantiated.
Already tried: I already tried the following approaches:
I tried simply embedding the developer build of my Sencha app into PhoneGap. Although this worked, I don't want to deploy my development build as my released app because it is inefficient and takes up a lot of space. I have learned from this experiment, however, that the way the Sencha Touch microloader works on package and production builds loads PhoneGap after Sencha. This can be clearly seen when inspecting the DOM after Sencha loads in a package build.
I have already configured my app.json file to include PhoneGap and
my plugins before app.js and the Sencha Touch framework. Playing
with the order of my JS file references in my app.json did not
seem to affect the load order.
I also tried creating a script loader, as described here
(StackOverflow). I then ran the script loader for Cordova, and in
the callback for that, ran the script loader for my plugin, and
then, finally, in the callback for that, ran the Sencha Touch
microloader. This resulted in an error. Additionally, I had to
manually set that up in my index.html file after Sencha built my
package. This seems unacceptable.
What I am looking for: I am looking for answers to the following:
Is there a way to configure Sencha's microloader or my Sencha app in general so that Cordova is ensured to have loaded before Sencha's microloader runs?
Is there a way to set this up so that using Sencha Cmd still works, and I don't have to hack around in my index.html file after I build the app?
Note:
*Please don't suggest I use the existing, so-called, SQLite Proxy for Sencha. I specifically chose my approach because, though I appreciated the existing work on a SQLite proxy for Sencha Touch 2 (namely, this), it is actually a WebSQL proxy that does not store natively in SQLite on iOS. My proxy uses the PGSQLite plugin for PhoneGap to natively store data in SQLite on iOS. I plan to open-source it when I have an opportunity to clean it up and untangle it from my code.
I ended up solving this myself by building a custom loader. I am not sure if there is a more Sencha-ish way to do it, but here are the details of what I did, which does work, in case anyone else wants to ensure that PhoneGap is completely loaded in package and production builds before running anything in Sencha. (That would probably be the case in all scenarios in which PhoneGap is packaging a Sencha app).
My index.html file:
<!DOCTYPE HTML>
<html manifest="" lang="en-US">
<head>
<!-- Load Cordova first. Replace with whatever version you are using -->
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
function onBodyLoad() {
// Check for whatever mobile you will run your PhoneGap app
// on. Below is a list of iOS devices. If you have a ton of
// devices, you can probably do this more elegantly.
// The goal here is to only listen to the onDeviceReady event
// to continue the load process on devices. Otherwise you will
// be waiting forever (literally) on Desktops.
if ((navigator.platform == 'iPad') ||
(navigator.platform == 'iPhone') ||
(navigator.platform == 'iPod') ||
(navigator.platform == 'iPhone Simulator') ||
(navigator.platform == 'iPadSimulator')
) {
// Listening for this event to continue the load process ensures
// that Cordova is loaded.
document.addEventListener("deviceready", onDeviceReady, false);
} else {
// If we're on Desktops, just proceed with loading Sencha.
loadScript('loader.js', function() {
console.log('Finished loading scripts.');
});
}
};
// This function is a modified version of the one found on
// StackOverflow, here: http://stackoverflow.com/questions/756382/bookmarklet-wait-until-javascript-is-loaded#answer-756526
// Using this allows you to wait to load another script by
// putting the call to load it in a callback, which is
// executed only when the script that loadScript is loading has
// been loaded.
function loadScript(url, callback)
{
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = url;
// Attach handlers for all browsers
var done = false;
script.onload = script.onreadystatechange = function()
{
if( !done && ( !this.readyState
|| this.readyState == "loaded"
|| this.readyState == "complete") )
{
done = true;
// Continue your code
callback();
}
};
head.appendChild(script);
}
function onDeviceReady() {
console.log("[PhoneGap] Device initialized.");
console.log("[PhoneGap] Loading plugins.");
// You can load whatever PhoneGap plugins you want by daisy-chaining
// callbacks together like I did with pgsqlite and Sencha.
loadScript('pgsqlite_plugin.js', function() {
console.log("[Sencha] Adding loader.");
// The last one to load is the custom Sencha loader.
loadScript('loader.js', function() {
console.log('Finished loading scripts.');
});
});
};
</script>
<meta charset="UTF-8">
<title>Sencha App</title>
</head>
<!-- Don't forget to call onBodyLoad() in onLoad -->
<body onLoad="onBodyLoad();">
</body>
</html>
Next, create a custom loader in loader.js in your document root, alongside your index.html. This one is heavily based on the development microloader that comes with Sencha. Much props to them:
console.log("Loader included.");
(function() {
function write(content) {
document.write(content);
}
function meta(name, content) {
write('<meta name="' + name + '" content="' + content + '">');
}
var global = this;
if (typeof Ext === 'undefined') {
var Ext = global.Ext = {};
}
var head = document.getElementsByTagName("head")[0];
var xhr = new XMLHttpRequest();
xhr.open('GET', 'app.json', false);
xhr.send(null);
var options = eval("(" + xhr.responseText + ")"),
scripts = options.js || [],
styleSheets = options.css || [],
i, ln, path;
meta('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
meta('apple-mobile-web-app-capable', 'yes');
meta('apple-touch-fullscreen', 'yes');
console.log("Loading stylesheets");
for (i = 0,ln = styleSheets.length; i < ln; i++) {
path = styleSheets[i];
if (typeof path != 'string') {
path = path.path;
}
var stylesheet = document.createElement("link");
stylesheet.rel = "stylesheet";
stylesheet.href = path;
head.appendChild(stylesheet);
}
for (i = 0,ln = scripts.length; i < ln; i++) {
path = scripts[i];
if (typeof path != 'string') {
path = path.path;
}
var script = document.createElement("script");
script.src = path;
head.appendChild(script);
}
})();
Notice that your index.html file does not contain a #microloader script element. That's because you should take it out and use your custom loader.
With all that in place, you will be able to sail smoothly, knowing that the whole PhoneGap environment is in place before your Sencha javascript starts doing things.