Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25912] iOS: Ti.UI.iOS.createDocumentViewer doesn't work when using SDK-fix

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2018-04-03T16:44:34.000+0000
Affected Version/sRelease 7.1.0, Release 7.0.2
Fix Version/sRelease 7.1.1
ComponentsiOS
LabelscreateHttpClient, documentViewer, filesystem
Reporterjosh.mocek
AssigneeHans Knöchel
Created2018-03-27T22:04:07.000+0000
Updated2018-04-05T20:36:04.000+0000

Description

Ti.UI.iOS.createDocumentViewer does not work correctly in 7.1.0 Build the sample project and copy the files below. If you build the project w/ 7.1.0 on iOS >=11.2 and click on PDF or PNG it works, but DOCX, PPT, video, and XLS do not work and just show 'Loading...' forever. This is also after moving the files to the 'tmp' directory as stated in the docs to account for iOS 11.2. If you build the project w/ 6.2.2 on iOS >=11.2 all the files open correctly.

Attachments

FileDateSize
index.js2018-03-27T21:56:26.000+00004296
index.tss2018-03-27T21:56:26.000+0000144
index.xml2018-03-27T21:56:26.000+0000438

Comments

  1. Mike Stancliffe 2018-03-28

    This is holding up a release of ours, we have tested in 6.2.2 and everything works as expected, but we are needing to be on 7.1 for other fixes. Would love it if it were possible to get this regression fix into 7.1.1
  2. Hans Knöchel 2018-03-28

    Hey there! I've checked it and it looks like Apple also has some issues with the applicationCache directory. A simple fix is to change the Ti.Filesystem.tempDirectory references to Ti.Filesystem.applicationDataDirectory. Here is a working (classic) test-case based on your input (thanks for that!):
       function doClick(e) {
       	downloadFile(e);
       }
       
       function createButton(title, option) {
         var button = Ti.UI.createButton({
           top: 100 + (option * 2),
           title: title,
           option: option
         });
         
         button.addEventListener('click', doClick);
         
         return button;
       }
       
       var newFile2 = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, "New");
       if (!newFile2.exists()) {
       	newFile2.createDirectory();
       }
       
       var index = Ti.UI.createWindow({backgroundColor: '#fff', layout: 'vertical'});
       index.add(createButton('View PDF', 1));
       index.add(createButton('View XLS', 2));
       index.add(createButton('View PPT', 3));
       index.add(createButton('View PNG', 4));
       index.add(createButton('View DOCX', 5));
       
       index.open();
       
       function isiOS11_2() {
       	var version = Ti.Platform.version.split(".");
       	return (parseInt(version[0]) >= 11 && parseInt(version[1]) >= 2);
       }
       
       function fileInTemporaryDirectory(fileName) {
       
       	var newFile2 = Titanium.Filesystem.getFile(fileName);
       	newFile2.createFile();
       	if (!newFile2.exists()) {
       		alert('New file could not be created in applicationDataDirectory directory!');
       		return;
       	}
       
       	var splitFile = String(fileName);
       	splitFile = splitFile.split('/');
       	splitFile = splitFile[splitFile.length - 1];
       	var newFile = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, splitFile);
       	newFile.createFile();
       
       	if (!newFile.exists()) {
       		alert('New file could not be created in temporary directory!');
       		return;
       	}
       
       	newFile.write(newFile2);
       	var pathSep = Ti.Filesystem.applicationDataDirectory + splitFile;
       	console.info('pathSeperate\n ' + pathSep);
       	docViewer = Ti.UI.iOS.createDocumentViewer({
       		url: pathSep
       	});
       	docViewer.show();
       
       }
       
       var doneWithFile = function(file) {
       	if (file.error == null) {
       		var path = file.path + file.file;
       			if (isiOS11_2()) {
       				fileInTemporaryDirectory(path);
       			}
       	} else {
       		alert(file.error);
       	}
       }
       
       function downloadFile(e) {
       	// var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       	Ti.API.info(JSON.stringify(e));
       	if (e != undefined && e.source != undefined && e.source.option != undefined) {
       		switch (e.source.option) {
       			case 1:
       				var path = 'http://www.pdf995.com/samples/pdf.pdf';
       				break;
       			case 2:
       				var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       				break;
       			case 3:
       				var path = "http://www.unm.edu/~unmvclib/powerpoint/pptexamples.ppt";
       				break;
       			case 4:
       				var path = "https://upload.wikimedia.org/wikipedia/en/e/e5/ShereFASTticket-Example.png";
       				break;
       			case 5:
       				var path = "https://calibre-ebook.com/downloads/demos/demo.docx";
       				break;
       			default:
       				var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       				break;
       		}
       	} else {
       		var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       	}
       
       	var file_obj = {};
       	var url = path;
       
       	var splitFile = String(path);
       	splitFile = splitFile.split('/');
       	splitFile = splitFile[splitFile.length - 1];
       	var filename = "New/" + splitFile;
       
       	//Replace Spaces with %20 so IOS will not crash
       	if (url != null) {
       		url = url.replace(/\s/g, '%20');
       		file_obj = {
       			file: filename,
       			url: url,
       			path: null
       		};
       
       		var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
       	
       		if (file.exists()) {
       			file_obj.nativePath = file.nativePath;
       			file_obj.path = Ti.Filesystem.applicationDataDirectory;
       			doneWithFile(file_obj);
       		} else {
       			console.info('Ti.Network.online: ' + Ti.Network.online);
       			if (Ti.Network.online) {
       				var c = Ti.Network.createHTTPClient({
       					timeout: 10000,
       					onload: function() {
       						file_obj.status = this.status;
       						if (this.status == 200) {
       							var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
       							file_obj.path = Ti.Filesystem.applicationDataDirectory;
       							f.write(this.responseData);
       							file_obj.nativePath = f.nativePath;
       						} else {
       							file_obj.error = 'File not found.'; // to set some errors codes
       						}
       						doneWithFile(file_obj);
       						c = null;
       					}
       				});
       				c.onerror = function(e) {
       					file_obj.status = e.code;
       					file_obj.error = e.error;
       					doneWithFile(file_obj);
       					c = null;
       				};
       				c.open('GET', url);
       				c.send();
       			} else {
       				file_obj.error = 'No internet connection.';
       				doneWithFile(file_obj);
       			}
       		}
       	} else {
       		file_obj.error = 'No URL';
       		doneWithFile(file_obj);
       	}
       }
       
    Interesting enough: It works fine with PDF's - even with an untouched test-case, so it seems like PDF files are okay but others may not? Of course I've only tested with PDF files during the initial change for 7.1.0 so it probably went through. Still a buggy behavior on the native side, sorry for the trouble caused by that!
  3. josh.mocek 2018-03-28

    That does work. I tried putting it in a subdirectory in applicationDataDirectory, but I still couldn't access them there. PDF's still work fine
  4. Hans Knöchel 2018-03-28

    Thanks for testing! I am preparing a fix that moves all files to the application-data (root) directory to be picked up properly AND be removed if manually copied there. That also prevents possible storage leaks for larger amount of data as the file will be removed after finishing to present it. Does that make sense for your case as well?
  5. Hans Knöchel 2018-03-28

    PR: https://github.com/appcelerator/titanium_mobile/pull/9968 Backport: https://github.com/appcelerator/titanium_mobile/pull/9977 Test-Case:
       function doClick(e) {
       	downloadFile(e);
       }
       
       function createButton(title, option) {
         var button = Ti.UI.createButton({
           top: 100 + (option * 2),
           title: title,
           option: option
         });
         
         button.addEventListener('click', doClick);
         
         return button;
       }
       
       var newFile2 = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, "New");
       if (!newFile2.exists()) {
       	newFile2.createDirectory();
       }
       
       var index = Ti.UI.createWindow({backgroundColor: '#fff', layout: 'vertical'});
       index.add(createButton('View PDF', 1));
       index.add(createButton('View XLS', 2));
       index.add(createButton('View PPT', 3));
       index.add(createButton('View PNG', 4));
       index.add(createButton('View DOCX', 5));
       
       index.open();
       
       function isiOS11_2() {
       	var version = Ti.Platform.version.split(".");
       	return (parseInt(version[0]) >= 11 && parseInt(version[1]) >= 2);
       }
       
       var doneWithFile = function(file) {
       	if (file.error == null) {
       		var path = file.path + file.file;
       		var docViewer = Ti.UI.iOS.createDocumentViewer({
       			url: path
       		});
       		docViewer.show();
       	} else {
       		alert(file.error);
       	}
       }
       
       function downloadFile(e) {
       	// var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       	Ti.API.info(JSON.stringify(e));
       	if (e != undefined && e.source != undefined && e.source.option != undefined) {
       		switch (e.source.option) {
       			case 1:
       				var path = 'http://www.pdf995.com/samples/pdf.pdf';
       				break;
       			case 2:
       				var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       				break;
       			case 3:
       				var path = "http://www.unm.edu/~unmvclib/powerpoint/pptexamples.ppt";
       				break;
       			case 4:
       				var path = "https://upload.wikimedia.org/wikipedia/en/e/e5/ShereFASTticket-Example.png";
       				break;
       			case 5:
       				var path = "https://calibre-ebook.com/downloads/demos/demo.docx";
       				break;
       			default:
       				var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       				break;
       		}
       	} else {
       		var path = "http://opendatakit.org/wp-content/uploads/static/sample.xls";
       	}
       
       	var file_obj = {};
       	var url = path;
       
       	var splitFile = String(path);
       	splitFile = splitFile.split('/');
       	splitFile = splitFile[splitFile.length - 1];
       	var filename = "New/" + splitFile;
       
       	//Replace Spaces with %20 so IOS will not crash
       	if (url != null) {
       		url = url.replace(/\s/g, '%20');
       		file_obj = {
       			file: filename,
       			url: url,
       			path: null
       		};
       
       		var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
       	
       		if (file.exists()) {
       			file_obj.nativePath = file.nativePath;
       			file_obj.path = Ti.Filesystem.applicationDataDirectory;
       			doneWithFile(file_obj);
       		} else {
       			console.info('Ti.Network.online: ' + Ti.Network.online);
       			if (Ti.Network.online) {
       				var c = Ti.Network.createHTTPClient({
       					timeout: 10000,
       					onload: function() {
       						file_obj.status = this.status;
       						if (this.status == 200) {
       							var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);
       							file_obj.path = Ti.Filesystem.applicationDataDirectory;
       							f.write(this.responseData);
       							file_obj.nativePath = f.nativePath;
       						} else {
       							file_obj.error = 'File not found.'; // to set some errors codes
       						}
       						doneWithFile(file_obj);
       						c = null;
       					}
       				});
       				c.onerror = function(e) {
       					file_obj.status = e.code;
       					file_obj.error = e.error;
       					doneWithFile(file_obj);
       					c = null;
       				};
       				c.open('GET', url);
       				c.send();
       			} else {
       				file_obj.error = 'No internet connection.';
       				doneWithFile(file_obj);
       			}
       		}
       	} else {
       		file_obj.error = 'No URL';
       		doneWithFile(file_obj);
       	}
       }
       
    Expected behavior: All files should load in iOS < 11.2 and iOS >= 11.2.
  6. Eric Wieber 2018-04-03

    FR Passed. Able to load PDF, XLS, PPT, MP4, PNG, and DOCX files without issue. Tested using provided sample code as well as modified versions to accept other file types and the document viewer suite.
  7. Eric Wieber 2018-04-05

    Verified changes are in SDK builds 7.1.1.v20180405080421 & 7.2.0.v20180404233630

JSON Source