Ios 从Firebase下载表视图中的项目过多

Ios 从Firebase下载表视图中的项目过多,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,当我从不同的设备发布时,当前设备上的tableview I会保留以前存在的项目,然后再次下载这些项目,包括新发布的项目。有人能帮我这样做吗,使其仅显示每个项目中的一个 我想问题出在我从Firebase()下载的中 这是我的密码: class DisplayVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerD

当我从不同的设备发布时,当前设备上的tableview I会保留以前存在的项目,然后再次下载这些项目,包括新发布的项目。有人能帮我这样做吗,使其仅显示每个项目中的一个

我想问题出在我从Firebase()下载的

这是我的密码:

class DisplayVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

@IBOutlet weak var captionField: RoundTextField!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var myMainImg: roundImage!

var imageSelected = false
static var imageCache: NSCache<NSString,UIImage> = NSCache()
var posts = [Post]() // array for the posts
var imagePicker: UIImagePickerController!

@IBAction func addImageTapped(_ sender: Any) {
    present(imagePicker, animated: true, completion: nil)

}

@IBAction func logoutPressed(_ sender: Any) {
    //remove keychain and sign out of firebase
    let keychainResult = KeychainWrapper.standard.removeObject(forKey: KEY_UID)
    print("AA: ID removed from keychain: \(keychainResult)")
    try! FIRAuth.auth()?.signOut()
    performSegue(withIdentifier: "goToSignIn", sender: nil)

}
@IBAction func postBtnTapped(_ sender: Any) {
   //does this exist? or is it null? if condition is not true then it is executed
    guard let caption = captionField.text, caption != "" else {
        let alert = UIAlertController(title: "Bad Caption", message: "Caption must be entered", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
        self.present(alert, animated: true, completion: nil)
        return
    }
    guard let img = myMainImg.image, imageSelected == true else {
        let alert = UIAlertController(title: "Bad Image", message: "Image must be choosen", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
        self.present(alert, animated: true, completion: nil)
        return

    }
    if let imgData = UIImageJPEGRepresentation(img, 0.2){

        let imgUid = NSUUID().uuidString
        let metadata = FIRStorageMetadata()
        metadata.contentType = "image/jpeg"

        DataService.ds.REF_POST_IMAGES.child(imgUid).put(imgData, metadata: metadata, completion: { (metadata, error) in
            if error != nil{
                print("unable to upload image to Firebase storage")
            }else{
                print("GREAT SUCESS FOR IMAGE ON STORAGE")
                let downloadURL = metadata?.downloadURL()?.absoluteString
                if let url = downloadURL{
                    self.postToFireBase(imageURL: url)
                }
            }
        })
    }

}

func postToFireBase(imageURL: String){
    let post: Dictionary<String, AnyObject> = ["caption": captionField.text as AnyObject,"imageURL":imageURL as AnyObject, "likes":0 as AnyObject,"userName": userName as AnyObject]

    let firebasePost = DataService.ds.REF_POSTS.childByAutoId()
    firebasePost.setValue(post)

    captionField.text = ""
    imageSelected = false
    myMainImg.image = UIImage(named: "add-image")

    posts.removeAll()
    tableView.reloadData()
}



//cannot use the view did load for the guard method!
override func viewDidAppear(_ animated: Bool) {

}

override func viewDidLoad() {
    super.viewDidLoad()
    self.hideKeyboardWhenTappedAround()

    tableView.delegate = self
    tableView.dataSource = self

    imagePicker = UIImagePickerController()
    imagePicker.allowsEditing = true
    imagePicker.delegate = self

    posts.removeAll()
    self.downloadFromFirebase()
}

func downloadFromFirebase(){
    //"POSTS" Listener, initialize listener and it will work constantly
    DataService.ds.REF_POSTS.observe(.value, with: { (snapshot) in

        if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot]{
            for snap in snapshot{
                print("SNAP: \(snap)") // make free objects by parsing the JSON
                if let postDict = snap.value as? Dictionary<String, AnyObject>{
                    let key = snap.key
                    let post = Post(postKey: key, postData: postDict)
                    self.posts.append(post) //stick the post in the posts Array
                }

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

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return posts.count //number of total posts
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let post = posts[indexPath.row]

    if let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? PostCell{

        if let img = DisplayVC.imageCache.object(forKey: post.imageURL as NSString){
            cell.configureCell(post: post, image: img)
            return cell
        }else{
            cell.configureCell(post: post, image: nil)
            return cell
        }
    }else{
        return PostCell()
    }

}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage{
     myMainImg.image = image

    }else{
        print("AA: Valid image wasn't selected")
    }
    imagePicker.dismiss(animated: true, completion: nil)
    imageSelected = true

}

func hideKeyboardWhenTappedAround() {
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    view.addGestureRecognizer(tap)
}

func dismissKeyboard() {
    view.endEditing(true)
}
}
类显示VC:UIViewController、UITableViewDelegate、UITableViewDataSource、UIImagePickerControllerDelegate、UINavigationControllerDelegate{
@IBOutlet弱var captionField:RoundTextField!
@IBVAR表格视图:UITableView!
@ibvar myMainImg:roundImage!
var imageSelected=false
静态变量imageCache:NSCache=NSCache()
var posts=[Post]()//posts的数组
var imagePicker:UIImagePickerController!
@iAction func addImageTapped(u发送方:任何){
当前(imagePicker,动画:真,完成:无)
}
@iAction func注销已按下(\发送方:任何){
//取下钥匙链并从firebase注销
让keychainResult=KeychainWrapper.standard.removeObject(forKey:KEY\u UID)
打印(“AA:ID已从keychain中删除:\(keychainResult)”)
试试!FIRAuth.auth()?.signOut()
performsgue(标识符为“goToSignIn”,发送方:nil)
}
@iAction func PostBttaped(\发送方:任意){
//这是否存在?还是为空?如果条件不为真,则执行它
guard let caption=captionField.text,caption!=“其他{
let alert=UIAlertController(标题:“错误标题”,消息:“必须输入标题”,首选样式:。警报)
addAction(UIAlertAction(标题:“确定”,样式:。取消,处理程序:nil))
self.present(警报、动画:true、完成:nil)
返回
}
guard let img=myMainImg.image,imageSelected==true else{
let alert=UIAlertController(标题:“坏图像”,消息:“必须选择图像”,首选样式:。警报)
addAction(UIAlertAction(标题:“确定”,样式:。取消,处理程序:nil))
self.present(警报、动画:true、完成:nil)
返回
}
如果让imgData=uiImageJPEG表示(img,0.2){
让imgUid=nsuid().uuidString
let metadata=FIRStorageMetadata()
metadata.contentType=“图像/jpeg”
DataService.ds.REF\u POST\u IMAGES.child(imgUid).put(imgData,元数据:元数据,完成:{(元数据,错误)在
如果错误!=nil{
打印(“无法将图像上载到Firebase存储”)
}否则{
打印(“存储图像的巨大成功”)
让downloadURL=元数据?.downloadURL()?.absoluteString
如果let url=downloadURL{
self.postToFireBase(imageURL:url)
}
}
})
}
}
func postToFireBase(imageURL:String){
让post:Dictionary=[“caption”:captionField.text作为AnyObject,“imageURL”:imageURL作为AnyObject,“likes”:0作为AnyObject,“userName”:userName作为AnyObject]
让firebasePost=DataService.ds.REF_POSTS.childByAutoId()
firebasePost.setValue(post)
captionField.text=“”
imageSelected=false
myMainImg.image=UIImage(名为“添加图像”)
posts.removeAll()
tableView.reloadData()
}
//无法将视图加载用于guard方法!
覆盖函数视图显示(u动画:Bool){
}
重写func viewDidLoad(){
super.viewDidLoad()
self.hidekeyboardwhen-appedaround()
tableView.delegate=self
tableView.dataSource=self
imagePicker=UIImagePickerController()
imagePicker.allowsEditing=true
imagePicker.delegate=self
posts.removeAll()
self.downloadFromFirebase()下载
}
func从Firebase()下载{
//“发布”侦听器,初始化侦听器,它将持续工作
DataService.ds.REF_POSTS.observe(.value),其中:{(快照)在
如果让snapshot=snapshot.children.allObjects为?[FIRDataSnapshot]{
用于管理单元快照{
print(“SNAP:\(SNAP)”//通过解析JSON生成自由对象
如果让postDict=snap.value作为字典{
让key=snap.key
让post=post(postKey:key,postData:postDict)
self.posts.append(post)//将post粘贴到posts数组中
}
}
}
self.tableView.reloadData()
})
}
func numberOfSections(在tableView:UITableView中)->Int{
返回1
}
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
return posts.count//posts总数
}
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
让post=posts[indexPath.row]
如果let cell=tableView.dequeueReusableCell(标识符为“PostCell”)为?PostCell{
如果让img=DisplayVC.imageCache.object(forKey:post.imageURL作为NSString){
cell.configureCell(post:post,image:img)
返回单元
}否则{
cell.configureCell(post:post,image:nil)
返回单元
}
}否则{
返回邮政编码()
}
}
func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo:[字符串:任意]){
如果让image=info[UIImagePickerControllerEditedImage]作为?UIImage{
myMainImg.image=image
}否则{
打印(“AA:未选择有效图像”)
}
imagePicker.Disclose(动画:true,完成:nil)
imageSelected=true
}
func hideKeyboardWhenTappedAround(){
让我们点击:UITapGestureRecognizer=UITapGestureRecognizer(目标:自我,操作:#选择器(解除键盘))
view.AddGestureRecognitor(点击)
}
func键盘(){
view.endEditing(真)
}
}
试试这个:

包括在

let post = Post(postKey: key, postData: postDict)
以下是:

if !posts.contains(post) {
    self.post.append(post)
}

让我知道它是否有效

语法不正确,它说如果!contains(其中:(Post)throws->Bool){我必须创建一个新数组来保存每个Post的Post id,并附加