-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🐛 RN 0.74, RNVC 4.3.2. Take a photo or snapshot on iOS, the file does not exist at the path indicated by the response #3009
Comments
Guten Tag, Hans here. Note New features, bugfixes, updates and other improvements are all handled mostly by |
Add a file:// prefix |
Thanks, @mrousavy, but the file:// prefix is already included in As I tried to explain in my original post, the folder the file was saved in doesn't exist when program control returns from I edited PhotoCaptureDelegate.swift to log the path and whether the file exists. It DOES exist immediately after taking the picture, but if I add code to check if that same file still exists, pod install, and re-run the app, the first file NO LONGER exists. So, it seems to me the photo file along with its containing folder [uuid]/tmp is being deleted before control returns from Here's the func photoOutput(_: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
defer {
removeGlobal()
}
if let error = error as NSError? {
promise.reject(error: .capture(.unknown(message: error.description)), cause: error)
return
}
do {
let path = try FileUtils.writePhotoToTempFile(photo: photo, metadataProvider: metadataProvider)
// Does the path of a previous photo still exist?
if FileManager.default.fileExists(atPath: "/private/var/mobile/Containers/Data/Application/629FC6E1-1F8F-46B9-8D08-1CAF06EC450A/tmp/29A98AB6-0B9C-4F34-9846-23D036EAD751.jpeg") {
print("Old path exists: /private/var/mobile/Containers/Data/Application/629FC6E1-1F8F-46B9-8D08-1CAF06EC450A/tmp/29A98AB6-0B9C-4F34-9846-23D036EAD751.jpeg")
} else {
print("Old path does not exist: /private/var/mobile/Containers/Data/Application/629FC6E1-1F8F-46B9-8D08-1CAF06EC450A/tmp/29A98AB6-0B9C-4F34-9846-23D036EAD751.jpeg")
}
// path of the photo we just took
print("Photo saved to path: \(path.absoluteString)")
let exif = photo.metadata["{Exif}"] as? [String: Any]
let width = exif?["PixelXDimension"]
let height = exif?["PixelYDimension"]
let exifOrientation = photo.metadata[String(kCGImagePropertyOrientation)] as? UInt32 ?? CGImagePropertyOrientation.up.rawValue
let cgOrientation = CGImagePropertyOrientation(rawValue: exifOrientation) ?? CGImagePropertyOrientation.up
let orientation = getOrientation(forExifOrientation: cgOrientation)
let isMirrored = getIsMirrored(forExifOrientation: cgOrientation)
// Verify the file exists for the photo we just took
if FileManager.default.fileExists(atPath: path.path) {
print("File exists at path: \(path.path)")
} else {
print("File does not exist at path: \(path.path)")
}
promise.resolve([
"path": path.absoluteString,
"width": width as Any,
"height": height as Any,
"orientation": orientation,
"isMirrored": isMirrored,
"isRawPhoto": photo.isRawPhoto,
"metadata": photo.metadata,
"thumbnail": photo.embeddedThumbnailPhotoFormat as Any,
])
} catch let error as CameraError {
promise.reject(error: error)
} catch {
promise.reject(error: .capture(.unknown(message: "An unknown error occured while capturing the photo!")), cause: error as NSError)
}
} I hope this clarification is helpful! I very much appreciate help in resolving this issue. It seems so strange that In case it matters: I'm running Xcode 15.1 on an M1 mac Mini, running macOS Sonoma 14.5. |
I have a workaround!
So I was barking up a forest of wrong trees because I thought I had already checked that workaround. I'm a dummy, but at least I learned a little bit this week. (The fact that I'm a dummy I already knew.) I'll leave this issue open since it seems to me that this is a bug: on iOS, res.path in my opinion should return a useable path like it does on Android. @mrousavy thanks again for an outstandingly helpful component! |
Hm this is very weird. Why would I be able to write to that path if it doesn't exist.... |
iOS paths do seem weird to me. For example, in your Swift code when a photo is taken, it writes to a path that starts with /private in writeDataToTempFile (in ios/Core/Utils/FileUtils.swift). Immediately after that Additionally, every time I run my app (which I do from Xcode, with Metro running), the path to where pics are taken has a different uuid. For example, I reported above RNVC returned path: 'file:///private/var/mobile/Containers/Data/Application/5CF1ADC7-3D83-4415-BB1C-EB3ADCE8DC77/tmp/5CCB9739-3EFD-4FBB-95C3-C361B8262B1B.jpeg'. Every time I run, I get a different uuid in place of the folder 5CF1ADC7-3D83-4415-BB1C-EB3ADCE8DC77. Yet, the old photos that I didn't move from each time I ran my app previously and took photos, they are all there in the path with the new uuid folder. All that to say, it seems to me iOS is doing some strange things with folders, maybe creating a new symlink every time I run my app and pointing them all to the same place, and always having the /private and NOT /private paths point to the same place, but /private is not allowed at the main app level, only in the Swift code? |
This can't be, maybe I return a different path. Either way, I am using react-native-vision-camera 4.3.2 in ShadowLens in production and it works perfectly fine, so I don't think this is a bug in VisionCamera? |
My best guess at this point is that I'm passing different parameters to RNVC than you do in ShadowLens, and that somehow the combination of parameters, maybe in conjunction with something else in my environment, causes this issue. You've probably heard the old software developer's adage that "Nothing can be foolproof because fools are so ingenious". Maybe I've been the fool in that proverb in this case and, while trying to use RNVC as intended, I've somehow landed on a combination that causes this issue. In any case, it's great that in ShadowLens you have a way to use RNVC that works, and for now my workaround works for me. If it becomes a problem again I'll revisit this issue. I'm currently wrestling with some orientation issues with RNVC on iOS. If I can't resolve them I'll open a separate issue, if my problems aren't already covered by what other people have found - I notice a few currently open issues dealing with orientation. Thanks again, I really appreciate RNVC and all your work on it! |
This is the function where I take a photo, from the reproducible code I included with my original post: const onTakePhotoPress = async () => {
if (camera && camera.current) {
const res = await camera.current.takePhoto();
console.log('res', res);
const resPathExists = await RNFetchBlob.fs.exists(res.path);
console.log('res.path exists?', resPathExists); // no errors, but this is always false
}
}; After taking a photo, I log the response, then I check to see if the But I found that on iOS, if I strip off the "file:///private" that is always at the beginning of const sourcePath = Platform.OS === 'ios' ? res.path.replace('file:///private', '') : res.path; In my real app, after taking the photo (and now utilizing my workaround to get a path that works) I move the file to where my app persists its data on the user's phone, using await RNFetchBlob.fs.mv(oldPath, newPath) |
What's happening?
I recently upgraded my project to React Native 0.74 and RNVC 4.3.2. Works great on Android!
But on iOS, when I take a photo or snapshot there is no error, but the path in the response does not exist. Where did the file go?
In the response path, this part of the path exists on the device:
/private/var/mobile/Containers/Data/Application/
, but the uuid subdirectory that comes next in the response path does not exist. Similarly,/var/mobile/Containers/Data/Application/
(without/private
) exists, but not the uuid subdirectory.I tried to get the example project to run, but I failed.
yarn bootstrap
failed with "Could not find 'bundler' (2.3.22) required by your [path]/Gemfile.lock." I don't know how to fix this, and all my rather blind attempts to follow suggestions I found online failed. I also tried to get the example project running withyarn install
from the "example" directory, andpod install
from "example/ios". Still getting incomprehensible errors in Xcode.So I created a minimal example to demonstrate the RNVC issue and pasted it into the Reproduceable Code section below. Tap to take a picture, and the log shows the response from
takePhoto()
. It also shows whether the path returned bytakePhoto()
exists. And that's the issue: at least for me, it never exists on iOS.EDIT: video works fine on iOS. It's just taking photos and snapshots that has the bad path issue.
Reproduceable Code
Relevant log output
Camera Device
Device
iPhone X (iOS 16.7.8)
VisionCamera Version
4.3.2
Can you reproduce this issue in the VisionCamera Example app?
No, I cannot reproduce the issue in the Example app
Additional information
The text was updated successfully, but these errors were encountered: