In my app, showing all videos from photos. When a video is selected, it is played with avplayer. But when i tried to get the size (kb) of the selected video file, it shows error. The same error appeared when i tried to copy the video file.
I have taken those permissions:
<key>NSCameraUsageDescription</key>
<string>App needs to access camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>App need to access microphone</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App needs to access photos and videos</string>
Code to get size:
func fileSize(forURL url: Any) -> Double {
var fileURL: URL?
var fileSize: Double = 0.0
if url is URL || url is String {
if url is URL {
fileURL = url as? URL
}
else {
fileURL = URL(fileURLWithPath: url as! String)
}
var fileSizeValue = 0.0
do{
try fileSizeValue = (fileURL?.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).allValues.first?.value as! Double?)!
if fileSizeValue > 0.0 {
fileSize = (Double(fileSizeValue) / (1024 * 1024))
}
} catch {
print("file size error: \(error)")
}
}
return fileSize
}
let fileSize = fileSize(forURL: selectedVideos[0] as Any)
video file url: "file:///var/mobile/Media/DCIM/107APPLE/IMG_7728.MOV"
Error: Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_7728.MOV” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/107APPLE/IMG_7728.MOV, NSFilePath=/var/mobile/Media/DCIM/107APPLE/IMG_7728.MOV, NSUnderlyingError=0x1c445ef90 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Edit: I have changed url to path. But still shows error:
let selectedFilePath = (selectedVideos[0] as! URL).path
print("video path: \(selectedFilePath)")
do{
let attributes = try FileManager.default.attributesOfItem(atPath: selectedFilePath)
let fileSize = attributes[.size] as! NSNumber
print("file size: \(fileSize)")
} catch {
print("file size error: \(error)")
}
let filePath = get_directory().appendingPathComponent("video\(CACurrentMediaTime()).MOV")
print("copy to path: \(filePath.path)")
do {
try FileManager.default.copyItem(atPath: selectedFilePath, toPath: filePath.path)
} catch {
print("copy error: \(error)")
}
Error:
video path: /var/mobile/Media/DCIM/107APPLE/IMG_7789.MOV
file size error: Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_7789.MOV” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/107APPLE/IMG_7789.MOV, NSUnderlyingError=0x1c0259530 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
copy to path: /var/mobile/Containers/Data/Application/5AAD29BD-489D-4737-AA98-E6131EFBA94D/Documents/addMusicToVideos/voices/video1171047.69338271.MOV
copy error: Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_7789.MOV” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/107APPLE/IMG_7789.MOV, NSUnderlyingError=0x1c4859830 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
url.path
– PiterPanurl
Any
although onlyURL
orString
is expected? That's horrible. Do your homework at design time and declare the type asURL
. Then the compiler will tell you all places where you are going to pass a string (or something else) and you can fix the code by creating the URL before calling the function. This avoids the unnecessary and expensive runtime check. Even a second function which takes a string, creates the URL and calls the function is much more efficient. – vadian