示例代码更改为 guard 并指出崩溃
Sample code changed to guard and pointing out the crash
这是我的代码
func numberOfSections(in collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.getVideosArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
//let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as! FullImageCollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as? FullImageCollectionViewCell else {
fatalError()
}
let indexPath = indexPath.row
//UserDefaults.standard.set(indexPath, forKey: "INDEX")
//UserDefaults.standard.synchronize()
self.value = indexPath
let videoStr = NSString.init(format: "http://52.2.212.171/wallpaper/admin/%@", self.getVideosArray.object(at: indexPath) as! String)
self.downloadVideoLinkAndCreateAsset(videoStr as String)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize
{
return CGSize(width: self.collectionView.frame.size.width, height: self.collectionView.frame.size.height)
}
func downloadVideoLinkAndCreateAsset(_ videoLink: String)
{
self.bgView.isHidden = false
// use guard to make sure you have a valid url
guard let videoURL = URL(string: videoLink) else { return }
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// check if the file already exist at the destination folder if you don't want to download it twice
if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent(videoURL.lastPathComponent).path) {
// set up your download task
URLSession.shared.downloadTask(with: videoURL) { (location, response, error) -> Void in
// use guard to unwrap your optional url
guard let location = location else { return }
// create a deatination url with the server response suggested file name
let destinationURL = documentsDirectoryURL.appendingPathComponent(response?.suggestedFilename ?? videoURL.lastPathComponent)
do {
try FileManager.default.moveItem(at: location, to: destinationURL)
self.loadVideoWithVideoURL(destinationURL)
}
catch let error as NSError
{
print(error.localizedDescription)
}
}.resume()
}
else
{
let getPathUrl = documentsDirectoryURL.appendingPathComponent(videoURL.lastPathComponent)
self.loadVideoWithVideoURL(getPathUrl)
}
}
func loadVideoWithVideoURL(_ videoURL: URL) {
let asset = AVURLAsset(url: videoURL)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
let time = NSValue(time: CMTimeMakeWithSeconds(CMTimeGetSeconds(asset.duration)/2, asset.duration.timescale))
generator.generateCGImagesAsynchronously(forTimes: [time]) { [weak self] _, image, _, _, _ in
if let image = image, let data = UIImagePNGRepresentation(UIImage(cgImage: image)) {
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let imageURL = urls[0].appendingPathComponent("image.jpg")
try? data.write(to: imageURL, options: [.atomic])
let image = imageURL.path
let mov = videoURL.path
let output = FilePaths.VidToLive.livePath
let assetIdentifier = UUID().uuidString
let _ = try? FileManager.default.createDirectory(atPath: output, withIntermediateDirectories: true, attributes: nil)
do {
try FileManager.default.removeItem(atPath: output + "/IMG.JPG")
try FileManager.default.removeItem(atPath: output + "/IMG.MOV")
} catch {
}
JPEG(path: image).write(output + "/IMG.JPG",
assetIdentifier: assetIdentifier)
QuickTimeMov(path: mov).write(output + "/IMG.MOV",
assetIdentifier: assetIdentifier)
guard let targetSize = self?.collectionView.bounds.size else
{
fatalError()
//return
}
PHLivePhoto.request(withResourceFileURLs: [ URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.MOV"), URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.JPG")],
placeholderImage: nil,
targetSize: targetSize,
contentMode: PHImageContentMode.aspectFit,
resultHandler: { (livePhoto, info) -> Void in
guard let indexValue = self?.value else
{
fatalError()
//return
}
let indexPath = IndexPath.init(row: indexValue, section: 0)
print(indexPath)
guard let cell = self?.collectionView.cellForItem(at: indexPath as IndexPath) as? FullImageCollectionViewCell
else
{
fatalError()
//return
}
cell.fullImage.livePhoto = livePhoto
self?.bgView.isHidden = true
//self?.livePhotoView.livePhoto = livePhoto
//self?.collectionView.reloadData()
})
}
}
}
这里我在 loadVideoWithVideoUrl 函数的单元格中设置实时照片。我更改为从 !守卫。并且应用程序在 func loadVideoWithVideoURL(_ videoURL: URL) 结束时崩溃,我将值设置为单元格。
guard let cell = self?.collectionView.cellForItem(at: indexPath as IndexPath) as? FullImageCollectionViewCell
else
{
fatalError()
//return
}
我怀疑您的崩溃是由于此行中的 !
引起的:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as! FullImageCollectionViewCell
改为:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as? FullImageCollectionViewCell else {
fatalError()
return
}
如果它在执行 fatalError()
行时崩溃,那么问题是 cell
到 FullImageCollectionViewCell
的转换失败。
这是我的代码
func numberOfSections(in collectionView: UICollectionView) -> Int
{
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return self.getVideosArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
//let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as! FullImageCollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as? FullImageCollectionViewCell else {
fatalError()
}
let indexPath = indexPath.row
//UserDefaults.standard.set(indexPath, forKey: "INDEX")
//UserDefaults.standard.synchronize()
self.value = indexPath
let videoStr = NSString.init(format: "http://52.2.212.171/wallpaper/admin/%@", self.getVideosArray.object(at: indexPath) as! String)
self.downloadVideoLinkAndCreateAsset(videoStr as String)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize
{
return CGSize(width: self.collectionView.frame.size.width, height: self.collectionView.frame.size.height)
}
func downloadVideoLinkAndCreateAsset(_ videoLink: String)
{
self.bgView.isHidden = false
// use guard to make sure you have a valid url
guard let videoURL = URL(string: videoLink) else { return }
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// check if the file already exist at the destination folder if you don't want to download it twice
if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent(videoURL.lastPathComponent).path) {
// set up your download task
URLSession.shared.downloadTask(with: videoURL) { (location, response, error) -> Void in
// use guard to unwrap your optional url
guard let location = location else { return }
// create a deatination url with the server response suggested file name
let destinationURL = documentsDirectoryURL.appendingPathComponent(response?.suggestedFilename ?? videoURL.lastPathComponent)
do {
try FileManager.default.moveItem(at: location, to: destinationURL)
self.loadVideoWithVideoURL(destinationURL)
}
catch let error as NSError
{
print(error.localizedDescription)
}
}.resume()
}
else
{
let getPathUrl = documentsDirectoryURL.appendingPathComponent(videoURL.lastPathComponent)
self.loadVideoWithVideoURL(getPathUrl)
}
}
func loadVideoWithVideoURL(_ videoURL: URL) {
let asset = AVURLAsset(url: videoURL)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
let time = NSValue(time: CMTimeMakeWithSeconds(CMTimeGetSeconds(asset.duration)/2, asset.duration.timescale))
generator.generateCGImagesAsynchronously(forTimes: [time]) { [weak self] _, image, _, _, _ in
if let image = image, let data = UIImagePNGRepresentation(UIImage(cgImage: image)) {
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let imageURL = urls[0].appendingPathComponent("image.jpg")
try? data.write(to: imageURL, options: [.atomic])
let image = imageURL.path
let mov = videoURL.path
let output = FilePaths.VidToLive.livePath
let assetIdentifier = UUID().uuidString
let _ = try? FileManager.default.createDirectory(atPath: output, withIntermediateDirectories: true, attributes: nil)
do {
try FileManager.default.removeItem(atPath: output + "/IMG.JPG")
try FileManager.default.removeItem(atPath: output + "/IMG.MOV")
} catch {
}
JPEG(path: image).write(output + "/IMG.JPG",
assetIdentifier: assetIdentifier)
QuickTimeMov(path: mov).write(output + "/IMG.MOV",
assetIdentifier: assetIdentifier)
guard let targetSize = self?.collectionView.bounds.size else
{
fatalError()
//return
}
PHLivePhoto.request(withResourceFileURLs: [ URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.MOV"), URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.JPG")],
placeholderImage: nil,
targetSize: targetSize,
contentMode: PHImageContentMode.aspectFit,
resultHandler: { (livePhoto, info) -> Void in
guard let indexValue = self?.value else
{
fatalError()
//return
}
let indexPath = IndexPath.init(row: indexValue, section: 0)
print(indexPath)
guard let cell = self?.collectionView.cellForItem(at: indexPath as IndexPath) as? FullImageCollectionViewCell
else
{
fatalError()
//return
}
cell.fullImage.livePhoto = livePhoto
self?.bgView.isHidden = true
//self?.livePhotoView.livePhoto = livePhoto
//self?.collectionView.reloadData()
})
}
}
}
这里我在 loadVideoWithVideoUrl 函数的单元格中设置实时照片。我更改为从 !守卫。并且应用程序在 func loadVideoWithVideoURL(_ videoURL: URL) 结束时崩溃,我将值设置为单元格。
guard let cell = self?.collectionView.cellForItem(at: indexPath as IndexPath) as? FullImageCollectionViewCell
else
{
fatalError()
//return
}
我怀疑您的崩溃是由于此行中的 !
引起的:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as! FullImageCollectionViewCell
改为:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as? FullImageCollectionViewCell else {
fatalError()
return
}
如果它在执行 fatalError()
行时崩溃,那么问题是 cell
到 FullImageCollectionViewCell
的转换失败。