UIImagePickerController 导致重复

UIImagePickerController causes duplicate

我正在使用 Swift 实现社交媒体应用程序。在 MyProfileViewController 中,我使用了 UIImagePickerController 来更改当前用户的个人资料图片。但是,使用 UIImagePickerController 会导致 table 视图行重复,即使我在 viewDidLoad 中处理 table 视图,而不是在 viewWillAppear 中。

为了说明,这是我的 viewDidLoad 函数。

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

    self.automaticallyAdjustsScrollViewInsets = false

    ref = Database.database().reference()
    storageRef = Storage.storage().reference()

    ref.child("users").child((Auth.auth().currentUser?.uid)!).observe(.value, with: {
        (snapshot) in
        let value = snapshot.value as? NSDictionary
        let userId = value?["id"] as! String
        let username = value?["username"] as! String
        let email = value?["userEmail"] as! String
        let profilePictureUrl = value?["profilePicture"] as! String

        self.currentUser = User(id: userId, username: username, email: email, profilePicture: profilePictureUrl)

        self.tableView.reloadData()
    })

    ref.child("posts").observe(.childAdded, with: {
        (snapshot) in
        let value = snapshot.value as? NSDictionary
        let id = value?["id"] as! String
        let tags = value?["tags"] as! String
        let facultyName = value?["faculty"] as! String
        let courseName = value?["course"] as! String
        let questionTitle = value?["title"] as! String
        let questionText = value?["description"] as! String
        let dateAndTime = value?["dateAndTime"] as! String
        let userID = value?["user-id"] as! String

        self.ref.child("users").child(userID).observe(.value, with: {
            (snapshot) in
            let value = snapshot.value as? NSDictionary
            let userId = value?["id"] as! String
            let username = value?["username"] as! String
            let email = value?["userEmail"] as! String
            let profilePictureUrl = value?["profilePicture"] as! String

            let post = Post(id: id, tags: tags, facultyName: facultyName, courseName: courseName, questionTitle: questionTitle, questionText: questionText, dateAndTime : dateAndTime, username: username)

            if userID == Auth.auth().currentUser?.uid {
                self.posts.insert(post, at: 0)
            }

            self.postDictionary[id] = post

            let member = User(id: userId, username: username, email: email, profilePicture: profilePictureUrl)

            if post.username == member.username {
                self.userDictionary[id] = member
            }

            self.tableView.reloadData()
        })
    })    
}

这是我的 UIImagePickerController 函数:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    let indexPath = NSIndexPath(row: 0, section: 0)
    let cell = tableView.cellForRow(at: indexPath as IndexPath) as! MyProfileInfoCell!

    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        selectedImage = image
        cell?.profilePicture.contentMode = .scaleAspectFit
        cell?.profilePicture.image = image
    }

    var data = NSData()
    data = UIImageJPEGRepresentation((cell?.profilePicture.image!)!, 0.8)! as NSData

    let filePath = "\((Auth.auth().currentUser?.uid)!)" // path where you wanted to store img in storage
    let metaData = StorageMetadata()
    metaData.contentType = "image/jpg"

    self.storageRef = Storage.storage().reference()
    self.storageRef.child(filePath).putData(data as Data, metadata: metaData) {
        (metaData,error) in
        if let error = error {
            print(error.localizedDescription)
            return
        } else{
            let downloadURL = metaData!.downloadURL()!.absoluteString

            self.ref.child("users").child((Auth.auth().currentUser?.uid)!).updateChildValues(["profilePicture" : downloadURL])
        }
    }

    self.dismiss(animated: true, completion: nil)

    print(self.posts.count)
}

我的 table 视图由 2 个原型单元格组成。第一个原型单元格用于个人资料信息,其中处理更改个人资料图片。第二个原型单元格用于显示该用户发布的帖子。问题出现在这里。当我更改个人资料图片时,帖子行被复制。

谁能帮我解决这个问题?

observe 方法将观察者添加到您数据库上的 "users"。每次更改 DB 上的 "users" 时,都会执行以下代码并将 post 添加到表视图:

self.ref.child("users").child(userID).observe(.value, with: {
        (snapshot) in
        let value = snapshot.value as? NSDictionary
        let userId = value?["id"] as! String
        let username = value?["username"] as! String
        let email = value?["userEmail"] as! String
        let profilePictureUrl = value?["profilePicture"] as! String

        let post = Post(id: id, tags: tags, facultyName: facultyName, courseName: courseName, questionTitle: questionTitle, questionText: questionText, dateAndTime : dateAndTime, username: username)

        if userID == Auth.auth().currentUser?.uid {
            self.posts.insert(post, at: 0)
        }

        self.postDictionary[id] = post

        let member = User(id: userId, username: username, email: email, profilePicture: profilePictureUrl)

        if post.username == member.username {
            self.userDictionary[id] = member
        }

        self.tableView.reloadData()
    })

当您更新个人资料图片时,数据库也会更新并执行上述代码。这就是 post 重复的原因。要解决此问题,请将方法从 observe 更改为 observeSingleEvent。 observeSingleEvent方法向DB请求一次数据。

self.ref.child("users").child(userID).observeSingleEvent(.value, with: {
        (snapshot) in
        let value = snapshot.value as? NSDictionary
        let userId = value?["id"] as! String
        let username = value?["username"] as! String
        let email = value?["userEmail"] as! String
        let profilePictureUrl = value?["profilePicture"] as! String

        let post = Post(id: id, tags: tags, facultyName: facultyName, courseName: courseName, questionTitle: questionTitle, questionText: questionText, dateAndTime : dateAndTime, username: username)

        if userID == Auth.auth().currentUser?.uid {
            self.posts.insert(post, at: 0)
        }

        self.postDictionary[id] = post

        let member = User(id: userId, username: username, email: email, profilePicture: profilePictureUrl)

        if post.username == member.username {
            self.userDictionary[id] = member
        }

        self.tableView.reloadData()
    })