Sample code changed to guard and pointing out the crash - ios

Here is my code
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()
})
}
}
}
Here I am setting live photo in the cell in loadVideoWithVideoUrl func. I changed to unwrap the value from ! to guard. And the app crashes at the end of func loadVideoWithVideoURL(_ videoURL: URL) where the I am setting the value to the cell.
guard let cell = self?.collectionView.cellForItem(at: indexPath as IndexPath) as? FullImageCollectionViewCell
else
{
fatalError()
//return
}

I suspect your crash is occurring because of the ! in this line:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as! FullImageCollectionViewCell
Change it to:
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FullImageCell", for: indexPath) as? FullImageCollectionViewCell else {
fatalError()
return
}
If it crashes executing the fatalError() line, then the problem is that the cast of cell to FullImageCollectionViewCell is failing.

Related

Scroll is not smooth when showing long text post in Label cells using CollectionView

i am making app with CollectionView cells using Swift and i fetching posts from my WordPress Website, i want to show posts in CollectionView cell and i want to show full text in Label, but the problem is that when is show posts on CollectionView , scroll is not smooth and sometimes it just stop scrolling for some seconds, this is my code to fetch posts..
func fetchPostData(completionHandler: #escaping ([Post]) -> Void ) {
let url = URL(string: "https://www.sikhnama.com/wp-json/wp/v2/posts/?categories=5&per_page=30&page=\(page)\(sortBy)")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else {return}
do {
let postsData = try JSONDecoder().decode([Post].self, from: data)
completionHandler(postsData)
DispatchQueue.main.async {
self.collectionView.reloadData()
SVProgressHUD.dismiss()
}
}
catch {
let error = error
print(String(describing: error))
}
}
task.resume()
}
this is in my CollectionViewCell
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
setNeedsLayout()
layoutIfNeeded()
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
var frame = layoutAttributes.frame
frame.size.height = ceil(size.height)
layoutAttributes.frame = frame
return layoutAttributes
}
and this is how i convert html to text
titleLabel.text = String(htmlEncodedString: hukam.content.rendered)
this is in Viewdid load
let layout = collectionView?.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = UICollectionViewFlowLayout.automaticSize
layout.estimatedItemSize = CGSize(width: view.frame.width-20, height: 40)
this is collectionView Extension
extension StatusViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return newsData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "postcell", for: indexPath) as! StatusViewCell
cell.setup(with: newsData[indexPath.row])
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
return cell
}
and this is how i setup constrain of label
this is my cpu profiler in Instruments
this is how i convert html to text
extension String {
init(htmlEncodedString: String) {
self.init()
guard let encodedData = htmlEncodedString.data(using: .utf8) else {
self = htmlEncodedString
return
}
let attributedOptions: [String : Any] = [
convertFromNSAttributedStringDocumentAttributeKey(NSAttributedString.DocumentAttributeKey.documentType): convertFromNSAttributedStringDocumentType(NSAttributedString.DocumentType.html),
convertFromNSAttributedStringDocumentAttributeKey(NSAttributedString.DocumentAttributeKey.characterEncoding): String.Encoding.utf8.rawValue
]
do {
let attributedString = try NSAttributedString(data: encodedData, options: convertToNSAttributedStringDocumentReadingOptionKeyDictionary(attributedOptions), documentAttributes: nil)
self = attributedString.string
} catch {
print("Error: \(error)")
self = htmlEncodedString
}
}
}
fileprivate func convertFromNSAttributedStringDocumentAttributeKey(_ input: NSAttributedString.DocumentAttributeKey) -> String {
return input.rawValue
}
fileprivate func convertFromNSAttributedStringDocumentType(_ input: NSAttributedString.DocumentType) -> String {
return input.rawValue
}
fileprivate func convertToNSAttributedStringDocumentReadingOptionKeyDictionary(_ input: [String: Any]) -> [NSAttributedString.DocumentReadingOptionKey: Any] {
return Dictionary(uniqueKeysWithValues: input.map { key, value in (NSAttributedString.DocumentReadingOptionKey(rawValue: key), value)})
}
I made a new application using tableView, there were cuts at the end of the descriptions of the news in my application, so I chose the label from the main Storyboard menu and made Autoshirink as Minimum font scale, I reduced it by 0.5 and it worked.
don't forget to make the lines zero because zero means you have infinite lines
This is how I parsed the data from JSON. I created a model, I put that model in an empty array here, then I added the data I parsed into my array, then when I show it in the cell, I print it according to the indexPath.row of this array.
func fetchNews(){
let urlRequest = URLRequest(url: URL(string: "https://inshorts.deta.dev/news?category="+categoryId)!)
loading.startAnimating()
let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
if error != nil {
print(error?.localizedDescription)
return
}
do{
let json = try JSONSerialization.jsonObject(with: data!) as! [String : AnyObject]
if let articklesFromJson = json["data"] as? [[String : AnyObject]]{
for articleFromJson in articklesFromJson {
let article = NewsModel()
if let title = articleFromJson["title"] as? String, let author = articleFromJson["author"] as? String, let content = articleFromJson["content"] as? String, let imageUrl = articleFromJson["imageUrl"] as? String {
article.author = author
article.content = content
article.title = title
article.imageUrl = imageUrl
}
self.News?.append(article)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}catch {
print("error")
}
}
task.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! tableCell
cell.titleCell.text = self.News?[indexPath.item].title
cell.authorCell.text = self.News?[indexPath.item].author
cell.textCell.text = self.News?[indexPath.item].content
cell.imgCell.dowloadImage(from: (self.News![indexPath.item].imageUrl!))
loading.stopAnimating()
return cell
}

How to preview a ppt document coming from the url in iOS11 swift 4

I am trying to preview the pdf and ppt documents coming from the remote urls and I am using QuickLookPreviewController to preview documents. So far I am able to preview pdfs and videos but when I open the ppt it opens the quickLookController and instead of the ppt preview I am seeing nothing
I don't know if this is the problem with QLPreviewController or there is some extra things I need to do for it to open. I am posting my code below so that you can understand whats wrong.
import UIKit
import Alamofire
import QuickLook
class AchievementsDetailViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,QLPreviewControllerDataSource {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var fileURLs = [URL]()
let quickLookController = QLPreviewController()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Achievements View"
quickLookController.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getAllAchievementsDetails()
}
func extractAndBreakFilenameInComponents(fileURL: NSURL) -> (fileName: String, fileExtension: String) {
let fileURLParts = fileURL.path!.components(separatedBy: "/")
let fileName = fileURLParts.last
let filenameParts = fileName?.components(separatedBy: ".")
return (filenameParts![0], filenameParts![1])
}
func getAllAchievementsDetails() {
fileURLs = []
let detailAchievementsURL = "\(WebAPI.baseURL +
WebAPI.detailAchievementAPI)\(appDelegate.userId)\(WebAPI.achievementId + id)"
Alamofire.request(detailAchievementsURL, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON {response in
switch response.result {
case .success:
let resposneString = response.result.value as! String
guard let detailAchievementData = Universal.convertStringToDictionary(text: resposneString) else {return}
switch response.response?.statusCode {
case 200?:
let imagesList = detailAchievementData["lstimages"] as! [[String : Any]]
for imageData in imagesList {
guard let imagePath = imageData["imagesurl"] else {return}
let imageString = "\(WebAPI.mediaBaseURL)\(imagePath)"
let image = imageString.replacingOccurrences(of: "~", with:"")
guard let imageURL = URL(string: image) else {return}
self.fileURLs.append(imageURL)
}
let videosList = detailAchievementData["lstvideos"] as! [[String : Any]]
for videoData in videosList {
guard let videoPath = videoData["videossurl"] else {return}
let videoString = "\(WebAPI.mediaBaseURL)\(videoPath)"
let video = videoString.replacingOccurrences(of: "~", with: "")
guard let videoURL = URL(string: video) else {return}
self.fileURLs.append(videoURL)
}
let docsList = detailAchievementData["lstdocuments"] as! [[String : Any]]
for documentData in docsList {
guard let documentPath = documentData["DocumentPath"] else {return}
let documentString = "\(WebAPI.mediaBaseURL)\(documentPath)"
let document = documentString.replacingOccurrences(of: "~", with: "")
guard let escapedAddress = document.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else {return}
guard let documentURL = URL(string: escapedAddress) else {return}
self.fileURLs.append(documentURL)
}
case 500?:
print(resposneString)
default:
print(resposneString)
}
case .failure(let error):
print(error.localizedDescription)
}
self.achievementsCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return fileURLs.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "mediaCell", for: indexPath) as! AchievementDetailCell
return cell
}
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return fileURLs.count
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return fileURLs[index] as QLPreviewItem
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let currentFileParts = extractAndBreakFilenameInComponents(fileURL: fileURLs[indexPath.row] as NSURL)
if currentFileParts.fileExtension == "pdf" || currentFileParts.fileExtension == "ppt" {
if QLPreviewController.canPreview(fileURLs[indexPath.row] as QLPreviewItem) {
quickLookController.currentPreviewItemIndex = indexPath.row
navigationController?.pushViewController(quickLookController, animated: true)
}
}
}
I hope everything is fine from my code...If not, please guide me.. Thanks in advance

data getting fetched from server after assigning it to collection view

I am new to swift language so not sure how to resolve this issue. Here I am trying to display images using uicollectionview. But I not getting the proper output as it does not show anything on collection view when executed. Need help friends.
View Did Load Function
override func viewDidLoad() {
super.viewDidLoad()
ImageGet()
}
Collection View
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(defectImages.count) // returns zero value here
return defectImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
cell.image.image = defectImages[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let largeVC = mainStoryBoard.instantiateViewController(withIdentifier: "ImageDisplayVC") as! ImageDisplayVC
largeVC.imgImage = defectImages[indexPath.row]
self.navigationController?.pushViewController(largeVC, animated: true)
}
Alamofire to get images
func ImageGet() {
let imageId = Int(details.id!)
let para: Parameters = ["imageId": imageId]
Alamofire.request(URL_IMG_List, method: .post, parameters: para).responseJSON { response in
if((response.result.value) != nil) {
let swiftyJsonVar = JSON(response.result.value!)
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
for index in 0..<self.arrRes.count{
self.imageData.file_name = self.arrRes[index]["file_name"] as! String
self.completeImagePath = self.get_image_path + self.imageData.file_name
self.imgpath.append(self.completeImagePath)
guard let url = URL(string: self.completeImagePath) else {return}
print(url)
if let data = try? Data(contentsOf: url) {
guard let image: UIImage = UIImage(data: data) else {return}
print(image)
self.defectImages.append(image as UIImage)
}
}
print(self.defectImages.count)
}
}
}
}
You just need to reload your collectionView once you fetch data from API and please check that you set your collectionView dataSource and delegate from storyBoard. if not than write below lines in viewDidLoad() before ImageGet().
self.collectionView.dataSource = self
self.collectionView.delegate = self
Replace below code with yours.
func ImageGet() {
let imageId = Int(details.id!)
let para: Parameters = ["imageId": imageId]
Alamofire.request(URL_IMG_List, method: .post, parameters: para).responseJSON { response in
if((response.result.value) != nil) {
let swiftyJsonVar = JSON(response.result.value!)
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
for index in 0..<self.arrRes.count{
self.imageData.file_name = self.arrRes[index]["file_name"] as! String
self.completeImagePath = self.get_image_path + self.imageData.file_name
self.imgpath.append(self.completeImagePath)
guard let url = URL(string: self.completeImagePath) else {return}
print(url)
if let data = try? Data(contentsOf: url) {
guard let image: UIImage = UIImage(data: data) else {return}
print(image)
self.defectImages.append(image as UIImage)
}
self.collectionView.reloadData() // RELOAD COLLECTIONVIEW
}
print(self.defectImages.count)
}
}
}
}

Swift: Saving photos to CoreData

I need to save images downloaded from the Internet to CoreData.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photos.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionPhotoCell", for: indexPath) as! PhotoCollectionCell
let photo = photos[(indexPath as NSIndexPath).row]
if let getImage = photo.getImage() {
cell.photoImageView.image = getImage
}
else {
// Photo Placeholder
cell.photoImageView.image = UIImage(named: "imgPlaceholder.png")
// Activity Indicator
cell.activityIndicator.isHidden = false
cell.activityIndicator.startAnimating()
FlickrClient().imageData(photo) {
(imageData, error) in
guard error == nil else {
return
}
DispatchQueue.main.async {
cell.activityIndicator.isHidden = true
cell.activityIndicator.stopAnimating()
cell.photoImageView.image = UIImage(data: imageData!)
}
}
}
cell.photoImageView.alpha = 1.0
return cell
}
Update:
In CoreData, the entity is Photos, and the Attribute is imageData. Looking at the code below, how does managedObjectContext.save(), save the downloaded images (in the collectionView) to CoreData? I'm still confused.
let photos = NSEntityDescription.insertNewObjectForEntityForName("Photo", inManagedObjectContext: self.managedObjectContext!) as Photo
do {
try managedObjectContext.save()
} catch {
fatalError("Failure to save")
}
You can get the managed object context from AppDelegate in this way:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
Step 1:-
first we have to find image's path into your simulator's document directory using
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsDirectory.appendingPathComponent("image.png")
print(fileURL)
if let data = image.pngData() {
do {
try data.write(to: fileURL)
let imgPath = "\(fileURL)"
imgCategoryPath = imgPath
} catch {
print("error saving file to documents:", error)
}
Step 2:-
second we have to retrive that image path from your simulator's document directory using
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if let dirPath = paths.first{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(nameOfImage).absoluteString
print(imageURL)
}
which path has got that store into core data in string formate column
Set Data
do {
try context.write(imageURL)
} catch {
print(error)
}
Read Data
do {
let imgString = try context.read(imageURL)
} catch {
print(error)
}

How to use NSCache and download Image From Url and Show images in CollectionViewCell?

I have a UICollectionViewCell and Inside that there is a imageView. My requirement is that I am getting Images Url from My_API and I want to download the Images from these Images Url and want to show them into a collectionViewCell imageView.
First thing is that how can I download the images from url I mean Which method is best and how to use NSCache in CollectionViewCell for images (in CellForRowAtIndexPath method).
Here is my code:
//MARK : DataSource
extension BrandImagesTableCell : UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if 0 != arrImages.count {
return self.arrImages.count
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BrandImagesCell", for: indexPath) as! BrandImagesCell
//let StrUrl = NSURL(string: self.arrImages[indexPath.row])! as URL
let urlPath: String = self.arrImages[indexPath.row]
let StrUrl: NSURL = NSURL(string: urlPath)!
if 0 != arrImages.count
{
cell.brandImage.downloadedFrom(url: StrUrl as URL)//, contentMode: .scaleToFill)
//cell.backgroundColor = UIColor.lightGray
}
return cell
}
}
In self.arrImages I have Images url.
And here is my download image method:
//Download Image from server.
extension UIImageView {
func downloadedFrom(url: URL) { //, contentMode mode: UIViewContentMode = .scaleAspectFit) {
//contentMode = mode
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { () -> Void in
self.image = image
}
}.resume()
}
}
So I want to know which method is better to download images, and do I have to use thread or NSCache?
Use KingFisher download this library and add into your project.
Use code like :
let ProfileUrl = YOUR_URL! as! String
if ProfileUrl.isEmpty == true {
YOURIMAGE_VIEW.image = UIImage.init(named: "ic_default_IMAGE.png")
}else{
let fbUrl = NSURL(string: ProfileUrl )!
YOURIMAGE_VIEW.kf_setImageWithURL(fbUrl, placeholderImage: nil,
optionsInfo: [.Transition(ImageTransition.Fade(1))],
progressBlock: { receivedSize, totalSize in
},
completionHandler: { image, error, cacheType, imageURL in
print("Finished")
})
}
Retrive image from cache file
KingfisherManager.sharedManager.retrieveImageWithURL(url, optionsInfo: nil, progressBlock: nil, completionHandler: { (image, error, cacheType, imageURL) -> () in
print(image)
})
Using Swift 3 :-
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BrandImagesCell", for: indexPath) as! BrandImagesCell
//let StrUrl = NSURL(string: self.arrImages[indexPath.row])! as URL
let urlPath: String = self.arrImages[indexPath.row]
//let StrUrl: NSURL = NSURL(string: urlPath)!
if 0 != arrImages.count
{
let imgUrl = urlPath
//Add Default image
if imgUrl.isEmpty == true {
cell.brandImage.image = UIImage.init(named: "placeholder.png")
}
else
{
let url = URL(string: imgUrl)!
cell.brandImage.kf.setImage(with: url,
placeholder: nil,
options: [.transition(.fade(0.5))],
progressBlock: { receivedSize, totalSize in
print("\(indexPath.row + 1): \(receivedSize)/\(totalSize)")
},
completionHandler: { image, error, cacheType, imageURL in
print("Finished")
//print("\(indexPath.row + 1): Finished")
})
}
}
return cell
}

Resources