Ios 就像使用firebase崩溃的反馈一样。快速单击类删除类

Ios 就像使用firebase崩溃的反馈一样。快速单击类删除类,ios,swift,firebase,firebase-realtime-database,user-experience,Ios,Swift,Firebase,Firebase Realtime Database,User Experience,我有一个类似instagram的应用程序。它有一个反馈页面 当用户喜欢某篇文章时,我会为这篇文章添加类似内容和反馈(使用自己的键(.childByAutoId) static func add(_ newLike: LikeItem) { // add like id for user feedback implementation var like = newLike let likeRef = ref.child("/userslikes/" + newLike.userId +

我有一个类似instagram的应用程序。它有一个反馈页面

当用户喜欢某篇文章时,我会为这篇文章添加类似内容和反馈(使用自己的键(
.childByAutoId

static func add(_ newLike: LikeItem) {
  // add like id for user feedback implementation
  var like = newLike
  let likeRef = ref.child("/userslikes/" + newLike.userId + "/onposts/" + newLike.postId).childByAutoId()
  like.key = likeRef.key

  var updates: [String: Any?] = [
     "/userslikes/" + like.userId + "/onposts/" + like.postId: like.toAnyObject(),
     "/postslikes/" + like.postId + "/"         + like.userId: like.toAnyObject()
  ]

  if like.userId != like.postAddedByUserId { // dont add your own likes
     var likeForFeedBack = like.toAnyObject()
     likeForFeedBack["isViewed"] = false // when user will open feedback -> true
     updates.updateValue(likeForFeedBack, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
  }

  ref.updateChildValues(updates)
}
没关系。我还有
remove
函数。它将喜欢节点,从这个喜欢中获得这个喜欢和
feedbackId
。然后我进行多部分更新

static func remove(with userId: String, _ post: PostItem) {
  var updates: [String: Any?] = [
     "/userslikes/" + userId   + "/onposts/" + post.key: nil,
     "/postslikes/" + post.key + "/"         + userId:   nil
  ]

  // deleting from feedback node
  getLikeFromUser(id: userId, postId: post.key) { like in
     if like.userId != like.postAddedByUserId {
        updates.updateValue(nil, forKey: "/feedback/" + like.postAddedByUserId + "/" + like.key)
     }

     ref.updateChildValues(updates)
  }
}

static func getLikeFromUser(id: String, postId: String,
                           completion: @escaping (_ likeId: LikeItem) -> Void) {
  let refToLike = ref.child("/userslikes/" + id + "/onposts/" + postId)

  refToLike.observeSingleEvent(of: .value, with: { snapshot in
     let like = LikeItem(snapshot: snapshot)

     completion(like)
  })
}
所以,当用户点击“remove like”时,我会有一些延迟(此时获取反馈id是获取like实体)

还有问题:如果我像removeLike按钮(像-remove like-l-rl-l-rl等)一样滥发
,有时我的反馈节点会重复(使用不同的键C。它没有删除旧节点),有时它不会添加(在这种情况下,如果我以后尝试删除它,它会崩溃)


如何修复它?

我的拙见,首先,这可以通过UX限制来修复。用户不应该在应用程序中发送任何按钮。这必须是两个事件之间的延迟。即使您可以添加一些最大值。在用户决策之间切换…请稍等片刻,然后再次免费(可能)

正如您在评论中所说,这是一个非常好的主意,好的用户体验将等待用户完成编写操作。这样您就可以消除不好的用户体验

您可以使用UIView的属性

设置为“否”时,触摸、按、键盘和对焦事件 用于视图的对象将被忽略并从事件队列中删除。 设置为“是”时,事件将正常传递到视图 此属性的默认值为“是”

在动画期间,用户 对于中涉及的所有视图,将暂时禁用交互 动画,无论此属性中的值如何。您可以禁用 通过指定 UIViewAnimationOptionAllowUserInteraction选项在配置 动画

当然有很多选择,天空是UX场景的极限

此外,您还可以查看Apple的用户界面加载指南:

尽快显示内容。不要让人们等待内容 在看到他们期望的屏幕之前加载。显示屏幕 立即,并使用占位符文本、图形或动画 确定内容尚不可用的位置。替换这些占位符 元素作为内容加载。尽可能预加载 背景中的内容,例如播放动画时或 用户正在浏览关卡或菜单

指标可能是:

如果有用,在等待任务时提供有用的信息 完成。在活动指示器上方添加标签,以提供额外的 避免使用诸如加载或验证之类的模糊术语,因为它们 通常不要增加任何价值

另一种选择 正如您在下面的评论中所说,在用户使用ViewController之前,还有另一个选项可以保持“喜欢/不喜欢”。但还有另一个UX问题,即当用户尝试关闭模式或返回到上一个视图控制器时,他们将等待此后台作业完成。另一个问题是,如果用户杀死应用程序,您还有一个更改需要保存ta及其AppDelegate的应用程序将终止。但在此处保存数据是不好的做法,因为有5秒的限制:

此方法可让你的应用程序知道它即将被终止,并且 完全从内存中清除。应使用此方法执行任何 应用程序的最终清理任务,如释放共享资源, 保存用户数据,并使计时器无效。您的实现 方法大约有五秒钟来执行任何任务并返回

如果该方法在时间到期前未返回,系统可能会终止 整个过程。对于不支持后台的应用程序 执行或链接到iOS 3.x或更早版本,此方法是 用户退出应用时始终调用。对于支持 在后台执行时,当 用户退出该应用程序,因为该应用程序只是在 但是,在 应用程序正在后台运行(未挂起),系统需要 由于某种原因终止它。调用此方法后,应用程序 还发布UIApplicationWillTerminate通知,以提供 感兴趣的对象有机会对转换作出响应


希望能有所帮助。

我的拙见是,首先这可以通过UX限制来解决。用户不应该在应用程序中发送任何按钮。这两个事件之间必须有延迟。即使您可以添加一些最大值。在用户决策之间切换…请稍等片刻,然后再次免费(可能)。若我理解正确。@gyer那个么,若我将阻止按钮,直到以前的数据写入数据库,这是一个好的解决方案吗?你们也可以写答案。若并没有更多的答案,我可以接受。谢天谢地,有一件事让我困惑。Instagram不像按钮那个样阻止。我发明的另一个选项是保存最终状态和upd仅在post info休假时食用(手机或控制器nvm)。但idk关闭应用程序时该怎么做,当用户在此页面上时,您对Instagram的看法是正确的。但他们可能没有任何性能问题。在appdelegate应用程序上保存更改不是一个好主意,因为您有5秒的限制。可能是另一种方法。完成后开始向db写入-检查类似的状态,如果这是另一个,而不是写,发送另一个写请求。它好吗?为什么?看。1)我点击了like-sending request-l-rl-l-rl-l-rl-完成写操作-检查状态-更改-发送另一个请求。2) 我点击了like-sending request-l-rl-l-rl-l-completion of write operation-check state-not change-dont send any request.Ok。我会成功的。如果没有别的,我也会等到晚上再接受