{ "id": "171411", "key": "TIMOB-25912", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20102", "name": "Release 7.1.1", "archived": false, "released": true, "releaseDate": "2018-05-02" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2018-04-03T16:44:34.000+0000", "created": "2018-03-27T22:04:07.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "createHttpClient", "documentViewer", "filesystem" ], "versions": [ { "id": "19957", "description": "", "name": "Release 7.1.0", "archived": false, "released": true, "releaseDate": "2018-03-14" }, { "id": "20060", "description": "", "name": "Release 7.0.2", "archived": false, "released": true, "releaseDate": "2018-02-09" } ], "issuelinks": [], "assignee": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2018-04-05T20:36:04.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "Ti.UI.iOS.createDocumentViewer does not work correctly in 7.1.0\r\nBuild the sample project and copy the files below.\r\nIf 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.\r\nIf you build the project w/ 6.2.2 on iOS >=11.2 all the files open correctly. ", "attachment": [ { "id": "64999", "filename": "index.js", "author": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-27T21:56:26.000+0000", "size": 4296, "mimeType": "text/javascript" }, { "id": "64998", "filename": "index.tss", "author": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-27T21:56:26.000+0000", "size": 144, "mimeType": "application/octet-stream" }, { "id": "64997", "filename": "index.xml", "author": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-27T21:56:26.000+0000", "size": 438, "mimeType": "text/xml" } ], "flagged": false, "summary": "iOS: Ti.UI.iOS.createDocumentViewer doesn't work when using SDK-fix", "creator": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "iOS >=11.2 w/ SDK 7.1.0", "comment": { "comments": [ { "id": "436027", "author": { "name": "cliff_stander", "key": "cliff_stander", "displayName": "Mike Stancliffe", "active": true, "timeZone": "America/Los_Angeles" }, "body": "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", "updateAuthor": { "name": "cliff_stander", "key": "cliff_stander", "displayName": "Mike Stancliffe", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-28T13:41:33.000+0000", "updated": "2018-03-28T13:41:33.000+0000" }, { "id": "436029", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "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!):\r\n{code:js}\r\nfunction doClick(e) {\r\n\tdownloadFile(e);\r\n}\r\n\r\nfunction createButton(title, option) {\r\n var button = Ti.UI.createButton({\r\n top: 100 + (option * 2),\r\n title: title,\r\n option: option\r\n });\r\n \r\n button.addEventListener('click', doClick);\r\n \r\n return button;\r\n}\r\n\r\nvar newFile2 = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"New\");\r\nif (!newFile2.exists()) {\r\n\tnewFile2.createDirectory();\r\n}\r\n\r\nvar index = Ti.UI.createWindow({backgroundColor: '#fff', layout: 'vertical'});\r\nindex.add(createButton('View PDF', 1));\r\nindex.add(createButton('View XLS', 2));\r\nindex.add(createButton('View PPT', 3));\r\nindex.add(createButton('View PNG', 4));\r\nindex.add(createButton('View DOCX', 5));\r\n\r\nindex.open();\r\n\r\nfunction isiOS11_2() {\r\n\tvar version = Ti.Platform.version.split(\".\");\r\n\treturn (parseInt(version[0]) >= 11 && parseInt(version[1]) >= 2);\r\n}\r\n\r\nfunction fileInTemporaryDirectory(fileName) {\r\n\r\n\tvar newFile2 = Titanium.Filesystem.getFile(fileName);\r\n\tnewFile2.createFile();\r\n\tif (!newFile2.exists()) {\r\n\t\talert('New file could not be created in applicationDataDirectory directory!');\r\n\t\treturn;\r\n\t}\r\n\r\n\tvar splitFile = String(fileName);\r\n\tsplitFile = splitFile.split('/');\r\n\tsplitFile = splitFile[splitFile.length - 1];\r\n\tvar newFile = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, splitFile);\r\n\tnewFile.createFile();\r\n\r\n\tif (!newFile.exists()) {\r\n\t\talert('New file could not be created in temporary directory!');\r\n\t\treturn;\r\n\t}\r\n\r\n\tnewFile.write(newFile2);\r\n\tvar pathSep = Ti.Filesystem.applicationDataDirectory + splitFile;\r\n\tconsole.info('pathSeperate\\n ' + pathSep);\r\n\tdocViewer = Ti.UI.iOS.createDocumentViewer({\r\n\t\turl: pathSep\r\n\t});\r\n\tdocViewer.show();\r\n\r\n}\r\n\r\nvar doneWithFile = function(file) {\r\n\tif (file.error == null) {\r\n\t\tvar path = file.path + file.file;\r\n\t\t\tif (isiOS11_2()) {\r\n\t\t\t\tfileInTemporaryDirectory(path);\r\n\t\t\t}\r\n\t} else {\r\n\t\talert(file.error);\r\n\t}\r\n}\r\n\r\nfunction downloadFile(e) {\r\n\t// var path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\tTi.API.info(JSON.stringify(e));\r\n\tif (e != undefined && e.source != undefined && e.source.option != undefined) {\r\n\t\tswitch (e.source.option) {\r\n\t\t\tcase 1:\r\n\t\t\t\tvar path = 'http://www.pdf995.com/samples/pdf.pdf';\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 3:\r\n\t\t\t\tvar path = \"http://www.unm.edu/~unmvclib/powerpoint/pptexamples.ppt\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 4:\r\n\t\t\t\tvar path = \"https://upload.wikimedia.org/wikipedia/en/e/e5/ShereFASTticket-Example.png\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 5:\r\n\t\t\t\tvar path = \"https://calibre-ebook.com/downloads/demos/demo.docx\";\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t} else {\r\n\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t}\r\n\r\n\tvar file_obj = {};\r\n\tvar url = path;\r\n\r\n\tvar splitFile = String(path);\r\n\tsplitFile = splitFile.split('/');\r\n\tsplitFile = splitFile[splitFile.length - 1];\r\n\tvar filename = \"New/\" + splitFile;\r\n\r\n\t//Replace Spaces with %20 so IOS will not crash\r\n\tif (url != null) {\r\n\t\turl = url.replace(/\\s/g, '%20');\r\n\t\tfile_obj = {\r\n\t\t\tfile: filename,\r\n\t\t\turl: url,\r\n\t\t\tpath: null\r\n\t\t};\r\n\r\n\t\tvar file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);\r\n\t\r\n\t\tif (file.exists()) {\r\n\t\t\tfile_obj.nativePath = file.nativePath;\r\n\t\t\tfile_obj.path = Ti.Filesystem.applicationDataDirectory;\r\n\t\t\tdoneWithFile(file_obj);\r\n\t\t} else {\r\n\t\t\tconsole.info('Ti.Network.online: ' + Ti.Network.online);\r\n\t\t\tif (Ti.Network.online) {\r\n\t\t\t\tvar c = Ti.Network.createHTTPClient({\r\n\t\t\t\t\ttimeout: 10000,\r\n\t\t\t\t\tonload: function() {\r\n\t\t\t\t\t\tfile_obj.status = this.status;\r\n\t\t\t\t\t\tif (this.status == 200) {\r\n\t\t\t\t\t\t\tvar f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);\r\n\t\t\t\t\t\t\tfile_obj.path = Ti.Filesystem.applicationDataDirectory;\r\n\t\t\t\t\t\t\tf.write(this.responseData);\r\n\t\t\t\t\t\t\tfile_obj.nativePath = f.nativePath;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tfile_obj.error = 'File not found.'; // to set some errors codes\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t\t\t\tc = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tc.onerror = function(e) {\r\n\t\t\t\t\tfile_obj.status = e.code;\r\n\t\t\t\t\tfile_obj.error = e.error;\r\n\t\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t\t\tc = null;\r\n\t\t\t\t};\r\n\t\t\t\tc.open('GET', url);\r\n\t\t\t\tc.send();\r\n\t\t\t} else {\r\n\t\t\t\tfile_obj.error = 'No internet connection.';\r\n\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t}\r\n\t\t}\r\n\t} else {\r\n\t\tfile_obj.error = 'No URL';\r\n\t\tdoneWithFile(file_obj);\r\n\t}\r\n}\r\n{code}\r\nInteresting 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!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-03-28T14:32:40.000+0000", "updated": "2018-03-28T14:32:40.000+0000" }, { "id": "436030", "author": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "body": "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", "updateAuthor": { "name": "josh.mocek", "key": "josh.mocek", "displayName": "josh.mocek", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-28T15:03:54.000+0000", "updated": "2018-03-28T15:03:54.000+0000" }, { "id": "436031", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "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?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-03-28T15:06:00.000+0000", "updated": "2018-03-28T15:06:00.000+0000" }, { "id": "436032", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR: https://github.com/appcelerator/titanium_mobile/pull/9968\r\nBackport: https://github.com/appcelerator/titanium_mobile/pull/9977\r\n\r\nTest-Case:\r\n{code:js}\r\nfunction doClick(e) {\r\n\tdownloadFile(e);\r\n}\r\n\r\nfunction createButton(title, option) {\r\n var button = Ti.UI.createButton({\r\n top: 100 + (option * 2),\r\n title: title,\r\n option: option\r\n });\r\n \r\n button.addEventListener('click', doClick);\r\n \r\n return button;\r\n}\r\n\r\nvar newFile2 = Titanium.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"New\");\r\nif (!newFile2.exists()) {\r\n\tnewFile2.createDirectory();\r\n}\r\n\r\nvar index = Ti.UI.createWindow({backgroundColor: '#fff', layout: 'vertical'});\r\nindex.add(createButton('View PDF', 1));\r\nindex.add(createButton('View XLS', 2));\r\nindex.add(createButton('View PPT', 3));\r\nindex.add(createButton('View PNG', 4));\r\nindex.add(createButton('View DOCX', 5));\r\n\r\nindex.open();\r\n\r\nfunction isiOS11_2() {\r\n\tvar version = Ti.Platform.version.split(\".\");\r\n\treturn (parseInt(version[0]) >= 11 && parseInt(version[1]) >= 2);\r\n}\r\n\r\nvar doneWithFile = function(file) {\r\n\tif (file.error == null) {\r\n\t\tvar path = file.path + file.file;\r\n\t\tvar docViewer = Ti.UI.iOS.createDocumentViewer({\r\n\t\t\turl: path\r\n\t\t});\r\n\t\tdocViewer.show();\r\n\t} else {\r\n\t\talert(file.error);\r\n\t}\r\n}\r\n\r\nfunction downloadFile(e) {\r\n\t// var path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\tTi.API.info(JSON.stringify(e));\r\n\tif (e != undefined && e.source != undefined && e.source.option != undefined) {\r\n\t\tswitch (e.source.option) {\r\n\t\t\tcase 1:\r\n\t\t\t\tvar path = 'http://www.pdf995.com/samples/pdf.pdf';\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 3:\r\n\t\t\t\tvar path = \"http://www.unm.edu/~unmvclib/powerpoint/pptexamples.ppt\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 4:\r\n\t\t\t\tvar path = \"https://upload.wikimedia.org/wikipedia/en/e/e5/ShereFASTticket-Example.png\";\r\n\t\t\t\tbreak;\r\n\t\t\tcase 5:\r\n\t\t\t\tvar path = \"https://calibre-ebook.com/downloads/demos/demo.docx\";\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t} else {\r\n\t\tvar path = \"http://opendatakit.org/wp-content/uploads/static/sample.xls\";\r\n\t}\r\n\r\n\tvar file_obj = {};\r\n\tvar url = path;\r\n\r\n\tvar splitFile = String(path);\r\n\tsplitFile = splitFile.split('/');\r\n\tsplitFile = splitFile[splitFile.length - 1];\r\n\tvar filename = \"New/\" + splitFile;\r\n\r\n\t//Replace Spaces with %20 so IOS will not crash\r\n\tif (url != null) {\r\n\t\turl = url.replace(/\\s/g, '%20');\r\n\t\tfile_obj = {\r\n\t\t\tfile: filename,\r\n\t\t\turl: url,\r\n\t\t\tpath: null\r\n\t\t};\r\n\r\n\t\tvar file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);\r\n\t\r\n\t\tif (file.exists()) {\r\n\t\t\tfile_obj.nativePath = file.nativePath;\r\n\t\t\tfile_obj.path = Ti.Filesystem.applicationDataDirectory;\r\n\t\t\tdoneWithFile(file_obj);\r\n\t\t} else {\r\n\t\t\tconsole.info('Ti.Network.online: ' + Ti.Network.online);\r\n\t\t\tif (Ti.Network.online) {\r\n\t\t\t\tvar c = Ti.Network.createHTTPClient({\r\n\t\t\t\t\ttimeout: 10000,\r\n\t\t\t\t\tonload: function() {\r\n\t\t\t\t\t\tfile_obj.status = this.status;\r\n\t\t\t\t\t\tif (this.status == 200) {\r\n\t\t\t\t\t\t\tvar f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, filename);\r\n\t\t\t\t\t\t\tfile_obj.path = Ti.Filesystem.applicationDataDirectory;\r\n\t\t\t\t\t\t\tf.write(this.responseData);\r\n\t\t\t\t\t\t\tfile_obj.nativePath = f.nativePath;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tfile_obj.error = 'File not found.'; // to set some errors codes\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t\t\t\tc = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tc.onerror = function(e) {\r\n\t\t\t\t\tfile_obj.status = e.code;\r\n\t\t\t\t\tfile_obj.error = e.error;\r\n\t\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t\t\tc = null;\r\n\t\t\t\t};\r\n\t\t\t\tc.open('GET', url);\r\n\t\t\t\tc.send();\r\n\t\t\t} else {\r\n\t\t\t\tfile_obj.error = 'No internet connection.';\r\n\t\t\t\tdoneWithFile(file_obj);\r\n\t\t\t}\r\n\t\t}\r\n\t} else {\r\n\t\tfile_obj.error = 'No URL';\r\n\t\tdoneWithFile(file_obj);\r\n\t}\r\n}\r\n{code}\r\nExpected behavior: All files should load in iOS < 11.2 and iOS >= 11.2.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-03-28T15:24:59.000+0000", "updated": "2018-04-02T19:48:21.000+0000" }, { "id": "436239", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "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.", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2018-04-03T16:44:34.000+0000", "updated": "2018-04-03T16:44:34.000+0000" }, { "id": "436554", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified changes are in SDK builds 7.1.1.v20180405080421 & 7.2.0.v20180404233630", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2018-04-05T20:36:04.000+0000", "updated": "2018-04-05T20:36:04.000+0000" } ], "maxResults": 10, "total": 10, "startAt": 0 } } }