cordova-plugin-qrscanner icon indicating copy to clipboard operation
cordova-plugin-qrscanner copied to clipboard

iOS 15.4 camera preview not showed

Open fabioz23 opened this issue 2 years ago • 21 comments

Hi all,

i'm experiencing a problem, on iOS 15.4 the camera preview is not showing, black screen and green dot on status bar. So the camera is used and QR recognition works. The same code on iOS 15.3.1 work fine (and also on Android devices).

I've tried also @v1934 version: https://github.com/v1934/cordova-plugin-qrscanner-11 experiencing the same problem.

What are the changes on Safari Webkit that doesn't allow to make transparent the web content and show the live camera feed?

fabioz23 avatar Mar 22 '22 14:03 fabioz23

Weird, I have tested it on a device with iOS 15.4 and it works fine, also on 15.2. Are you using the wkwebview plugin? If yes then maybe that's the cause for different behaviour.

Try executing QRScanner.show() and QRscanner.hide() manually in safari debugging when camera is turned on. On Android 10+ these two methods were reversed because of some change in Android

v1934 avatar Mar 22 '22 15:03 v1934

Schermata 2022-03-22 alle 16 54 43

this is what i see on screen: Schermata 2022-03-22 alle 16 55 30

I've tried to downgrade from 15.4 to 15.3.1 and the same app (capacitor 2.5, ionic 5, angular 11) works as normal.

fabioz23 avatar Mar 22 '22 15:03 fabioz23

this is the func using the qrscanner-11 plugin:

qrCodeFromCamera() {
            this.platform.ready().then(() => {
                this.qrScanner.prepare()
                    .then((status: QRScannerStatus) => {
                        if (status.authorized) {
                            const ionApp = document.getElementsByTagName('ion-app')[0] as HTMLElement;
                            ionApp.style.display = 'none';

                            const scanSub = this.qrScanner.scan().subscribe(async (text: string) => {

                                ionApp.style.display = 'block';

                                scanSub.unsubscribe(); // stop scanning
                                await this.qrScanner.hide();
                                this.qrScanner.destroy().then();

                            });

                            this.qrScanner.resumePreview();

                            this.qrScanner.show()
                                .then(async (data: QRScannerStatus) => {}, 
			err => {
                                        console.log('err= ', err);
                                });

                        } else if (status.denied) {
                            console.log('denied = ', status.denied);
                            this.qrScanner.openSettings();
                        } else {
                                console.log('err = ', status);
                        }
                    })
                    .catch((e: any) => {
                            console.log('Error is', e);
                    }).finally(() => {
                        console.log('qrscanner onFinally');
                });
            });

    }

fabioz23 avatar Mar 22 '22 16:03 fabioz23

Did calling show() and hide() change anything or it was still black? On android 10+ hide() actually showed the camera. But iOS was not affected. What you could also try is to useFrontCamera() and see if it changes anything.

Are you sure that html and body elements have background-color: transparent? In my app i force the color to transparent when showing QRScanner, although I'm not using Ionic. It probably does it by default, but in my case without changing the color I'd also get only black/white screen.

Are you using the wkwebview plugin or anything like this? WKWebViewOnly flag or similar? There may be differences between webview implementations.

Update: I can see that WKWebView is now used by default in cordova-ios for some time already, so I guess that's not the problem

v1934 avatar Mar 23 '22 09:03 v1934

is not the same problem seen on android devices and 2.6.0 plugin version.

my problem is different, the code above works on android 8.x to 12 and from iOS 12 to 15.3.1.

The problem is isolated only on iOS 15.4. (both plugins, this repo and your @v1934 repo)

With 2.6.0 plugin version (this repo) i've also the Android 11-12 problem related to .hide() .show() inversion.

fabioz23 avatar Mar 23 '22 20:03 fabioz23

Did calling show() and hide() change anything or it was still black? On android 10+ hide() actually showed the camera. But iOS was not affected. What you could also try is to useFrontCamera() and see if it changes anything.

i'll try but i expect the same result.

Are you sure that html and body elements have background-color: transparent? In my app i force the color to transparent when showing QRScanner, although I'm not using Ionic. It probably does it by default, but in my case without changing the color I'd also get only black/white screen.

yes, the background is transparent.

Are you using the wkwebview plugin or anything like this? WKWebViewOnly flag or similar? There may be differences between webview implementations.

Update: I can see that WKWebView is now used by default in cordova-ios for some time already, so I guess that's not the problem

yep

fabioz23 avatar Mar 23 '22 20:03 fabioz23

We do have the same problem. Any news on how to fix this?

phausero avatar Mar 24 '22 08:03 phausero

We do have the same problem. Any news on how to fix this?

i'm investigating on it.

i ask also support from plugin maintaners @majochoc , @matiu and @v1934 as they know this plugin better than me

fabioz23 avatar Mar 24 '22 09:03 fabioz23

Well, I'm actually just an user of this plugin just like you, I just fixed the previous android bug because it was affecting my app. I'd like to test it too but somehow on my physical 15.4 device I don't reproduce this problem, and I somehow don't have any 15.4 simulator available to download (only 15.2). My app is not based on Ionic though, maybe here lies the problem?

v1934 avatar Mar 24 '22 09:03 v1934

I think i found a solution. You have to also set the background of the webviews scrollview to transparent too now. Will create a PR.

phausero avatar Mar 24 '22 09:03 phausero

I think i found a solution. You have to also set the background of the webviews scrollview to transparent too now. Will create a PR.

can you give more details on your solution?

i've already tried to make transparent and/or not display some elements in the dom stack with no success.

                        const body = document.getElementsByTagName('body')[0] as HTMLElement;
                        body.style.background = 'transparent';
                        body.style.display = 'none';

                        const appRoot = document.getElementsByTagName('app-root')[0] as HTMLElement;
                        appRoot.style.background = 'transparent';
                        appRoot.style.display = 'none';

                        const ionApp = document.getElementsByTagName('ion-app')[0] as HTMLElement;
                        ionApp.style.background = 'transparent';
                        ionApp.style.display = 'none';

                        const ionContent = document.getElementsByTagName('ion-content')[0] as HTMLElement;
                        ionContent.style.background = 'transparent';
                        ionContent.style.display = 'none';

fabioz23 avatar Mar 24 '22 09:03 fabioz23

@fabioz23 I guess @phausero referes to the UIScrollView element that is a child of WKWebView, therefore it cannot be fixed from HTML. Does the same error happen if your HTML content/body is not scrollable? This repo is abandoned for years already, so if @phausero submits a PR I'll also move the changes to my fork with android fix

v1934 avatar Mar 24 '22 10:03 v1934

ok found and fixed.

@v1934 i've done a PR to your repo for this fix

fabioz23 avatar Mar 24 '22 11:03 fabioz23

@phausero if you agree and test goes fine we can mark as solved this issue.

fabioz23 avatar Mar 24 '22 11:03 fabioz23

I have accepted the PR and pushed an update, you can check it out by adding [email protected] to your cordova plugins. I have so far tested it on physical Android 10, iOS 15.2 and 15.4 devices, all working fine. Let me know if the issue is resolved for you as well.

v1934 avatar Mar 24 '22 13:03 v1934

@v1934 - the latest fork you have for qrscanner-11 (3.0.4) is breaking in Cordova 11 (cordova-android 11). Failing to compile the dependency:

1: Task failed with an exception.

  • Where: Script 'C:\Users\rolin\dev\MyApp\platforms\android\cordova-plugin-qrscanner-11\myApp-qrscanner.gradle' line: 6

  • What went wrong: A problem occurred evaluating script.

Could not find method compile() for arguments [com.journeyapps:zxing-android-embedded:3.3.0] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

I also checked out the zxing-android-embedded scanner toolset, its now up to 4.3.0 - not certain if that helps anything here though.

rolinger avatar Feb 25 '23 14:02 rolinger

@v1934 - any chance you are making a whole new plugin since the orig authors are no longer maintaining this one. I know @jacobg has been maintaining a bunch of fixes in his too; maybe merge the efforts together.

rolinger avatar Feb 25 '23 14:02 rolinger

@v1934 - the latest fork you have for qrscanner-11 (3.0.4) is breaking in Cordova 11 (cordova-android 11). Failing to compile the dependency:

1: Task failed with an exception.

  • Where: Script 'C:\Users\rolin\dev\MyApp\platforms\android\cordova-plugin-qrscanner-11\myApp-qrscanner.gradle' line: 6
  • What went wrong: A problem occurred evaluating script.

Could not find method compile() for arguments [com.journeyapps:zxing-android-embedded:3.3.0] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

I also checked out the zxing-android-embedded scanner toolset, its now up to 4.3.0 - not certain if that helps anything here though.

I got this resolved fixing the gradle script. In gradle 7.0 and higher certain methods have been replaced. Note that the compile, runtime, testCompile, and testRuntime configurations introduced by the Java plugin have been deprecated since Gradle 4.10 (Aug 27, 2018), and were finally removed in Gradle 7.0 (Apr 9, 2021).

The aforementioned configurations should be replaced by implementation, runtimeOnly, testImplementation, and testRuntimeOnly, respectively.

Thus changing the plugin src/android/qrscanner.gradle file fixed the install for me. So far, the plugin has loaded and seems to work fine now on Cordova11 (cordova-android11). Haven't tested iOS yet. Thats next after I rebuild my project for Cordova 11 on the Mac.

dependencies {
    compile 'com.journeyapps:zxing-android-embedded:3.3.0'
    compile 'com.android.support:appcompat-v7:23.1.0'
    //compile 'com.journeyapps:zxing-android-embedded:3.3.0'
    //compile 'com.android.support:appcompat-v7:23.1.0'
    implementation 'com.journeyapps:zxing-android-embedded:3.3.0'
    implementation 'com.android.support:appcompat-v7:23.1.0'
}

rolinger avatar Feb 25 '23 15:02 rolinger

Please try using the new version of my fork: [email protected]

v1934 avatar Feb 28 '23 13:02 v1934

@fabioz23 @phausero - I have noticed that on different phones hiding the app layer to reveal the live camera screen beneath the app is not consistent. I have watched users on the same version of my app click the scan now button and the camera is revealed showing an overlay transparent png with red target brackets (IE: [ - ] ) and sometimes its not, its a white screen showing the red brackets - but the camera is on and working and will scan a qr code in front of it. The red target brackets are visual only, giving the user something to aim/focus/center the image with while the scanner does its work in the background.

IE: ionApp.style.display = 'none'

This is telling me that some phones or some versions of iOS need another layer removed to reveal the live camera screen beneath it. However, when it has happened, I have not been able to successful capture what the device is or what additional layer needs to be hidden. I suspect the same is happening to you on certain devices.

I do recall getting it all to work. Then on another test device saw this issue happening and had to hide a different layer...not just another layer, but a different layer altogether. My next version I plan on tracking it down and will try to determine if there any conditions I can add that will always hide the correct layer(s).

rolinger avatar Feb 28 '23 13:02 rolinger

Can anyone advise how I use [email protected] in a capacitor 4 project to replace @ionic-native/qr-scanner/ngx which is https://github.com/bitpay/cordova-plugin-qrscanner but wrapped in an @ionic-native npm package?

Tried adding it as an import to replace

import { QRScanner, QRScannerStatus } from "@ionic-native/qr-scanner/ngx";

with

import { QRScanner, QRScannerStatus } from "cordova-plugin-qrscanner-11";

but this just fails as

Could not find a declaration file for module 'cordova-plugin-qrscanner-11'. '/Users/admin/Documents/Task-6181-Upgrade-Capacitor/node_modules/cordova-plugin-qrscanner-11/dist/cordova-plugin-qrscanner-lib.min.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/cordova-plugin-qrscanner-11` if it exists or add a new declaration (.d.ts) file containing `declare module 'cordova-plugin-qrscanner-11';`ts(7016)

lankymart avatar Apr 27 '23 11:04 lankymart