ionic-team / capacitor-plugins

Official plugins for Capacitor ⚡️
508 stars 577 forks source link

Camera pickImages() doesn't work first time on safari #1314

Closed Danchat5 closed 8 months ago

Danchat5 commented 1 year ago

Bug Report

Plugin(s)

"@capacitor/camera": "^4.1.1"

Capacitor Version

4.0.1

Platform(s)

web

Current Behavior

When the pickImages() function runs, the option menu on iOS (that gives the options Gallery, Take Picture, or Files) does not appear the first time. Every consecutive time the function is called, it works as intended.

  async pickImage () {
    const newPhotos = await Camera.pickImages({
      quality: 100,
      limit: 1,
      correctOrientation: true
    })
}

Code Reproduction

You can view a test app here where I try out both pickImages() and getPhoto() functions.

Additional Context

This appears to be a near duplicate of this issue, except for the fact that Android was the offending platform. I ensured that the plugin that caused the issue on that problem was not installed in my application.

I will list the plugins I am using below:

"@angular/animations": "^14.2.2",
    "@angular/common": "^14.2.2",
    "@angular/compiler": "^14.2.2",
    "@angular/compiler-cli": "^14.2.2",
    "@angular/core": "^14.2.2",
    "@angular/forms": "^14.2.2",
    "@angular/platform-browser": "^14.2.2",
    "@angular/platform-browser-dynamic": "^14.2.2",
    "@angular/router": "^14.2.2",
    "@angular/service-worker": "^14.2.2",
    "@awesome-cordova-plugins/email-composer": "^5.45.0",
    "@awesome-cordova-plugins/globalization": "^5.45.0",
    "@capacitor/android": "^4.2.0",
    "@capacitor/app": "^4.0.1",
    "@capacitor/browser": "^4.0.1",
    "@capacitor/camera": "^4.1.1",
    "@capacitor/core": "^4.2.0",
    "@capacitor/dialog": "^4.0.1",
    "@capacitor/filesystem": "^4.1.1",
    "@capacitor/haptics": "^4.0.1",
    "@capacitor/ios": "^4.2.0",
    "@capacitor/keyboard": "^4.0.1",
    "@capacitor/preferences": "^4.0.1",
    "@capacitor/push-notifications": "^4.1.0",
    "@capacitor/splash-screen": "^4.0.1",
    "@capacitor/status-bar": "^4.0.1",
    "@fortawesome/angular-fontawesome": "^0.11.1",
    "@fortawesome/fontawesome-pro": "~6.2.0",
    "@fortawesome/free-brands-svg-icons": "~6.2.0",
    "@fortawesome/pro-regular-svg-icons": "~6.2.0",
    "@fortawesome/pro-solid-svg-icons": "~6.2.0",
    "@ionic-native/qr-scanner": "^5.36.0",
    "@ionic/angular": "^6.2.7",
    "@ionic/pwa-elements": "^3.1.1",
    "@mineminemine/fcm": "^4.0.3",
    "@ngx-translate/core": "^14.0.0",
    "@ngx-translate/http-loader": "^7.0.0",
    "@transistorsoft/capacitor-background-fetch": "^1.0.0",
    "angular-gauge": "^4.0.0",
    "arraybuffer-to-string": "^1.0.2",
    "base64-arraybuffer": "^1.0.2",
    "base64-js": "^1.5.1",
    "cordova-plugin-email-composer": "^0.10.1",
    "cordova-plugin-globalization": "^1.11.0",
    "date-fns-tz": "^1.3.7",
    "hammerjs": "^2.0.8",
    "idb": "^7.0.2",
    "lock": "^1.1.0",
    "lodash-es": "^4.17.21",
    "ngx-ui-scroll": "^3.0.1",
    "p-queue": "^7.3.0",
    "p-timeout": "^6.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.5.6",
    "scope-css": "^1.2.1",
    "shell-escape": "^0.2.0",
    "swiper": "^8.4.2",
    "tslib": "^2.4.0",
    "zone.js": "^0.11.8"
Ionitron commented 1 year ago

This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.

Please see the Contributing Guide for how to create a Code Reproduction.

Thanks! Ionitron 💙

Danchat5 commented 1 year ago

I also attempted getPhoto() instead of pickImages(), and I encountered the same error (does not work the first time, works every consecutive attempt). Seems to be the same issue as this one.

Ionitron commented 1 year ago

This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.

Please see the Contributing Guide for how to create a Code Reproduction.

Thanks! Ionitron 💙

Danchat5 commented 1 year ago

I have been able to replicate the error in a standalone app. You can view it here, where both getPhoto() and pickImages() do nothing the first time they are clicked on an iOS device. Any other time they are clicked, the menu will pop up as expected. This was tested on both an iPhone and an iPad.

jcesarmobile commented 1 year ago

Please, can you provide the source code? The url is not enough, we need to be able to run it and make changes to verify we have fixed the issue.

Danchat5 commented 1 year ago

Alright, here you go:

homeComponent.ts

import { Component } from '@angular/core';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera'
import { HttpClient } from '@angular/common/http'
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  constructor(public http: HttpClient, private readonly domSanitizer: DomSanitizer) { }

  img: any

  async pickImage() {
    const newPhotos = await Camera.pickImages({
      quality: 100,
      limit: 1,
      correctOrientation: true
    })

    if (newPhotos.photos.length > 0) {
      try {
        let p = newPhotos.photos.pop()

        //format of p: blob http://hash
        console.log(p?.webPath)
        if (p?.webPath) {
          this.img = this.domSanitizer.bypassSecurityTrustUrl(p?.webPath)
        }
      } catch (e) {
        console.error(e)
      }
    }
  }

  async getPhoto() {
    const photo = await Camera.getPhoto({
      resultType: CameraResultType.Uri,
      quality: 100,
      correctOrientation: true,
      source: CameraSource.Photos
    })
    if(photo?.webPath) {
      this.img = this.domSanitizer.bypassSecurityTrustUrl(photo.webPath)
    }

  }

}

homeComponent.html

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Camera Test
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">

  <ion-fab horizontal="center" slot="fixed">
    <button (click)="pickImage()">
      pickImages()
    </button>
  </ion-fab>
  <ion-fab >
    <button horizontal="center" (click)="getPhoto()">
      getPhoto()
    </button>
  </ion-fab>
  <img [src]="img">
</ion-content>

The plugins that are installed are above in my original post. I can post the whole project in a zip file later if need be.

jcesarmobile commented 1 year ago

That's still not enough, we need a .zip or a public github repository that we can download

Danchat5 commented 1 year ago

Here's the project in a zip file: SelectImageDemo.zip

jcesarmobile commented 1 year ago

Thanks for the sample app, I've been able to reproduce. This is not an iOS bug but a Safari bug, and only affects web platform on Safari browser (both desktop and mobile). Native iOS works fine.

Danchat5 commented 1 year ago

I just tested on Google Chrome and Firefox on my iPhone and I'm getting the same issue.

How do you test it natively on iOS?

jcesarmobile commented 1 year ago

On iOS/iPadOS all browsers use "Safari" (WebKit) under the hood.

For testing natively you can follow this https://capacitorjs.com/docs/ios

Danchat5 commented 1 year ago

Where do you recommend I bring up this issue? I haven't dealt with Safari bugs before.

jcesarmobile commented 1 year ago

It’s a bug in camera plugin that only affects safari, so we will look into it and try to fix it.

Danchat5 commented 1 year ago

@jcesarmobile Any updates on this bug?

PimBreugem commented 9 months ago

We are experiencing the same issue, on safari the user is required to click twice before being able to select an image. Any update on this bug? Or, is there a workaround available?

ionitron-bot[bot] commented 7 months ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of the plugin, please create a new issue and ensure the template is fully filled out.