I am trying to make api call and print the result at UICollectionView cellForItemAt function but UICollectionView is lagging while fetching data from api. I tried collection view prefetching api but I couldn't implement it. How can I solve lagging scroll problem? Here is the problem:
Here is my api call class:
class ApiManager {
static var url: String?
static var header: [String : String]?
static var httpMethod: String?
static let session = URLSession.shared
static func getTask(itemName: String, completion:#escaping ([String]) -> Void) -> URLSessionDataTask {
let url = URL(string: ApiManager.url!)
var request = URLRequest(url: url!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.allHTTPHeaderFields = ApiManager.header!
request.httpMethod = ApiManager.httpMethod
let session = ApiManager.session
let dataTask = session.dataTask(with: request) { data, response, error in
if error == nil && data != nil {
if (error != nil) {
print(error!)
} else {
do {
if let dictionary = try JSONSerialization.jsonObject(with: data!, options: []) as? [[String:Any]] {
var itemArray = [String]()
for index in 0...dictionary.count - 1 {
if let items = dictionary[index][itemName] as? String {
itemArray.append(items)
}
}
completion(itemArray)
}
} catch {
}
}
}
}
return dataTask
}
}
Here is my ViewController code:
class ViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!
var quoteArray = [String]()
var categories = ["love", "motivational", "mothersday", "all"]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
for category in categories {
ApiManager.url = "https://famous-quotes4.p.rapidapi.com/random?category=\(category)&count=1000"
}
ApiManager.header = ["x-rapidapi-host": "famous-quotes4.p.rapidapi.com", "x-rapidapi-key": "SECRET_API_KEY" ]
ApiManager.httpMethod = "GET"
ApiManager.getTask(itemName: "text") { items in
DispatchQueue.main.async {
self.quoteArray.append(contentsOf: items)
self.collectionView.reloadData()
}
}.resume()
}
}
Here is my cellForItemAt func code:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? Cell else { fatalError("cell dequeue error") }
cell.label.text = self.quoteArray[indexPath.row]
return cell
}
Related
I have backend api it contains all values i can see those values in postman.. but while parsing i am unable to download all values from api.. some times i am getting all values.. some times i am not getting only some values.. if i close app and run again then i am getting all values.. again if i close and run or if i go to other viewcontroller and coming back to home then i am missing some values. if i print jsonObj i am not getting all values from api.. why is this happening?
here is my code:
import UIKit
import SDWebImage
struct JsonData {
var iconHome: String?
var typeName: String?
var id: String?
init(icon: String, tpe: String, id: String) {
self.iconHome = icon
self.typeName = tpe
self.id = id
}
}
class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITextFieldDelegate {
#IBOutlet weak var collectionView: UICollectionView!
var itemsArray = [JsonData]()
override func viewDidLoad() {
super.viewDidLoad()
homeServiceCall()
//Do any additional setup after loading the view.
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return itemsArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! HomeCollectionViewCell
let aData = itemsArray[indexPath.row]
cell.paymentLabel.text = aData.typeName
cell.paymentImage.sd_setImage(with: URL(string:aData.iconHome ?? ""), placeholderImage: UIImage(named: "varun finance5_icon"))
return cell
}
//MARK:- Service-call
func homeServiceCall(){
let urlStr = "https://dev.com/webservices//getfinancer"
let url = URL(string: urlStr)
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
guard let respData = data else {
return
}
guard error == nil else {
print("error")
return
}
do{
let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
print("the home json is \(jsonObj)")
let financerArray = jsonObj["financer"] as! [[String: Any]]
for financer in financerArray {
guard let id = financer["id"] as? String else { break }
guard let pic = financer["icon"] as? String else { break }
guard let typeName = financer["tpe"] as? String else { break } //changed this one to optional too. Avoid force-unwrapping. Keep everything safe
let jsonDataObj = JsonData(icon: pic, tpe: typeName, id: id)
self.itemsArray.append(jsonDataObj)
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
catch {
print("catch error")
}
}).resume()
}
}
Please help me in the above code.
Try network call with background thread.
DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {
self.homeServiceCall()
}
And the URL is legal with double / as below ?
let urlStr = "https://dev.com/webservices//getfinancer"
And check the all of your backend data's is compatible with your JSONSerialization type of JsonData struct.
I hope it helps.
This is my controller that I am using to lookup the specific books. When I type in the search bar, no book information is displayed back to me while I type or after I finish typing. I would like to understand why and find a solution that would remedy this problem.
import UIKit
class TextbookSearchViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var tableView: UITableView!
var booksFound = [[String: AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
}
func queryBooks(bookTitle: String) {
let stringURL = "https://www.googleapis.com/books/v1/volumes?q=\(bookTitle)"
guard let url = URL(string: stringURL) else {
print("Problem with URL")
return
}
let urlRequest = URLRequest(url: url as URL)
let urlSession = URLSession.shared
let queryTask = urlSession.dataTask(with: urlRequest) { (data, response, error) in
guard let jsonData = data else {
print("No Information could be Found:")
return
}
do {
let json = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as! [String: AnyObject]
let tableItems = json["Items"] as! [[String: AnyObject]]
self.booksFound = tableItems
self.tableView.reloadData()
} catch {
print("Error with JSON: ")
}
}
queryTask.resume()
}
}
extension TextbookSearchViewController: UITableViewDataSource {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return booksFound.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath)
if let volumeInfo = self.booksFound[indexPath.row]["volumeInfo"] as? [String: AnyObject] {
cell.textLabel?.text = volumeInfo["title"] as? String
cell.detailTextLabel?.text = volumeInfo["subtitle"] as? String
}
return cell
}
}
extension TextbookSearchViewController: UISearchBarDelegate {
func searchBarButtonClicked(searchBar: UISearchBar) {
let bookTitle = searchBar.text?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
self.queryBooks(bookTitle: bookTitle!)
searchBar.resignFirstResponder()
}
}
Probably you forget to set UISearchBar delegate
#IBOutlet weak var searchBar: UISearchBar! {
didSet {
searchBar.delegate = self
}
}
Also, you need below in place of func searchBarButtonClicked(searchBar: UISearchBar)
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
// your code
}
Key in response is items not Items
Use json["items"] in place of json["Items"]
Complete code:
import UIKit
class TextbookSearchViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var searchBar: UISearchBar! {
didSet {
searchBar.delegate = self
}
}
#IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
}
}
var booksFound = [[String: AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
}
}
extension TextbookSearchViewController: UITableViewDataSource {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return booksFound.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath)
if let volumeInfo = self.booksFound[indexPath.row]["volumeInfo"] as? [String: AnyObject] {
cell.textLabel?.text = volumeInfo["title"] as? String
cell.detailTextLabel?.text = volumeInfo["subtitle"] as? String
}
return cell
}
}
extension TextbookSearchViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
let bookTitle = searchBar.text?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
queryBooks(bookTitle: bookTitle!)
searchBar.resignFirstResponder()
}
func queryBooks(bookTitle: String) {
let stringURL = "https://www.googleapis.com/books/v1/volumes?q=\(bookTitle)"
guard let url = URL(string: stringURL) else {
print("Problem with URL")
return
}
let urlRequest = URLRequest(url: url as URL)
let urlSession = URLSession.shared
let queryTask = urlSession.dataTask(with: urlRequest) { [weak self] (data, response, error) in
guard let jsonData = data else {
print("No Information could be Found:")
return
}
do {
let json = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as! [String: AnyObject]
guard let tableItems = json["items"] as? [[String: AnyObject]] else {
self?.booksFound = [[String: AnyObject]]()
return
}
print(tableItems)
self?.booksFound = tableItems
DispatchQueue.main.async {
self?.tableView.reloadData()
}
} catch {
print("Error with JSON: ")
}
}
queryTask.resume()
}
}
I don't know why but when I open the app, it takes a while to load all the data on the screen, until there remains a white screen without content. All the data loaded is downloaded from an API. What should I do to make it better?
App Loaded after about 10 seconds:
I'll post below how I'm parsing all the data.
ViewController.swift:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UITableViewDataSource {
#IBOutlet weak var tableViewTopSell: UITableView!
#IBOutlet var collectionView: UICollectionView!
#IBOutlet weak var collectionViewBanner: UICollectionView!
var dataSource: [Content] = [Content]()
var dataBanner: [Banner] = [Banner]()
var dataTopSold: [Top10] = [Top10]()
override func viewDidLoad() {
super.viewDidLoad()
//SetupNavBarCustom
self.navigationController?.navigationBar.CustomNavigationBar()
let logo = UIImage(named: "tag.png")
let imageView = UIImageView(image:logo)
self.navigationItem.titleView = imageView
//CallAPIData
getTopSold { (data) in
DispatchQueue.main.async {
self.dataTopSold = data
self.tableViewTopSell.reloadData()
}
}
getBanner { (data) in
DispatchQueue.main.async {
self.dataBanner = data
self.collectionViewBanner.reloadData()
}
}
getAudiobooksAPI { (data) in
DispatchQueue.main.async {
self.dataSource = data
self.collectionView.reloadData()
}
}
}
//CollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (collectionView == self.collectionView) {
return self.dataSource.count
}else{
return self.dataBanner.count
}}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (collectionView == self.collectionView) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell
let content = self.dataSource[indexPath.item]
cell.bookLabel.text = content.descricao
cell.bookImage.setImage(url: content.urlImagem, placeholder: "")
return cell
}else if (collectionView == self.collectionViewBanner) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCellBanner", for: indexPath) as! CollectionViewCell
let content = self.dataBanner[indexPath.item]
cell.bannerImage.setImage(url: content.urlImagem, placeholder: "")
return cell
}
return UICollectionViewCell()
}
//TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataTopSold.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "topSoldCell", for: indexPath) as! TableViewCell
let content = self.dataTopSold[indexPath.item]
cell.labelNomeTopSell.text = content.nome
cell.imageViewTopSell.setImage(url: content.urlImagem, placeholder: "")
return cell
}
}
extension UIImageView{
func setImage(url : String, placeholder: String, callback : (() -> Void)? = nil){
self.image = UIImage(named: "no-photo")
URLSession.shared.dataTask(with: NSURL(string: url)! as URL, completionHandler: { (data, response, error) -> Void in
guard error == nil else{
return
}
DispatchQueue.main.async(execute: { () -> Void in
let image = UIImage(data: data!)
self.image = image
if let callback = callback{
callback()
}
})
}).resume()
}
}
DataStore.swift:
import Foundation
import UIKit
func getBanner(_ completion:#escaping ([Banner])->Void) {
let url = URL(string: "https://alodjinha.herokuapp.com/banner")
let session = URLSession.shared
guard let unwrappedURL = url else { print("Error unwrapping URL"); return }
let dataTask = session.dataTask(with: unwrappedURL) { (data, response, error) in
guard let unwrappedDAta = data else { print("Error unwrapping data"); return }
do {
let jsonBanner = try JSONDecoder().decode(BannerData.self, from: unwrappedDAta)
completion(jsonBanner.data)
} catch {
print("Could not get API data. \(error), \(error.localizedDescription)")
}
}
dataTask.resume()
}
func getTopSold(_completion:#escaping ([Top10])->Void) {
let url = URL(string: "https://alodjinha.herokuapp.com/produto/maisvendidos")
let session = URLSession.shared
guard let unwrappedURL = url else { print("Error url"); return}
let dataTask = session.dataTask(with: unwrappedURL) { (data, response, error) in
guard let unwrappedData = data else { print("Error data"); return}
do {
let jsonTop10 = try JSONDecoder().decode(Top10Data.self, from: unwrappedData)
_completion(jsonTop10.data)
}catch{
print("Could no get API data")
}
}
dataTask.resume()
}
Model.swift:
import Foundation
//Categorias
struct Contents : Decodable {
let data : [Content]
}
struct Content : Decodable {
let id : Int
let descricao : String
let urlImagem : String
}
//Banner
struct BannerData : Decodable {
let data : [Banner]
}
struct Banner : Decodable {
let id : Int
let urlImagem : String
let linkUrl : String
}
//Top10
struct Top10Data:Decodable {
let data: [Top10]
}
struct Top10:Decodable {
let id : Int
let nome : String
let urlImagem : String
}
Apart from it's a heavy network loading VC , you Currently don't have any problems loading the data as all are out of main thread , the only problem is loading the images as when you scroll it re-download the image again which may be just downloaded for this i recommend using SDWebImage which will take care of the download & cache for you , your main problem may be low network speed for many requests
Another thing to manage this network problem you may serial queue the download of the data that will help you load one part fastly and display it which will make the impression to the user that the app is in request for more data instead of make all the requests at once
I already new in swift 3 and objetive c, right now I am stuck into how can I pass the id of each row to another table view controller when the user tap in the row the user want to go.
Here is the json data firstFile:
[
{"id_categoria":"1","totalRows":"323","nombre_categoria":"Cirug\u00eda"},
{"id_categoria":"2","totalRows":"312","nombre_categoria":"Med Interna"},
{"id_categoria":"3","totalRows":"6","nombre_categoria":"Anatomia"},
{"id_categoria":"4","totalRows":"24","nombre_categoria":"Anestesiologia"},
...]
Here is my first table view controller:
import UIKit
class CatMedVC: UIViewController, UITableViewDataSource {
#IBAction func volver(_ sender: Any) { }
#IBOutlet weak var listaCategoria: UITableView!
var fetchedCategoria = [Categoria]()
override func viewDidLoad() {
super.viewDidLoad()
listaCategoria.dataSource = self
parseData()
}
override var prefersStatusBarHidden: Bool{
return true
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fetchedCategoria.count
}
public func tableView(_ tableView: UITableView, cellForRowAt IndexPath: IndexPath) ->
UITableViewCell {
let cell = listaCategoria.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text = fetchedCategoria[IndexPath.row].esp
cell?.detailTextLabel?.text = fetchedCategoria [IndexPath.row].totalRows
return cell!
}
func parseData() {
let url = "http://www.url.com/firstFile.php" //in json format
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) { (data, response, error) in
if(error != nil) {
print("Error")
}
else {
do {
let fetchedData = try JSONSerialization.jsonObject(with:data!, options: .mutableLeaves) as! NSArray
//print(fetchedData)
for eachFetchedCategoria in fetchedData {
let eachCategoria = eachFetchedCategoria as! [String : Any]
let nombre_categoria = eachCategoria["nombre_categoria"] as! String
let totalRows = eachCategoria["totalRows"] as! String
let id_categoria = eachCategoria["id_categoria"] as! String
self.fetchedCategoria.append(Categoria(nombre_categoria: nombre_categoria, totalRows: totalRows, id_categoria: id_categoria))
}
//print(self.fetchedCategoria)
self.listaCategoria.reloadData()
}
catch {
print("Error 2")
}
}
}
task.resume()
}
}
class Categoria {
var nombre_categoria : String
var totalRows : String
var id_categoria : String
init(nombre_categoria : String, totalRows : String, id_categoria : String) {
self.nombre_categoria = nombre_categoria
self.totalRows = totalRows
self.id_categoria = id_categoria
}
}
So I need pass the id_categoria String into the another table view to show the data for the id selected previously...here I don't know how to do it...I have the json file waiting for the id selected previously..but I don't know how to catch it into the url
Here the second table view:
import UIKit
class EspMedVC: UITableViewController {
var TableData:Array< String > = Array < String >()
var EspecialidadArray = [String]()
#IBAction func volver(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
get_data_from_url("http://www.url.com/secondFile.php?id=") // Here I need to put the id_categoria String in json format
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
cell.textLabel?.text = TableData[indexPath.row]
return cell
}
func get_data_from_url(_ link:String)
{
let url:URL = URL(string: link)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
self.extract_json(data!)
})
task.resume()
}
func extract_json(_ data: Data)
{
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
}
catch
{
return
}
guard let data_list = json as? NSArray else
{
return
}
if let nombre_especialidad = json as? NSArray
{
for i in 0 ..< data_list.count
{
if let nombre_esp_obj = nombre_especialidad[i] as? NSDictionary
{
if let nombre_especialidad = nombre_esp_obj["subesp"] as? String
{
if let totalRows = nombre_esp_obj["totalRows"] as? String
{
TableData.append(nombre_especialidad + " [" + totalRows + "]")
}
}
}
}
}
DispatchQueue.main.async(execute: {self.do_table_refresh()})
}
func do_table_refresh()
{
self.tableView.reloadData()
}
}
This is a rough guide, please search for the methods in the documentation or here at other questions inside stackoverflow.
1) Add a variable inside your EspMedVC that will hold the "id_categoria String" that should be displayed.
2) Add a variable inside your CatMedVC that will hold the "id_categoria String" that the user selected.
3) Implement the "didSelectRow" delegate method from your tableview inside the "CatMedVC", inside this method you should set the variable set on step 2.
4) Implement the "prepareForSegue" method inside your CatMedVC, inside the the implementation you should retrieve the destination VC, cast it to "EspMedVC" and set the variable from step 1.
5) On the "viewDidLoad" from EspMedVC you can now use the variable set on step 2 to query your JSON and update the table view accordingly.
I am trying to dynamically update a uicollectionview. I used this amazing tutorial on how to create a simple uicollection.
It works great when using a static array of items. My issue - I would like to have the uicollection populate with data I parsed into a new array from my db. I am not sure how to reload the uicollection after parsing my json data.
UPDATED CODE WITH ANSWER:
import UIKit
class Books: UIViewController, UICollectionViewDelegate {
#IBOutlet weak var bookscollection: UICollectionView!
var user_id: Int = 0;
//------------ init ---------------//
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
showtutorial()
getuserid()
}
//------------ show books ---------------//
var booknames = [String]()
var bookcolor = [String]()
var bookdescription = [String]()
var bookid = [Int]()
func posttoapi(){
//show loading
LoadingOverlay.shared.showOverlay(view: self.view)
//send
let url:URL = URL(string: "http://www.url.com")!
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let paramString = "user_id=\(user_id)"
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest) {(data, response, error) in
//hide loading
LoadingOverlay.shared.hideOverlayView()
//no response
guard let data = data, let _:URLResponse = response, error == nil else {
print("response error")
return
}
//response, parse and send to build
let json = String(data: data, encoding: String.Encoding.utf8);
if let data = json?.data(using: String.Encoding.utf8){
let json = try! JSON(data: data)
for item in json["rows"].arrayValue {
//push data to arrays
self.booknames.append(item["name"].stringValue)
self.bookcolor.append(item["color"].stringValue)
self.bookdescription.append(item["description"].stringValue)
self.bookid.append(item["id"].int!)
//reload uicollection
DispatchQueue.main.sync(execute: {
self. bookscollection.reloadData()
})
}
}
}
task.resume()
}
//------------ collection -------------//
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("collection view code called")
return self.booknames.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = bookscollection.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! BooksCell
cell.myLabel.text = self.booknames[indexPath.item]
cell.backgroundColor = UIColor.cyan // make cell more visible in our example project
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.item)!")
}
//------------ end ---------------//
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Thank you for any help!
Same problem i faced..your url having many images means reload t
dispatch_async(dispatch_get_main_queue(), {
self.collectionView.reloadData()
})