Rendering an image from local dataDirectory on iOS

I’m sure I must be doing something simple wrong here. All I want to do is load images when the app loads, store them, then render them.

The download and storage is going fine, but I cannot get anything to work in terms of rendering the image in an image tag. I’m saving the return from the file.toURL() method (have also tried .toNativeURL())

I have tried both file:// and cdvfile:// by using the methods on the native file object, but neither work. The CDV file produces the error “WARNING: unsafe url sanitzed” on iOS.

I’ve tried using the bypassSecurityTrustStyle function of the DOMsanitizer to no effect, and as thats from the browser platform library, is it even available when it runs on iOS?

Any help would be appreciated, surely this must be simple. I’m sure I’l missing something obvious.

2 Likes

This response probably contains too much info for your need, as it describes an entire process of taking a picture, creating file, etc, but the normalizeUrl part might be of use to you. I’d have trimmed it down but it’s just a copy of a previous post i put up.

I’m using nativeUrl, FYI

In my html. A quick example

<ion-item>
  <img [src]="normalizedUrl"  />
</ion-item>

In my component.

import { NavController, NavParams, Slides, normalizeURL <--- } from 'ionic-angular'; 
import { CameraAccessProvider } from '../../providers/camera-access/camera-access';

  export class PicturePage {
    normalizedUrl: string; <--- 

      constructor() {
      this.normalizedUrl = "";
   }

  /** function to takePicture */
  this.getImage(){
    this.cameraProvider.transferImage()
     .then((res: string) => this.cameraProvider.createFileEntry(res))
     .then((entry: Entry) => this.normalizedUrl = normalizeURL(entry.nativeURL))
}     

In my provider

import { File, DirectoryEntry, FileEntry, Entry } from '@ionic-native/file';
import { FileTransfer, FileUploadOptions, FileTransferObject, FileUploadResult } from '@ionic-native/file-transfer';
//Not all of these are necessary for what I posted.

export class CameraAccessProvider {

 constructor(
   public file: File,
   public camera: Camera) { 
     console.log('Feel free to ask if you want me to clarify anything');
  }

// Initial function to take photo and respond with imagePath (since it's FILE_URI)
  transferImage(): Promise<any> {
    let options: CameraOptions = {
      sourceType: this.camera.PictureSourceType.CAMERA,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG
    }
     return this.camera.getPicture(options)
     .then((imagePath) => imagePath)
     .catch(err => err.message)
  }

Then I create a file entry with the imagePath

  createFileEntry(imagePath: string): Promise<any> {
   let cleansedPath = imagePath.replace(/^.*[\\\/]/, '');
   let d = new Date();
   let t = d.getTime();
   let newFileName: string = t + ".jpg";

    return this.file.moveFile(this.file.tempDirectory, cleansedPath, this.file.dataDirectory, newFileName)
    .then((entry: Entry) => entry)
    .catch((err) => err.message)
   }

the ((entry: Entry) is what I added normalizeUrl to up top. Without adding normalizeUrl, no image displays. With it, image shows up crystal clear.
FYI, only tested on iOS device

SUCCESS! Brilliant, thank you so much.

Any time. If you don’t mind, mark it as a solution to spare others from the nightmare!