{ "id": "175684", "key": "TIMOB-28267", "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": "21177", "name": "Release 9.3.1", "archived": false, "released": true, "releaseDate": "2021-01-26" } ], "resolution": null, "resolutiondate": null, "created": "2020-10-30T11:35:26.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "eventlistener" ], "versions": [], "issuelinks": [], "assignee": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2021-01-26T15:15:41.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": "When using ti.barcode module with SDK 9.0.3.GA and 9.2.2.GA on iOS 13 it sometimes happens that the registered event handlers stop working. This often happens if you remove a event listener that does not exist and try adding it again.\r\n\r\nBecause we want to ensure we don't register a event listener twice we often call `Barcode.removeEventListener(...);` before adding any listeners. This used to work on older iOS/titanium/ti.barcode versions.\r\n\r\nWe've tested with ti.barcode version 2.0.4 and 6.0.0\r\n\r\nWith the following example app the issue can be reproduced by tapping the buttons in the following order;\r\n\r\n> Add Event Listeners\r\n> resetCapture\r\n> remove event listeners\r\n> resetCapture\r\n\r\nThe barcodeSuccess callback is not called anymore although that is expected.\r\nIf we try to tap `resetCapture` multiple times in a clean run the event handers will always be properly removed, added and called.\r\n\r\nindex.js\r\n{code}\r\nconst Barcode = require('ti.barcode');\r\nconst overlay = Ti.UI.createView({\r\n\tbackgroundColor: 'transparent',\r\n\ttop: 0,\r\n\tright: 0,\r\n\tbottom: 0,\r\n\tleft: 0\r\n});\r\n\r\nvar switchButton = Ti.UI.createButton({\r\n\ttitle: Barcode.useFrontCamera ? 'Back Camera' : 'Front Camera',\r\n\ttextAlign: 'center',\r\n\tcolor: '#000',\r\n\tbackgroundColor: '#fff',\r\n\tstyle: 0,\r\n\tfont: {\r\n\t\tfontWeight: 'bold',\r\n\t\tfontSize: 16\r\n\t},\r\n\tborderColor: '#000',\r\n\tborderRadius: 10,\r\n\tborderWidth: 1,\r\n\topacity: 0.5,\r\n\twidth: 220,\r\n\theight: 30,\r\n\tbottom: 10\r\n});\r\n\r\nswitchButton.addEventListener('click', function () {\r\n\tBarcode.useFrontCamera = !Barcode.useFrontCamera;\r\n\tswitchButton.title = Barcode.useFrontCamera ? 'Back Camera' : 'Front Camera';\r\n});\r\n\r\noverlay.add(switchButton);\r\n\r\nvar cancelButton = Ti.UI.createButton({\r\n\ttitle: 'Cancel',\r\n\ttextAlign: 'center',\r\n\tcolor: '#000',\r\n\tbackgroundColor: '#fff',\r\n\tstyle: 0,\r\n\tfont: {\r\n\t\tfontWeight: 'bold',\r\n\t\tfontSize: 16\r\n\t},\r\n\tborderColor: '#000',\r\n\tborderRadius: 10,\r\n\tborderWidth: 1,\r\n\topacity: 0.5,\r\n\twidth: 220,\r\n\theight: 30,\r\n\ttop: 20\r\n});\r\ncancelButton.addEventListener('click', function () {\r\n\tBarcode.cancel();\r\n});\r\noverlay.add(cancelButton);\r\n\r\n\r\nfunction barcodeAddEventListeners() {\r\n console.log('barcodeAddEventListeners');\r\n Barcode.addEventListener('success', barcodeSuccess);\r\n Barcode.addEventListener('cancelled', barcodeCancelled);\r\n Barcode.addEventListener('error', barcodeError);\r\n}\r\n\r\nfunction barcodeRemoveEventListeners() {\r\n console.log('barcodeRemoveEventListeners');\r\n Barcode.removeEventListener('success', barcodeSuccess);\r\n Barcode.removeEventListener('cancelled', barcodeCancelled);\r\n Barcode.removeEventListener('error', barcodeError);\r\n}\r\n\r\nfunction resetCapture() {\r\n barcodeRemoveEventListeners();\r\n barcodeAddEventListeners();\r\n barcodeCapture();\r\n}\r\n\r\nfunction barcodeSuccess() {\r\n console.log('barcodeSuccess');\r\n}\r\n\r\nfunction barcodeCancelled() {\r\n console.log('barcodeCancelled');\r\n}\r\n\r\nfunction barcodeError() {\r\n console.log('barcodeError');\r\n}\r\n\r\n\r\nvar cameraPermission = (callback) => {\r\n\tif (OS_ANDROID) {\r\n\t\tif (Ti.Media.hasCameraPermissions()) {\r\n\t\t\tif (callback) {\r\n\t\t\t\tcallback(true);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tTi.Media.requestCameraPermissions(function (e) {\r\n\t\t\t\tif (e.success) {\r\n\t\t\t\t\tif (callback) {\r\n\t\t\t\t\t\tcallback(true);\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (callback) {\r\n\t\t\t\t\t\tcallback(false);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconsole.log('No camera permission'); // eslint-disable-line no-alert\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tif (OS_IOS) {\r\n\t\tif (callback) {\r\n\t\t\tcallback(true);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nfunction barcodeCapture() {\r\n cameraPermission(success => {\r\n console.log('gotPermission', {success: success});\r\n if(success) {\r\n Barcode.capture({\r\n animate: true,\r\n showCancel: false,\r\n showRectangle: false,\r\n keepOpen: false,\r\n allowInstructions: false,\r\n allowMenu: true,\r\n overlay: overlay,\r\n acceptedFormats: [\r\n Barcode.FORMAT_QR_CODE\r\n ]\r\n });\r\n }\r\n })\r\n \r\n}\r\n\r\n\r\n$.index.open();\r\n{code}\r\n\r\nindex.xml\r\n{code}\r\n\r\n\t\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n", "attachment": [], "flagged": false, "summary": "Ti.Barcode event handlers not working properly on iOS", "creator": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "Appcelerator Command-Line Interface, version 8.1.1\r\nCopyright (c) 2014-2020, Appcelerator, Inc. All Rights Reserved.\r\n\r\n10/30/2020, 12:27:20 PM\r\n\r\nOperating System\r\n Name = Mac OS X\r\n Version = 10.15.6\r\n Architecture = 64bit\r\n # CPUs = 8\r\n Memory = 17179869184\r\n\r\nNode.js\r\n Node.js Version = 12.9.0\r\n npm Version = 6.14.8\r\n\r\nTitanium CLI\r\n CLI Version = 5.2.5\r\n\r\nTitanium SDK\r\n SDK Version = 9.2.2.GA\r\n SDK Path = /Users/vdlp/Library/Application Support/Titanium/mobilesdk/osx/9.2.2.GA\r\n Target Platform = iphone\r\n\r\nCommand\r\n /Users/vdlp/.nvm/versions/node/v12.9.0/bin/node /Users/vdlp/.appcelerator/install/8.1.1/package/node_modules/titanium/lib/titanium.js build --project-dir /Users/vdlp/Mobile/demos/tabgrouptest --log-level info --platform ios --color --no-prompt --liveview --target device --sdk 9.2.2.GA --device-id 5932a44fa3205c2ec324bdb715484f317b765904 --developer-name Apple Development: Lars de Ruijter (7G83ZQN6RU) --pp-uuid 290b70e4-fe77-4f8b-a625-a483ee47e0ea --config-file /var/folders/hy/91fthb9n5rb58slwgwj4l__c0000gn/T/build-1604057231729.json --no-banner --project-dir /Users/vdlp/Mobile/demos/tabgrouptest\r\n\r\n[INFO] Found Titanium module id=ti.cloud version=3.2.11 platform=commonjs deploy-type=test path=/Users/vdlp/Library/Application Support/Titanium/modules/commonjs/ti.cloud/3.2.11\r\n[INFO] Found Titanium module id=ti.map version=3.4.0 platform=ios deploy-type=test path=/Users/vdlp/Mobile/demos/tabgrouptest/modules/iphone/ti.map/3.4.0\r\n[INFO] Found Titanium module id=ti.barcode version=6.0.0 platform=ios deploy-type=test path=/Users/vdlp/Mobile/demos/tabgrouptest/modules/iphone/ti.barcode/6.0.0\r\n[INFO] Found Titanium plugin id=ti.alloy version=1.0 ", "closedSprints": [ { "id": 1212, "state": "closed", "name": "2020 Sprint 25", "startDate": "2020-12-07T22:11:00.000Z", "endDate": "2020-12-18T22:11:00.000Z", "completeDate": "2020-12-18T16:35:34.544Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "457410", "author": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "body": "Is this happening on iOS 14 too? Or just iOS 13?", "updateAuthor": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "created": "2020-11-02T15:25:16.000+0000", "updated": "2020-11-02T15:25:16.000+0000" }, { "id": "457437", "author": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Only had a chance to test it on iOS 13", "updateAuthor": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-11-04T09:44:37.000+0000", "updated": "2020-11-04T09:44:37.000+0000" }, { "id": "457710", "author": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Could not reproduce it on the simulator. Could not test on the device as the test app crashes on click of resetCapture button on both iOS 13 and 14 devices.", "updateAuthor": { "name": "spulipakkam", "key": "spulipakkam", "displayName": "Srinivasan Pulipakkam", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-11-24T20:10:22.000+0000", "updated": "2020-11-30T16:59:23.000+0000" }, { "id": "457740", "author": { "name": "spulipakkam", "key": "spulipakkam", "displayName": "Srinivasan Pulipakkam", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~menzo] Can you please check the response ^^ and see if there is any issue in the test app.. ", "updateAuthor": { "name": "spulipakkam", "key": "spulipakkam", "displayName": "Srinivasan Pulipakkam", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-11-30T17:00:06.000+0000", "updated": "2020-11-30T17:00:06.000+0000" }, { "id": "457757", "author": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Well it's not gonna work on a simulator because the test requires using the camera which is not available on simulator. And for me the app works on device when built with the mentioned SDK / plugin versions. Maybe Satyam can provide crash log?", "updateAuthor": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-02T09:37:09.000+0000", "updated": "2020-12-02T09:37:09.000+0000" }, { "id": "457774", "author": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "body": "The app crash was a permission issue at my end. Could run the app now and noticed that following the steps in sequence as mentioned below the barcodeSuccess callback is successfully called in step 2 but not in step 4.\r\nStep 1: After the app open click on Add Event Listeners\r\nStep 2: click resetCapture\r\nStep 3: click remove event listeners\r\nStep 4: click resetCapture", "updateAuthor": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-03T17:37:55.000+0000", "updated": "2020-12-03T17:37:55.000+0000" }, { "id": "457796", "author": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "body": "So just to be clear, that confirms that you were able to reproduce the issue?", "updateAuthor": { "name": "menzo", "key": "menzo", "displayName": "VDLP", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-04T11:12:03.000+0000", "updated": "2020-12-04T11:12:03.000+0000" }, { "id": "457840", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~menzo] Yes. We are able to reproduce it. I have started working on this. I'll update here with progress.", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-09T00:28:59.000+0000", "updated": "2020-12-09T00:28:59.000+0000" }, { "id": "457883", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This is bug in SDK not in Barcode module.\r\n\r\nPR - https://github.com/appcelerator/titanium_mobile/pull/12339\r\n\r\nTest Case 1 - \r\n\r\n{code:java}\r\nvar win = Ti.UI.createWindow({\r\n\tbackgroundColor: '#fff',\r\n\tlayout: 'vertical'\r\n});\r\n\r\nvar btn1 = Ti.UI.createButton({\r\n\ttitle: 'Add Event Listeners to button 3',\r\n\ttop: 120\r\n});\r\nbtn1.addEventListener('click', () => {\r\n\tbtn3.addEventListener('click', logEvent);\r\n});\r\nwin.add(btn1);\r\n\r\nvar btn2 = Ti.UI.createButton({\r\n\ttitle: 'Remove Event Listeners to button 3',\r\n\ttop: 40\r\n});\r\nbtn2.addEventListener('click', () => {\r\n\tbtn3.removeEventListener('click', logEvent);\r\n});\r\nwin.add(btn2);\r\n\r\nvar btn3 = Ti.UI.createButton({\r\n\ttop: 40,\r\n\ttitle: 'Click on Button3'\r\n});\r\nwin.add(btn3);\r\n\r\nwin.open();\r\n \r\nfunction logEvent() {\r\n console.log('Event logged');\r\n}\r\n\r\nwin.addEventListener('focus', focusEvent);\r\n\r\nwin.removeEventListener('focus', focusEvent);\r\nwin.removeEventListener('focus', focusEvent);\r\nwin.removeEventListener('focus', focusEvent);\r\n\r\nwin.addEventListener('focus', focusEvent);\r\n\r\nfunction focusEvent() {\r\n console.log('Focus Event logged');\r\n}\r\n{code}\r\n\r\nNote - \r\n1. On app run it should log 'Focus Event logged'.\r\n2. Add event listener on button 3 once the remove event listener > 3 times and then add event listener again by clicking respective buttons. Now click button 3. It should log 'Event Log' .\r\n\r\n\r\n", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-11T21:12:52.000+0000", "updated": "2020-12-11T21:12:52.000+0000" }, { "id": "457906", "author": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed.\r\nWaiting for Jenkins build.", "updateAuthor": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-12-15T23:36:45.000+0000", "updated": "2020-12-15T23:36:45.000+0000" }, { "id": "457916", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "merged to master, cherry-picked to 9_3_X for 9.3.1 target", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2020-12-16T17:47:37.000+0000", "updated": "2020-12-16T17:47:37.000+0000" }, { "id": "458081", "author": { "name": "mj", "key": "mj", "displayName": "martin", "active": true, "timeZone": "Europe/Berlin" }, "updateAuthor": { "name": "mj", "key": "mj", "displayName": "martin", "active": true, "timeZone": "Europe/Berlin" }, "created": "2021-01-26T15:15:41.000+0000", "updated": "2021-01-26T15:15:41.000+0000" } ], "maxResults": 14, "total": 14, "startAt": 0 } } }