,所以我正在访问用户的视频&通过自定义UICollectionView的照片,我的问题是,当我尝试通过手机上传到视频时,我会遇到此错误:
2017-09-03 13:09:20.884509-0400 Project[5797:2021536] Cannot get file size: Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_3476.MP4” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSFilePath=/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSUnderlyingError=0x17064f450 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4
2017-09-03 13:09:21.261767-0400 Project[5797:2021536] Body file is unreachable: /var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4
Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_3476.MP4” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSFilePath=/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSUnderlyingError=0x170651b20 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
这是我加载文件的地方
struct Media {
var image:UIImage?
var videoURL:NSURL?
}
var mediaArray = [Media]()
func grabPhotos(){
let imgManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
if fetchResult.count > 0 {
for i in 0..<fetchResult.count{
var mediaItem = Media()
//Used for fetch Image//
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 400, height: 400), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
mediaItem.image = imageOfVideo;
//Used for fetch Video//
imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
if let asset = avAsset as? AVURLAsset {
let videoData = NSURL(string: "(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
mediaItem.videoURL = videoData!
self.mediaArray.append(mediaItem)
print(self.mediaArray.count)
}
})
})
}
}
else{
//showAllertToImportImage()//A function to show alert
}
}
}
我认为在上传视频时与之无关,因为我可以从手机上录制视频,只是从手机本身上传。我只是在URL上转移到NextVC,例如:
let videoVC = PrepareVideoVC()
videoVC.url = outputFileURL as URL!
self.navigationController?.pushViewController(videoVC, animated: false)
我研究了该文件"无法打开,因为您没有权限查看它,但无法真正弄清楚如何实施
我也遇到了https://stackoverflow.com/a/41517165/7823620,但我再次尝试实施它,但无法获得它以免给我错误
也可以从模拟器上传,但不能从手机上传
它正在尝试从此目录获取文件:
NSFilePath=/var/mobile/Media/DCIM/
您可以尝试
url.startAccessingSecurityScopedResource()
<...>
url.stopAccessingSecurityScopedResource()
使用此选项:
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionCurrent;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
options.networkAccessAllowed = true;
如果您请求中间质量的视频,那么您将出现错误。错误域= nscocoaerrordomain代码= 257,无许可...
,因此,如果AppDelegate通过此方法传递在启动文档中:
func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
我发现我必须这样做才能修复它,以便使用上述Ivan的解决方案成功加载了FileManager文档,但是如果说该文档是电子邮件附件,则无法进行调用。
这为我修复了,再次感谢伊万·瓦维洛夫(Ivan Vavilov)的帖子。
func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
print("Doc attachment passed")
let docAttachment = url
// files written to 'tmp' are NOT backed up to iCloud or iTunes
let tempDir = getTempDirectory()
// add file name to tmp path
tempFileToLoad = tempDir.appendingPathComponent(docAttachment.lastPathComponent)
let fm = FileManager()
// passed a file from the FileManger app?
let isAttachmentScopedResource = docAttachment.startAccessingSecurityScopedResource()
do {
// put in tmp so we can read/write
try fm.copyItem(at: docAttachment, to: tempFileToLoad!)
if(isAttachmentScopedResource) {
// have MUST release the security access after calling it
docAttachment.stopAccessingSecurityScopedResource()
}
} catch {
print("Error getting file. (error)")
return false
}