Reputation: 13
I've have been searching for this answer for days. Whenever i try to instantiate a new viewcontroller called "Govind" I get a SIGARBT error. The reason why I get a SIGARBT error is because in the view controller called I use the variables; yourVariable, ASIN, VariationImages, to find specific nodes in my database. The values for yourVariable, ASIN, and VariationImages do not change, when I set them equal to the values from firebase. The values from firebase are not nil. Here's my code
import UIKit
import Firebase
import FirebaseDatabase
var yourVariable = ""
var ProductsNumber = 100
var ASIN = ""
var Weblink = ""
var VariationImages = 5
class Initial: UIViewController, UICollectionViewDataSource,
UICollectionViewDelegate {
@IBOutlet weak var FrontPageCollectionView: UICollectionView!
var UIFrame = UIScreen.main.bounds
var ref: DatabaseReference!
var DatabaseHandle = nil as DatabaseHandle!
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).observe(.value, with: { (TheCategory) in
yourVariable = TheCategory.childSnapshot(forPath: "Category").value as! String
ASIN = TheCategory.childSnapshot(forPath: "ASIN").value as! String
self.DatabaseHandle = self.ref.child(TheCategory.childSnapshot(forPath: "Category").value as! String).child(TheCategory.childSnapshot(forPath: "ASIN").value as! String).child("VariationImages").observe(.value, with: { (NumberOfVariationImages) in
VariationImages = Int(NumberOfVariationImages.childrenCount)
})
})
CallGovind()
}
func CallGovind() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "Govind")
controller.modalPresentationStyle = .popover
self.present(controller, animated: true, completion: nil)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FrontpageCell", for: indexPath) as! myCell
self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).child("Thumbnail").observe(.value, with: { (snapshot) in
cell.FrontpageImages.sd_setImage(with: URL(string: snapshot.value as! String), placeholderImage: #imageLiteral(resourceName: "Menu"), options: [.continueInBackground, .progressiveDownload])
})
cell.FrontpageImages.contentMode = .scaleAspectFill
cell.FrontpageImages.layer.cornerRadius = 5
cell.FrontpageImages.clipsToBounds = true
return cell
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
//Here's where the data goes into the second view controller
import UIKit
import Firebase
import FirebaseDatabase
class Testing: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var ref: DatabaseReference!
var DatabaseHandle = nil as DatabaseHandle!
override func viewDidLoad() {
super.viewDidLoad()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//Populate view
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cells", for: indexPath) as! myCell
self.DatabaseHandle = ref.child(yourVariable).child(ASIN).child("VariationImages").child(String(indexPath.row)).observe(.value, with: { (snapshot) in
cell.myImageViews.sd_setImage(with: URL(string: snapshot.value as! String), placeholderImage: #imageLiteral(resourceName: "Menu"), options: [.continueInBackground, .progressiveDownload])
})
return cell
}
Everywhere where the DataBaseHandle is, produces an error because it is an empty string because the variables have not updated
Upvotes: 0
Views: 2329
Reputation: 4470
AS ryantxr stated callGovind inside the closure and also good way to share variable among all the classes is singleTon.
As per my knowledge you have to create SingleTon class to manage this type variable like create seperate singleton file
import Foundation
/**
* Created by Jaydeep on 13-Feb-17.
*/
public class Singleton
{
var yourVariable : String = ""
static let shared = Singleton()
private init()
{
}
}
Usage
Singleton.shared.yourVariable = "xyz"
You can access singleTon class object anywhere and always you get last updated value.
Upvotes: 2
Reputation: 4219
Most likely your invocation of function CallGovind()
is getting executed before the completion handlers are done. This means your other view controller is called before the variables are set.
... .observe(.value, with: { (TheCategory) in
// Code in here will get executed asynchronously
// and likely will get called later
// Since you set variables in here, and they
// are not set by the time you call the other
// view controller.
}
CallGovind() // gets called BEFORE above code
One possible solution is to make sure that the other view controller is called after the completion blocks are done.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).observe(.value, with: { (TheCategory) in
yourVariable = TheCategory.childSnapshot(forPath: "Category").value as! String
ASIN = TheCategory.childSnapshot(forPath: "ASIN").value as! String
self.DatabaseHandle = self.ref.child(TheCategory.childSnapshot(forPath: "Category").value as! String).child(TheCategory.childSnapshot(forPath: "ASIN").value as! String).child("VariationImages").observe(.value, with: { (NumberOfVariationImages) in
VariationImages = Int(NumberOfVariationImages.childrenCount)
// Call other controller here so that the variables
// are set
DispatchQueue.main.async {
CallGovind()
}
})
})
}
Upvotes: 1