Capacitor 5 - iOS savePhoto from public/images file
On iOS: Experiencing a issue in attempting to use Media.savePhoto on an image that is saved locally within the apps /public/imgs/ folder.
For paths I have tried using /imgs/example.png as well as capacitor://localhost/_capacitor_file_/imgs/8.png which I got from using Capacitor.converFileSrc
Errors were the same for both:
Task <4BC40F3D-FEAF-4748-9D84-9843D952E56F>.<1> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=capacitor://localhost/_capacitor_file_/imgs/8.png, NSErrorFailingURLKey=capacitor://localhost/_capacitor_file_/imgs/8.png, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <4BC40F3D-FEAF-4748-9D84-9843D952E56F>.<1>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <4BC40F3D-FEAF-4748-9D84-9843D952E56F>.<1>, NSUnderlyingError=0x600000d34300 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}}
ERROR MESSAGE: {"errorMessage":"Unable to download image from url","message":"Unable to download image from url"}
I am able to use these as srcs in img tags to view the images in app but cannot save them?
Any tips or something I might be missing? Preferably not upgrade.
Hm, very interesting. I've never tried this before, and while it definitely seems possible, I'm not sure what path would get it to work. I'll try to look into this in the coming week. Until then, the plugin supports base64 encoded images, if that'll work for your use case.
Looks like it's possible.
You need to get the absolute path of the asset on the device, instead of using a web URL or relative URL. On iOS, that involves the bundle path (Swift: Bundle.main.bundleURL.absoluteString). I'm not sure if there's a plugin that can get you bundle URL. In my testing, I just added the bundle to albums:
// In fetchAlbumsToJs in swift
var o = JSObject()
o["name"] = "Bundle"
o["identifier"] = Bundle.main.bundleURL.absoluteString
o["type"] = "smart" // = system-generated
albums.append(o)
This is necessary to get every time because bundle URL constantly changes. Almost certainly not the best way to do this, but it's what I did for testing.
Then, you can save your asset using the bundle URL:
// works in the example app
const albums = (await Media.getAlbums()).albums;
const album = albums.find(a => a.name === "Bundle");
let opts: MediaSaveOptions = { path: album!.identifier + "public/assets/image.png" };
await Media.savePhoto(opts);
If you can't find a plugin that gives bundle URL, you may need to patch this into the plugin with the code provided here, or something else (you could add a function to the plugin to return bundle URL or something). I recommend using patch package.