我有像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)
})
}
因此,当用户点击“删除”时,我有一些延迟(此时正在获取实体以获取反馈ID)。
问题:如果我发送垃圾邮件like-removeLike
按钮(例如 - 删除像 - l - rl - l - rl等),有时我的反馈节点是重复的(带有不同的密钥ofc。它没有删除旧的节点)有时它没有添加(在这种情况下,如果我将来尝试删除它会崩溃)。
如何解决?
答案 0 :(得分:1)
我的拙见,首先,这可以解决UX的限制。用户不应该在应用程序中垃圾邮件任何按钮。必须是这些事件之间的延迟。即使你可以添加一些最大值。在用户决定之间切换......等待一段时间再让它自由(也许)。
就像你在评论中说的那样,在完成写操作之前,这是一个非常好的想法和良好的用户体验等待用户。这样你就可以消除不良的用户体验。
您可以使用UIView的userinteractionenabled属性。
设置为NO时,触摸,按下,键盘和聚焦事件 用于视图的将被忽略并从事件队列中删除。 设置为YES时,事件将正常传递到视图。该 此属性的默认值为YES。
动画期间,用户 对于涉及的所有视图,暂时禁用交互 动画,无论此属性中的值如何。你可以禁用 通过指定此行为 配置时的UIViewAnimationOptionAllowUserInteraction选项 动画。
当然有很多选择,天空是UX场景的限制。
您还可以查看Apple的用户界面指南以进行加载:
https://developer.apple.com/ios/human-interface-guidelines/interaction/loading/
尽快显示内容。不要让人们等待内容 在看到他们期待的屏幕之前加载。显示屏幕 立即,并使用占位符文本,图形或动画 确定内容尚不可用的位置。替换这些占位符 元素作为内容加载。只要可能,预加载即将到来 背景中的内容,例如播放动画时或 用户正在导航关卡或菜单。
和指标可能:
https://developer.apple.com/ios/human-interface-guidelines/ui-controls/progress-indicators/
如果它有用,请在等待任务时提供有用的信息 去完成。在活动指标上方添加标签以提供额外费用 上下文。避免模糊的术语,如加载或验证,因为它们 通常不添加任何价值。
就像你在下面的评论中所说的那样,在用户使用ViewController之前,还有另一种选择可以保持喜欢/不喜欢。但是还有另一个用户体验问题,当用户尝试关闭模式或返回到上一个视图控制器时,他们将等到后台作业完成。另一个问题是,如果用户杀死了你需要进行1次更改的应用程序以保存数据,那么它就是AppDelegate的applicationWillTerminate。但是在那里保存数据是不好的做法,因为5秒限制:
此方法可让您的应用知道它即将被终止 完全从记忆中清除。您应该使用此方法执行任何操作 应用程序的最终清理任务,例如释放共享资源, 保存用户数据,并使计时器无效。你执行这个 方法大约五秒钟来执行任何任务并返回。
如果方法在时间到期之前没有返回,系统可能会终止 这个过程完全。对于不支持背景的应用程序 执行或链接到iOS 3.x或更早版本,此方法是 在用户退出应用程序时始终调用。对于支持的应用程序 后台执行时,此方法一般不会被调用 用户退出应用程序,因为应用程序只是移动到后台 那种情况。但是,可以在以下情况下调用此方法 应用程序在后台运行(未暂停)并且系统需要 因某种原因终止它。调用此方法后,该应用程序 还发布了UIApplicationWillTerminate通知 有兴趣的对象有机会回应过渡。
希望它有所帮助。