I'm trying to develop an IOS application using Swift. The application is a simple app which retrieves data from database and display.
The problem is I cannot manage to display data which is retrieved from database via REST server... I've asked similar question here.
As I stated there, I tried DispatchQueue.main.async
to execute fetching and reloadData(). but it failed.
When I replace async to sync, it works partially (first screen loading time, it doesn't display but after then it display items).
Can you guys help me get through this?
The followings are my class code
import UIKit
class OrderViewController:UIViewController {
let cartView:UIView = {
let tableView = UIView()
tableView.backgroundColor = UIColor.gray
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
var itemView:UIView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
edgesForExtendedLayout = []
view.backgroundColor = UIColor.white
itemView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(itemView)
view.addSubview(cartView)
setupItemView()
setupCartView()
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 20, bottom: 10, right: 20)
//let viewFrame = CGRect(x: view.bounds.minX, y: view.bounds.minY, width: view.bounds.width*2/3, height: view.bounds.height)
let collectionViewController = ItemcollectionViewController(collectionViewLayout: layout)
// get rid of black bar underneath navBar
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
itemView.addSubview(collectionViewController.view)
}
private func setupItemView(){
itemView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
itemView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
itemView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 2/3).isActive = true
itemView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
private func setupCartView() {
cartView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
cartView.leftAnchor.constraint(equalTo: itemView.rightAnchor).isActive = true
cartView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/3).isActive = true
cartView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
}
Class where is fetching data:
import UIKit
import Alamofire
import SwiftyJSON
class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout {
let dateFormat = "yyyy-MM-dd"
let cellId = "CellId"
//var categories: [Category]?
var categories = [Category]()
let viewOptionVar:ViewOptionBar = {
let vOV = ViewOptionBar()
vOV.translatesAutoresizingMaskIntoConstraints = false
return vOV
}()
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.contentInset = UIEdgeInsetsMake(50, 0, self.view.frame.height, self.view.frame.width)
collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, self.view.frame.width)
collectionView?.dataSource = self
collectionView?.delegate = self
DispatchQueue.global().async {
Alamofire.request("http://localhost:8080/category/all").responseJSON { (responseData) -> Void in
switch responseData.result{
case .success:
if let returnedCategories = responseData.result.value as! NSArray? {
for element in returnedCategories {
let categoryDictionary = element as! NSDictionary
let category = Category()
category.categoryId = categoryDictionary["categoryId"] as? String
category.categoryName = categoryDictionary["categoryName"] as? String
category.categoryDescription = categoryDictionary["categoryDescription"] as? String
let categoryRegisteredDateString = categoryDictionary["categoryRegisteredDate"] as? String
let df = DateFormatter()
df.dateFormat = self.dateFormat
let categoryRegisteredDate = df.date(from: categoryRegisteredDateString!)!
category.categoryRegisteredDate = categoryRegisteredDate
self.categories.append(category)
}
print("After parsing \(self.categories)")
}
case .failure(let error):
print("Error while fetching Categories: \(error)")
}
}
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
}
print(self.categories)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.categories.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ItemCell
cell.category = categories[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 111, height: 111)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
private func setupViweOptionBar() {
view.addSubview(viewOptionVar)
view.addConstraintsWithFormat(format: "H:|[v0]|", views: viewOptionVar)
view.addConstraintsWithFormat(format: "V:|[v0(50)]", views: viewOptionVar)
}
}