Titanium JIRA Archive
Appcelerator Modules (MOD)

[MOD-2478] iOS: Cancel does not work on ti.barcode when scanning

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionCannot Reproduce
Resolution Date2020-04-03T14:58:23.000+0000
Affected Version/sn/a
Fix Version/sn/a
Componentsn/a
Labels2020-Q2, ios
Reporterandy@asamicros.com
AssigneeVikas Goyal
Created2018-04-04T09:02:07.000+0000
Updated2020-04-03T14:58:27.000+0000

Description

Previous issues like this have been reported, but closed when the problem could not be replicated. It appears that testing was done in the simulator, which produces a black image when calling to use the scanner. In this situation, cancel WILL work. However, in the real world, with a real iOS device, when the camera is capturing an image, cancel WILL NOT work immediately. The cancel event is registered, but only actioned when the camera image is made to go black. This is very easy to recreate using the example supplied with the module.

Attachments

FileDateSize
IMG_1073.TRIM.MOV2018-04-04T13:52:01.000+00001257201
qrcode_scan.mov2020-04-01T12:42:13.000+00003392164
VID_20180406_115332.mp42018-04-06T18:31:10.000+00003073645

Comments

  1. Rene Pot 2018-04-04

    [~andy@asamicros.com] attached is a video I just created using the sample provided. Cancel works immediately as you can see. This is on an iPhone 8 device, using TiSDK 7.1.0.GA and Alloy 1.11 and ti.barcode 1.10.1 Can you give me more info?
  2. andy@asamicros.com 2018-04-04

    iPhone 4S, ver 9.3.5 for my development unit. I used the app.js example, so alloy not relevant? I'm using ti SDK 7.1.0GA as previously mentioned. I did not see an alloy example to test.
  3. andy@asamicros.com 2018-04-04

    5C and 6C reporting same issue, although I don't know iOS version on these devices.
  4. Rene Pot 2018-04-05

    [~andy@asamicros.com] can you perhaps show a video of what exactly you see?
  5. andy@asamicros.com 2018-04-06

    OK. Working on it. Is there a file size limit?
  6. andy@asamicros.com 2018-04-06

    Attached a video. Yo can see that I have the modules cancel button, as well as the overlay button. Neither respond until the image is made to go black.
  7. Sharif AbuDarda 2018-05-20

    Hello [~andy@asamicros.com], Can you please provide a sample code/project for us to test the issue in our end? Thanks.
  8. andy@asamicros.com 2018-05-20

    Sharif, As I said in the description: 'This is very easy to recreate using the example supplied with the module.' ...Andy
  9. Rakhi Mitro 2018-08-09

    Hello, Are you experiencing the issue now? Please let us know if you need more help on this. Thanks
  10. andy@asamicros.com 2018-08-09

    I was not aware that there has been any changes done to this module, so I have not revisited this issue. I have been looking at alternative frameworks. Are you saying that this issue has been fixed and an update issued?
  11. Rakhi Mitro 2018-08-09

    [~andy@asamicros.com], Can you please test it using latest SDK and let us know how it goes. Thanks
  12. Sharif AbuDarda 2018-08-11

    Hello, Can you try with the latest module 2.0.1 version? There has a huge change in this. This was a iOS-only issue. Let us know. Thanks.
  13. Sharif AbuDarda 2018-08-13

    Hello [~andy@asamicros.com], Whats the status of your issue?
  14. andy@asamicros.com 2018-08-14

    Guys, Please clarify what I'm testing here. Am I testing the latest SDK as per Rakhi Mitro comment, or am I testing an updated ti.barcode module? What versions of SDK does the barcode module support? It will take a week or so to factor this into my current schedule. As you are pressing me, does this mean that you guts have tested on iPhone 4,5,6 devices and have determined that all is OK?
  15. Rene Pot 2018-08-14

    [~andy@asamicros.com] we're asking if you still have the same issue with the latest ti.barcode release. There has been a big refactor. Also we've never been able to reproduce the issue, therefore we're asking you to check it.
  16. andy@asamicros.com 2018-08-14

    Is this because you have not tested on a real iPhone 4, 5, 6 or that using the exact same software versions that I have indicated works for you on these devices? It would be helpful to know why you can't replicate the issue, indeed, it may be a pointer for moving forwards.
  17. Hans Knöchel 2018-08-14

    Quick interception here: We recently (last week) released a new version of Ti.Barcode that was rewritten from the scratch. Would you mind checking that version? You can download v2.0.1 [here](https://github.com/appcelerator-modules/ti.barcode/releases/tag/ios-2.0.1).
  18. Sharif AbuDarda 2018-09-08

    Hello [~andy@asamicros.com], What's the status of your issue? Did you try the above solutions?
  19. andy@asamicros.com 2018-09-09

    I will be testing this in the coming week.
  20. andy@asamicros.com 2018-09-10

    I can confirm that the module built with 7.3.1.GA has a working canvel button on the iOS device I am using (4S). We should be testing on a range of devices in a couple of weeks time.
  21. andy@asamicros.com 2018-09-11

    The use of the switch camera button in the suppled demo on iOS causes the image to freeze on my 4S, hence no longer works. Can still works though.
  22. andy@asamicros.com 2018-09-11

    On a Moto G running Android 7, the app freezes when a barcode is captured and keepOpen is false. If keepOpen is true, the capture is quite slow compared to iOS, but again freezes when the back button is pressed. If showCancel is true, no button is displayed. This test and the prevous comment on iOS are using the latest versions, as far as i know. Android 4.0.1, and iOS 2.0.2, with ti 7.3.1.GA.
  23. andy@asamicros.com 2018-09-11

    On my 4S, if the object passed to capture() has showRectangle : true, then the displayedMessage value is shown along with the rectangle, BUT the LED does not work - having set useLED : true. The LED flashes briefly. If showRectangle : false, then no rectangle, the LED works, no rectangle, BUT no displayedMessage. My previous comments on cancel are only valid for Barcode.cancel() calls. If showCancel is true, there is a problem. When capture is called and the device is in portrait orientation, the inbuilt cancel button does not respond UNTIL the device is rotated to landscape. If the device is rotated back to portrait, the button will respond. There is also a rendering issue is the device is in landscape when the barcode.capture call is made. It corrects on rotation. Hope this helps.
  24. andy@asamicros.com 2018-10-01

    Any news on the cancel bug I mentioned for 2.0.2 as it still exists in 2.0.3 i.e. My previous comments on cancel are only valid for Barcode.cancel() calls. If showCancel is true, there is a problem. When capture is called and the device is in portrait orientation, the inbuilt cancel button does not respond UNTIL the device is rotated to landscape. If the device is rotated back to portrait, the button will respond.
  25. Motiur Rahman 2018-12-04

    [~andy@asamicros.com] Can you check out this version v2.0.4. It has added functionality to prevent rotation of scanner - https://github.com/appcelerator-modules/ti.barcode/releases Thanks!
  26. andy@asamicros.com 2018-12-05

    Have you addressed any of the other issues I have mentioned?
  27. andy@asamicros.com 2018-12-08

    The cancel button behaviour is as before. Barcode.allowRotation = false appears not to do anything.
  28. andy@asamicros.com 2018-12-10

    Using the app.js shipped with the module. Setup as follows: Barcode.allowRotation = false; Barcode.displayedMessage = 'Barcode in the box'; Barcode.allowMenu = false; Barcode.allowInstructions = false; Barcode.useLED = true; Using: Barcode.capture({ animate: true, overlay: overlay, showCancel: true, showRectangle: true, keepOpen: false /*, acceptedFormats: [ Barcode.FORMAT_QR_CODE ]*/ }); Barcode is scanned irrespective of orientation. I have tried both orientations of iphone as well as orientation of the barcode. Also, change the orientation of the device, and the LED goes out. The cancel button controlled by: showCancel: true does not work. Previous versions worked after device was rotated, now it just does not work. This is iOS 12.1 (16B92)
  29. andy@asamicros.com 2018-12-10

    Where is the correct place to add an alert to the user after a scan? If you add an alert in the success callback, you get a black screen which hides the alert. My work around at the moment is the create a gotScan boolean value set to false before you call capture. Set gotScan = true in the success callback. Then check this gotScan value in the window focus event. This is based on the example code supplied with the module, and keepOpen set to false. Or is there a better place to do this?
  30. Vijay Singh 2019-01-10

    Add alert in success block after a time delay. See the following example. Especially line no 205 to 225 -
        var Barcode = require('ti.barcode');
         
        Barcode.allowRotation = true;
        Barcode.displayedMessage = 'Place barcode inside rectangle';
        Barcode.allowMenu = false;
        Barcode.allowInstructions = true;
        Barcode.useLED = true;
         
        var isiOS = Ti.Platform.osname === 'iphone' || Ti.Platform.osname === 'android';
        var isAndroid = Ti.Platform.osname === 'android';
         
        var window = Ti.UI.createWindow({
            backgroundColor: 'white'
        });
         
        var scrollView = Ti.UI.createScrollView({
            contentWidth: 'auto',
            contentHeight: 'auto',
            top: 0,
            showVerticalScrollIndicator: true,
            layout: 'vertical'
        });
         
        /**
         * Create a chrome for the barcode scanner.
         */
        var overlay = Ti.UI.createView({
            backgroundColor: 'transparent',
            top: 0,
            right: 0,
            bottom: 0,
            left: 0
        });
         
        var switchButton = Ti.UI.createButton({
            title: Barcode.useFrontCamera ? 'Back Camera' : 'Front Camera',
            textAlign: 'center',
            color: '#000',
            backgroundColor: '#fff',
            style: 0,
            font: {
                fontWeight: 'bold',
                fontSize: 16
            },
            borderColor: '#000',
            borderRadius: 10,
            borderWidth: 1,
            opacity: 0.5,
            width: 220,
            height: 30,
            bottom: 10
        });
         
        switchButton.addEventListener('click', function() {
            Barcode.useFrontCamera = !Barcode.useFrontCamera;
            switchButton.title = Barcode.useFrontCamera ? 'Back Camera' : 'Front Camera';
        });
         
        overlay.add(switchButton);
         
        var cancelButton = Ti.UI.createButton({
            title: 'Cancel',
            textAlign: 'center',
            color: '#000',
            backgroundColor: '#fff',
            style: 0,
            font: {
                fontWeight: 'bold',
                fontSize: 16
            },
            borderColor: '#000',
            borderRadius: 10,
            borderWidth: 1,
            opacity: 0.5,
            width: 220,
            height: 30,
            top: 20
        });
        cancelButton.addEventListener('click', function() {
            Barcode.cancel();
        });
        overlay.add(cancelButton);
         
        /**
         * Create a button that will trigger the barcode scanner.
         */
        var scanCode = Ti.UI.createButton({
            title: 'Scan the Code',
            width: 150,
            height: 60,
            top: 20
        });
         
        var cameraPermission = function(callback) {
            if (isAndroid) {
                if (Ti.Media.hasCameraPermissions()) {
                    if (callback) {
                        callback(true);
                    }
                } else {
                    Ti.Media.requestCameraPermissions(function(e) {
                        if (e.success) {
                            if (callback) {
                                callback(true);
                            }
                        } else {
                            if (callback) {
                                callback(false);
                            }
                            alert('No camera permission');
                        }
                    });
                }
            }
         
            if (isiOS) {
                if (callback) {
                    callback(true);
                }
            }
        };
         
        scanCode.addEventListener('click', function() {
            cameraPermission(function(re) {
                reset();
                // Note: while the simulator will NOT show a camera stream in the simulator, you may still call "Barcode.capture"
                // to test your barcode scanning overlay.
                Barcode.capture({
                    animate: true,
                    overlay: overlay,
                    showCancel: false,
                    showRectangle: false,
                    keepOpen: false
                    /*,
                            acceptedFormats: [
                                Barcode.FORMAT_QR_CODE
                            ]*/
                });
            });
        });
        scrollView.add(scanCode);
         
         
        /**
         * Create a button that will show the gallery picker.
         */
        var scanImage = Ti.UI.createButton({
            title: 'Scan Image from Gallery',
            width: 150,
            height: 60,
            top: 20
        });
         
        scanImage.addEventListener('click', function() {
            reset();
            Ti.Media.openPhotoGallery({
                success: function(evt) {
                    Barcode.parse({
                        image: evt.media
                        /*,
                                        acceptedFormats: [
                                            Barcode.FORMAT_QR_CODE
                                        ]*/
                    });
                }
            });
        });
         
        scrollView.add(scanImage);
         
        /**
         * Now listen for various events from the Barcode module. This is the module's way of communicating with us.
         */
         
        var scannedBarcodes = {},
            scannedBarcodesCount = 0;
         
        function reset() {
            scannedBarcodes = {};
            scannedBarcodesCount = 0;
            cancelButton.title = 'Cancel';
         
            scanResult.text = ' ';
            scanContentType.text = ' ';
            scanFormat.text = ' ';
            scanParsed.text = ' ';
        }
         
        Barcode.addEventListener('error', function(e) {
            scanContentType.text = ' ';
            scanFormat.text = ' ';
            scanParsed.text = ' ';
            scanResult.text = e.message;
            console.log('An Error occured: ' + e);
        });
         
        Barcode.addEventListener('cancel', function(e) {
            Ti.API.info('Cancel received');
        });
         
        var alert = Ti.UI.createAlertDialog();
        
        Barcode.addEventListener('success', function(e) {
            Ti.API.info('Success called with barcode: ' + e.result);
            if (!scannedBarcodes['' + e.result]) {
                scannedBarcodes[e.result] = true;
                scannedBarcodesCount += 1;
                cancelButton.title = 'Finished (' + scannedBarcodesCount + ' Scanned)';
         
                scanResult.text += e.result + ' ';
                scanContentType.text += parseContentType(e.contentType) + ' ';
                scanFormat.text += e.format + ' ';
                scanParsed.text += parseResult(e) + ' ';
            }
            // break it with an alert
            var message = 'Found barcode as ' + e.result;
            setTimeout(function(e){ 
                alert['title'] = message;
                alert.show();
            }, 1000);
        });
         
        /**
         * Finally, we'll add a couple labels to the window. When the user scans a barcode, we'll stick information about it in
         * to these labels.
         */
        scrollView.add(Ti.UI.createLabel({
            text: 'You may need to rotate the device',
            top: 10,
            height: Ti.UI.SIZE || 'auto',
            width: Ti.UI.SIZE || 'auto'
        }));
         
        scrollView.add(Ti.UI.createLabel({
            text: 'Result: ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        }));
         
        var scanResult = Ti.UI.createLabel({
            text: ' ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        });
         
        scrollView.add(scanResult);
         
        scrollView.add(Ti.UI.createLabel({
            text: 'Content Type: ',
            top: 10,
            left: 10,
            textAlign: 'left',
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        }));
         
        var scanContentType = Ti.UI.createLabel({
            text: ' ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        });
         
        scrollView.add(scanContentType);
         
        scrollView.add(Ti.UI.createLabel({
            text: 'Format: ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        }));
         
        var scanFormat = Ti.UI.createLabel({
            text: ' ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        });
         
        scrollView.add(scanFormat);
         
        scrollView.add(Ti.UI.createLabel({
            text: 'Parsed: ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        }));
         
        var scanParsed = Ti.UI.createLabel({
            text: ' ',
            textAlign: 'left',
            top: 10,
            left: 10,
            color: 'black',
            height: Ti.UI.SIZE || 'auto'
        });
         
        scrollView.add(scanParsed);
         
        function parseContentType(contentType) {
            switch (contentType) {
                case Barcode.URL:
                    return 'URL';
                case Barcode.SMS:
                    return 'SMS';
                case Barcode.TELEPHONE:
                    return 'TELEPHONE';
                case Barcode.TEXT:
                    return 'TEXT';
                case Barcode.CALENDAR:
                    return 'CALENDAR';
                case Barcode.GEOLOCATION:
                    return 'GEOLOCATION';
                case Barcode.EMAIL:
                    return 'EMAIL';
                case Barcode.CONTACT:
                    return 'CONTACT';
                case Barcode.BOOKMARK:
                    return 'BOOKMARK';
                case Barcode.WIFI:
                    return 'WIFI';
                default:
                    return 'UNKNOWN';
            }
        }
         
        function parseResult(event) {
            var msg = '';
            switch (event.contentType) {
                case Barcode.URL:
                    msg = 'URL = ' + event.result;
                    break;
                case Barcode.SMS:
                    msg = 'SMS = ' + JSON.stringify(event.data);
                    break;
                case Barcode.TELEPHONE:
                    msg = 'Telephone = ' + event.data.phonenumber;
                    break;
                case Barcode.TEXT:
                    msg = 'Text = ' + event.result;
                    break;
                case Barcode.CALENDAR:
                    msg = 'Calendar = ' + JSON.stringify(event.data);
                    break;
                case Barcode.GEOLOCATION:
                    msg = 'Geo = ' + JSON.stringify(event.data);
                    break;
                case Barcode.EMAIL:
                    msg = 'Email = ' + event.data.email + '\nSubject = ' + event.data.subject + '\nMessage = ' + event.data.message;
                    break;
                case Barcode.CONTACT:
                    msg = 'Contact = ' + JSON.stringify(event.data);
                    break;
                case Barcode.BOOKMARK:
                    msg = 'Bookmark = ' + JSON.stringify(event.data);
                    break;
                case Barcode.WIFI:
                    return 'WIFI = ' + JSON.stringify(event.data);
                default:
                    msg = 'unknown content type';
                    break;
            }
            return msg;
        }
        window.add(scrollView);
        window.open();
        
        
  31. Vikas Goyal 2020-04-01

  32. Samir Mohammed 2020-04-03

    Closing ticket, able to cancel scanning when running on Sim and device (note sometimes device scans quickly before user gets chance to cancel).

JSON Source