Mavjud bo'lsa, maxsus jadval ko'rish qatoriga element qo'shing

Men Parse ma'lumotlar bazasidan bir sinfda (maktabda) foydalanuvchilar jadvalini yaratishga harakat qilaman. Barcha foydalanuvchilar foydalanuvchi nomiga ega bo'lishi kerak, lekin hamma ham ilovaga o'zining to'liq ismini bermagan yoki profil rasmini o'rnatmagan. Men ushbu kodni ishlataman:

let studentsQuery = PFQuery(className:"_User")
studentsQuery.whereKey("objectId", containedIn: studentsArray! as! [AnyObject])

let query2 = PFQuery.orQueryWithSubqueries([studentsQuery])

query2.findObjectsInBackgroundWithBlock {
    (results: [PFObject]?, error: NSError?) -> Void in

    if error != nil {

        // Display error in tableview

    } else if results! == [] {

        spinningActivity.hideAnimated(true)

        print("error")

    } else if results! != [] {

        if let objects = results {

            for object in objects {

                if object.objectForKey("full_name") != nil {

                    let studentName = object.objectForKey("full_name")!  as! String

                    self.studentNameResults.append(studentName)


                }

                if object.objectForKey("username") != nil {

                    let studentUsername = object.objectForKey("username")!  as! String

                    self.studentUsernameResults.append(studentUsername)

                }

                if object.objectForKey("profile_picture") != nil {

                    let studentProfilePictureFile = object.objectForKey("profile_picture") as! PFFile

                    studentProfilePictureFile.getDataInBackgroundWithBlock({ (image: NSData?, error: NSError?) in

                        if error == nil {

                            let studentProfilePicture : UIImage = UIImage(data: image!)!
                            self.studentProfilePictureResults.append(studentProfilePicture)

                        } else {

                            print("Can't get profile picture")

                            // Can't get profile picture

                        }

                        self.studentsTableView.reloadData()

                    })

                    spinningActivity.hideAnimated(true)

                } else {

                    // no image

                }

            }
        }
} else {

    spinningActivity.hideAnimated(true)

    print("error")

}
}

Agar barcha foydalanuvchilarda foydalanuvchi nomi, to'liq_ism va profil_rasmi bo'lsa, bu kod yaxshi ishlaydi. Biroq, foydalanuvchining foydalanuvchi nomlaridan tableView ni olish va foydalanuvchining tegishli tableViewCell raqamiga foydalanuvchining ismi yoki rasmini faqat foydalanuvchining rasmi bo'lsa, qanday qo'shishni tushunolmayapman. Mening tableView qurilmam qanday sozlangan:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return studentUsernameResults.count

}


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("studentsCell", forIndexPath: indexPath) as! StudentsInClassInformationTableViewCell

        cell.studentProfilePictureImageView.layer.cornerRadius = cell.studentProfilePictureImageView.frame.size.width / 2
        cell.studentProfilePictureImageView.clipsToBounds = true

        cell.studentProfilePictureImageView.image = studentProfilePictureResults[indexPath.row]

        cell.studentUsernameLabel.text = studentUsernameResults[indexPath.row]

        cell.studentNameLabel.text = studentNameResults[indexPath.row]


        return cell

}

studentProfilePictureResults, studentUsernameResults va studentNameResults foydalanuvchi rasmi, foydalanuvchi nomi va Parsedan olingan ism natijalari massivlaridan keladi. Agar foydalanuvchida profil rasmi bo'lmasa, men Index is out of range xatosini olaman. Shubhasiz, bu, aytaylik, uchta nom, uchta foydalanuvchi nomi va faqat ikkita rasm borligini anglatadi va Xcode hujayrani qanday sozlashni bilmaydi. Savolim: Qanday qilib foydalanuvchining foydalanuvchi nomidan tableView-ni oʻrnatishim va uning ismi va profil rasmini faqat bitta katakchaga joylashtirishim mumkin, faqat ularda mavjud boʻlsa?


person Dan Levy    schedule 23.04.2016    source manba
comment
Alohida massivlarni saqlamang. PFObjects ning bitta massivini saqlang va men sizga fotosuratlar uchun [username(string):UIImage) lug'atidan foydalanishni tavsiya qilaman.   -  person Paulw11    schedule 24.04.2016
comment
@Paulw11 Foydalanuvchining foydalanuvchi nomi, ismi va rasmini so'raganimda, siz aytayotgandek barcha natijalarni birdaniga olaman (natijalarni bitta massivda saqlash). Qanday qilib foydalanuvchi nomi, ism va rasmni birga saqlashim mumkin? Men lug'atlar bilan ko'p o'ynamadim, lekin ular faqat ikkita (2) natijani saqlashi mumkin deb o'yladim. Uchalasini (3) qanday saqlashim mumkin?   -  person Dan Levy    schedule 24.04.2016


Javoblar (1)


Turli xil atributlarni turli massivlarda saqlashga urinish muammo bo'ladi, chunki siz aniqlaganingizdek, ma'lum bir foydalanuvchining atributiga ega bo'lmagan muammolarga duch kelasiz. Yo'q atribut uchun nil ni saqlashingiz uchun ixtiyoriy qatorlardan foydalanishingiz mumkin, ammo PFObject ning o'zini bitta massivda saqlash va atributlarni bo'lishdan ko'ra cellForRowAtIndexPath atributlariga kirish ancha oson.

Suratni olish alohida, asinxron operatsiyani talab qilganligi sababli, uni alohida saqlashingiz mumkin. Qabul qilingan fotosuratlarni saqlash uchun massivdan foydalanish o'rniga, buyurtma berishda bir xil muammo bo'ladi, siz foydalanuvchi identifikatori bilan indekslangan lug'atdan foydalanishingiz mumkin; ko'p sonli talabalar uchun cellForRowAtIndexPath da talab qilinganidek, fotosuratlarni yuklab olish uchun SDWebImage kabi biror narsadan foydalanish samaraliroq bo'lar edi.

// these are instance properties defined at the top of your class
var students: [PFObject]?
var studentPhotos=[String:UIImage]()

// This is in your fetch function
let studentsQuery = PFUser.Query()
    studentsQuery.whereKey("objectId", containedIn: studentsArray! as! [AnyObject])

let query2 = PFQuery.orQueryWithSubqueries([studentsQuery])

query2.findObjectsInBackgroundWithBlock {
    (results: [PFObject]?, error: NSError?) -> Void in
    guard (error == nil) else {
        print(error)
        spinningActivity.hideAnimated(true)
        return
    }

    if let results = results {
        self.students = results
            for object in results {
                if let studentProfilePictureFile = object.objectForKey("profile_picture") as? PFFile {
                    studentProfilePictureFile.getDataInBackgroundWithBlock({ (image: NSData?, error: NSError?) in
                    guard (error != nil) else {
                        print("Can't get profile picture: \(error)")
                        return
                    }

                if let studentProfilePicture = UIImage(data: image!) {
                    self.studentPhotos[object["username"]!]=studentProfilePicture
                }
            }
     }
     spinningActivity.hideAnimated(true)
     self.tableview.reloadData()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if self.students != nil {
        return self.students!.count
    }
    return 0 
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("studentsCell", forIndexPath: indexPath) as! StudentsInClassInformationTableViewCell

    cell.studentProfilePictureImageView.layer.cornerRadius = cell.studentProfilePictureImageView.frame.size.width / 2
    cell.studentProfilePictureImageView.clipsToBounds = true

    let student = self.students[indexPath.row]

    if let studentPhoto = self.studentPhotos[student["username"]!] {
        cell.studentProfilePictureImageView.image = studentProfilePictureResults[indexPath.row] 
    } else {
        cell.studentProfilePictureImageView.image = nil
    }

    cell.studentUsernameLabel.text = student["username"]!

    if let fullName = student["full_name"] {
        cell.studentNameLabel.text = fullName
    } else {
        cell.studentNameLabel.text = ""
    return cell
}

Bir nechta boshqa ko'rsatmalar;

  • Maydon nomlarida so'zlarni ajratish uchun _ dan foydalanish iOS dunyosida umuman ishlatilmaydi; camelCase afzal, shuning uchun full_name o'rniga fullName
  • Agar sizda class maydoni yoki mos yozuvlar ob'ekti bo'lsa, boshqa sinf a'zolari qatorini ta'minlashga hojat qolmagan bo'lsa, Parse so'rovingiz samaraliroq bo'lishi mumkin.
person Paulw11    schedule 24.04.2016
comment
Siz qutqaruvchisiz, Pol! Men bir oz nosozliklarni tuzatishim kerak edi va javobingizni bir necha kun ichida men duch kelgan bir nechta muammolarga asoslanib tahrir qilaman, lekin umuman buni qilishning toza va oddiy usuli! Yana bir bor rahmat! - person Dan Levy; 27.04.2016