Essentials icon indicating copy to clipboard operation
Essentials copied to clipboard

[Bug] On IOS, Photo returned by MediaPicker.CapturePhotoASync() is not found

Open euquiq opened this issue 4 years ago • 6 comments

Description

On Android this works as expected.

On IOS, when I try to get the photo taken by MediaPicker as a file, for i.e. get it's size, I get:

Length	System.IO.FileNotFoundException: Could not find file '/private/var/containers/Bundle/Application/BCB43D5F-508C-4882-BFB5-70C6953F6855/Myapp.iOS.app/fa637fb7-0b37-4896-bc33-cd3b5738f548.png'.	

There is a PR that apparently fixes this: https://github.com/xamarin/Essentials/pull/1639

Steps to Reproduce

  1. var photo = await MediaPicker.CapturePhotoAsync();
  2. var file = new FileInfo(photo.FullPath);
  3. file.Length throws the "FileNotFoundException".

Expected Behavior

Be able to access the file.

Actual Behavior

File not found.

Basic Information

Seems the same bug as depicted in: https://github.com/xamarin/Essentials/issues/1620

  • Version with issue: 1.7.0
  • Last known good version: Not known.
  • IDE: MAC OS VISUAL STUDIO 2019
  • Platform Target Frameworks:
    • iOS: Latest on iPhone SE (new one)

euquiq avatar Jul 30 '21 21:07 euquiq

@euquiq - Try this code:

var stream = await imagePicker.OpenReadAsync(); byte[] dataBytes = new byte[stream.Length]; var streamData = await stream.ReadAsync(dataBytes, 0, dataBytes.Length);

var cacheFile = System.IO.Path.Combine(Xamarin.Essentials.FileSystem.CacheDirectory, "filename.png"); using (var cache = new FileStream(cacheFile, FileMode.Create, FileAccess.Write)) { cache.Write(dataBytes, 0, dataBytes.Length); await cache.FlushAsync(); }

Replace "filename.png" with the filename. The code must be placed in the iOS implementation and can be passed back with the correct path to the image.

sshere avatar Apr 13 '22 03:04 sshere

@sshere Thx, You saved my day!!!

The FullPath of the file just seems wrong at first. So resaved it, in Cache directory made it work for me.

var file = await MediaPicker.CapturePhotoAsync();
var cachePath = Path.Combine(FileSystem.CacheDirectory, file.FileName);
using (var stream = await file.OpenReadAsync())
using (var cache = new FileStream(cachePath, FileMode.Create, FileAccess.Write))
        await stream.CopyToAsync(cache);

Phenek avatar Jul 06 '22 16:07 Phenek

Bug still not fixed (Essentials v 1.7.3)

yevgeny-sotnikov avatar Sep 28 '22 10:09 yevgeny-sotnikov

Bug still not fixed (Essentials v 1.7.3) Hi @yevgeny-sotnikov !) For me not fixed as well

IrynaDoroshenkoDev avatar Apr 26 '23 16:04 IrynaDoroshenkoDev

Same here... still not working on Xamarin.Essentials v1.7.7. The Android implementation works fine, and returns a FileResult with the FileName and FullPath set properly. Meaning... The fullpath includes the complete path to the folder... and the filename.

But, the iOS implementation returns the same string value for both properties. And, trusting the "FullPath" property to be what it says, results in an exception.

Is there a fix for this?

LeeWhite187 avatar Jul 11 '23 17:07 LeeWhite187

Since the iOS implementation doesn't give a correct FullPath to the taken photo, how should I delete the orphaned file in iOS if I'm consuming the stream, instead?

LeeWhite187 avatar Jul 11 '23 17:07 LeeWhite187