2016-10-21 3 views
0

Ich versuche immer noch, meine Firebasics mit Firebase in Swift zu lernen. Ich habe Probleme, ein Array mit Firebase zu füllen. Das Array wird verwendet, um eine CollectionView zu füllen. Mein Code jetzt ist:Füllen eines Arrays mit Firebase

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.collectionView!.register(locationCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) 

    let nib: UINib = UINib(nibName: "locationCollectionViewCell", bundle: nil) 
    self.collectionView!.register(nib, forCellWithReuseIdentifier: reuseIdentifier) 


    let flowLayout = UICollectionViewFlowLayout() 
    flowLayout.itemSize = CGSize(width: 200, height: 200) 
    flowLayout.scrollDirection = .horizontal 
    self.collectionView?.collectionViewLayout = flowLayout 

    myFirebaseFunc() 

} 

func myFirebaseFunc() { 
    let locationRef = FIRDatabase.database().reference().queryOrdered(byChild: "Location") 
    locationRef.observeSingleEvent(of: .value, with: { (snapshot) in 
     if snapshot.exists() { 
      var sorted = ((snapshot.value! as AnyObject).allValues as NSArray).value(forKey: "name") as! NSArray 
      sorted = sorted[0] as! NSArray 
      for element in sorted { 
       let m = MyStruct(name: element as! String) 
       self.myArray.append(m) 
      } 
      print(self.myArray) //array is correctly populated 
      DispatchQueue.main.async{ 
       self.collectionView?.reloadData() 
      } 
     } 
    }) 
    print(self.myArray) //array is suddenly empty 

} 

JSON Daten:

{ 
    "Location" : [ { 
    "address" : "602 Pacific Coast Hwy, Huntington Beach, CA 92648", 
    "hours" : "Sun 8am-8pm, Mon - Sat 8am-9pm", 
    "name" : "Huntington Beach", 
    "phoneNumber" : "(714) 536-TACO(8226)" 
    }, { 
    "address" : "3014 W Balboa Blvd, Newport Beach, CA 92663", 
    "hours" : "Sun 8am-8pm, Mon - Sat 8am-9pm", 
    "name" : "Newport Beach", 
    "phoneNumber" : "(949) 723-TACO(8226)" 
    } ] 
} 

Nach den Debugger verwenden, scheint es, dass mein Haupt ist, dass das Innere des observeSingleEvent nie aufgerufen wird, und auf diese Weise das Array ist nicht bevölkert sein. Jede Hilfe wird geschätzt!

Edit: So wird jetzt objectSingleEvent aufgerufen, und myArray wird korrekt gefüllt, aber wenn myArray irgendwo außerhalb von observeSingleEvent aufgerufen wird, sagt das Array, dass es leer ist, obwohl es in observeSingleEvent korrekt ausgefüllt ist.

+0

Eine schnelle erste Vermutung ist, dass Ihr Code wahrscheinlich keine Berechtigung zum Lesen der Daten hat. Lesen Sie hier mehr darüber, wie Sie das erkennen können: http://stackoverflow.com/documentation/firebase/5548/how-do-i-listen-for-errors-when-accessing-the-database/24788/detect-errors-when -reading-data-on-ios # t = 201610211354116706566 –

+0

Wird 'snapshot.value' gedruckt, um einen Wert zu erhalten, oder ist es null? –

+0

Frank Ich habe die Erlaubnis, die Daten zu lesen, ich habe nur die Firebase-Regeln auf immer wahr gesetzt. @Zaid, druckt snapshot.value druckt die JSON-Datenbank, sortiert sortiert nur die Namen und druckt myarray in observeSingleEvent druckt das korrekte MyStruct-Array; Das Drucken von myarray an anderer Stelle führt jedoch zu einem leeren Array. –

Antwort

0

Dies ist nicht der richtige Weg, die Sie suchen,

observeSingleEvent ist Asynchron-Methode, so dass Sie nicht Ausgabe erhalten wird, bis er von Firebase-Server ausgeführt und abgerufenen Daten erhalten.

So ist der beste Weg, um diese Aufgabe async geben zwei Möglichkeiten, zu handhaben,
1.) Entweder diese Daten laden, wenn app Start von AppDelegate und verwenden Sie hier in Ihrem Viewcontroller,
2.) oder zeigt Lade Indikator, bis Daten vom Server abgerufen und von innen observeSingleEvent gehandhabt werden.

+0

Selbst wenn Sie es in AppDelegate einfügen, kann es die Daten im Array nicht speichern, auch wenn es nur gut geladen wird. Ein Ladeindikator ist interessant, aber ich denke nicht, dass es helfen wird, wenn ich die Daten in einer Liste an erster Stelle nicht –

+0

bekommen kann. –

+0

@MichaelEliot, Ja AppDelegate muss noch geladen werden, daher müssen Sie die Ladeanzeige verwenden. –

Verwandte Themen