Firebase — массив NSObjects, не возвращающий нормальное значение счетчика

#ios #swift #for-loop #firebase #firebase-realtime-database

#iOS #swift #для цикла #firebase #firebase-база данных в реальном времени

Вопрос:

Я пытаюсь запросить пользователей в конкретной компании, затем добавляю его в массив NSObjects.

Код:

 var userDetails = [UserDetails]()
func getDriversInfoWithCompany() {

      FIRDatabase.database().reference().child(“users").queryOrderedByChild("company").queryEqualToValue(“KFC").observeEventType(.ChildAdded, withBlock: { (snapshot) in

        let details = UserDetails(key: snapshot.key, snapshot: snapshot.value  as! Dictionary<String, AnyObject>)

        self.userDetails.append(details)

    self.loadStaffs()                

     }, withCancelBlock: nil)

}

func loadStaffs() {

    let count = self.userDetails.count

    print(count)

    for i in 0...count {

        print(self.userDetails[i].username)

    } 

}
  

И я использую цикл for, чтобы получить его имена пользователей. Но у меня возникает ошибка fatal error: Index out of range , тогда я print() count и вывод
1
2
3
4
вместо просто 4 . Я думаю, как я могу получить конечное значение 4 , чтобы, если я его зациклю, оно не выдаст мне ошибку. Спасибо!

Редактировать:

 Code:
    Snap (NU4chDtG7eWKXgPaTuFFDfWXWcf2) {
    company = "KFC";
    email = "user@email.com";
    fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/NU4chDtG7eWKXgPaTuFFDfWXWcf2/492003486?alt=mediaamp;token=34cecf1e-d65f-4856-8aac-3afdcf9d451e";
    userRole = DISPATCH;
    username = UserName;
    }
    Snap (blkSE7N8GEPeoObNCWLhjyUnkSu2) {
    company = "KFC";
    email = "user@email.com";
    fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/blkSE7N8GEPeoObNCWLhjyUnkSu2?alt=mediaamp;token=b97fd727-12f8-4725-a830-67133de78aab";
    userRole = SHIPPER;
    username = UserName;
    }
    Snap (d605A6Mc0hRWygvK9fjwUnPfliU2) {
    company = "KFC";
    email = "user@email.com";
    fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/d605A6Mc0hRWygvK9fjwUnPfliU2?alt=mediaamp;token=f35347ca-8da5-402d-a6b6-c3a56f59cbcf";
    userRole = DRIVER;
    username = UserName;
    }
    Snap (fGfIKyF8g5WAOLBdc5dpNSWmaGy2) {
    company = "KFC";
    email = "user@email.com";
    fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/fGfIKyF8g5WAOLBdc5dpNSWmaGy2?alt=mediaamp;token=79735c4e-aa70-4cb0-8a16-b6efedb668a2";
    userRole = DISPATCHER;
    username = "UserName";
    }
  

Код:

 Snap (users) {

NU4chDtG7eWKXgPaTuFFDfWXWcf2 =     {

company = "KFC";

email = "user@email.com";

fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/NU4chDtG7eWKXgPaTuFFDfWXWcf2/492003486?alt=mediaamp;token=34cecf1e-d65f-4856-8aac-3afdcf9d451e";

userRole = DISPATCH;

username = UserName;

};

blkSE7N8GEPeoObNCWLhjyUnkSu2 =     {

company = "KFC";

email = "user@email.com";

fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/blkSE7N8GEPeoObNCWLhjyUnkSu2?alt=mediaamp;token=b97fd727-12f8-4725-a830-67133de78aab";

userRole = SHIPPER;

username = UserName;

};

d605A6Mc0hRWygvK9fjwUnPfliU2 =     {

company = "KFC";

email = "user@email.com";

fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/d605A6Mc0hRWygvK9fjwUnPfliU2?alt=mediaamp;token=f35347ca-8da5-402d-a6b6-c3a56f59cbcf";

userRole = DRIVER;

username = UserName;

};

fGfIKyF8g5WAOLBdc5dpNSWmaGy2 =     {

company = "KFC";

email = "user@email.com";

fileUrl = "https://firebasestorage.googleapis.com/v0/b/myapp-234esg.appspot.com/o/profileImage/fGfIKyF8g5WAOLBdc5dpNSWmaGy2?alt=mediaamp;token=79735c4e-aa70-4cb0-8a16-b6efedb668a2";

userRole = DISPATCHER;

username = "UserName";

};

}
  

Первый из них.Дочернее значение, а второе значение .Value . Спасибо!

Ответ №1:

Попробуйте изменить свою loadStaff() функцию на :-

 func loadStaffs() {

        let count = self.userDetails.count
        print(count)

            for i in 0...count-1 {

             print(self.userDetails[i].username)

             } 
         }
  

Для извлечения используйте :-

 func getDriversInfoWithCompany() {

  FIRDatabase.database().reference().child(“users").queryOrderedByChild("company").queryEqualToValue(“KFC").observeEventType(.Value, withBlock: { (snapshot) in
    if let snapDict = snapshot.value as? [String:AnyObject]{ 

      for each in snapDict as [String:AnyObject]{

      let details = UserDetails(key: each.0, snapshot: each.1  as! Dictionary<String, AnyObject>)

     self.userDetails.append(details)

     self.loadStaffs()                

   } 
  }
 }, withCancelBlock: nil)

}
  

Комментарии:

1. Можете ли вы уточнить, но все же счетчик повторяется . Я не могу вас понять? Вы спрашиваете, почему loadStaff() вызывается каждый раз, и вы хотите, чтобы он вызывался, когда все значения были добавлены?

2. Потому что это будет до тех пор, пока вы используете childAdded eventCall. Он запускает completionBlock каждый раз после извлечения одного узла. Измените childAdded на .Value , а затем выполните цикл по извлеченному снимку, чтобы запустить вашу loadStaff() функцию только один раз 🙂

3. Я изменил его на .Value, и теперь он ничего не возвращает. Как вы думаете, в чем проблема? Должен ли я изменить свой запрос?

4. Вы пробовали распечатать снимок? это ноль? Кроме того, поскольку теперь вы извлекаете весь JSON с .Value помощью EventType, вам нужно перебирать каждое значение ключа.

5. снимок не равен нулю, но ключ изменен на users вместо uid пользователя. Как я могу заставить это работать?