Left/right 在我的应用程序中滑动会触发将数据保存到我的数据库的操作。然而,快速滑动会导致许多保存失败
Left/right swiping in my app triggers an action that saves data to my DB. However fast swiping causes many saves to fail
我已经实现了类似于 tinder 的滑动功能,但是 运行 在保存对象时遇到了问题。
我的数据库中当前用户的行中有 2 列。一列包含一组 acceptedUsers(用户已被点赞),另一列是 rejectedUsers 列,包含一组被拒绝的用户(已被刷过的用户)。
这是我的数据库在滑动时更新的方式:
-(void)cardSwipedLeft:(UIView *)card;
{
NSString *swipedUserId = [[[userBeingSwipedArray objectAtIndex:0] valueForKey:@"user"] valueForKey:@"objectId"];
[currentUserImagesRow addUniqueObject:swipedUserId forKey:@"rejectedUsers"];
[currentUserImagesRow saveInBackground];
当我在两次滑动之间留出大约 2 秒以上时,这很好用。然而,快速滑动会导致一些保存失败。
有没有更好的方法可以在不破坏应用用户体验的情况下做到这一点?
在使用 for 循环之前,我已经将多行保存到我的数据库中,这对我来说一直很有效。我以为 parse.com 可以处理保存的速度。
我在这个项目中同时使用 swift 和 objective-c。
感谢您的宝贵时间
这是一个有趣的问题。我认为要走的路是将滑动和节省更多地分离。从收集需要保存的东西开始...
@property(nonatomic, strong) NSMutableArray *toSave;
@property(nonatomic, assign) BOOL busySaving;
// on swipe
[self.toSave addObject: currentUserImagesRow];
[self doSaves];
- (void)doSaves {
// we get called because of user interaction, and we call ourselves
// recursively when finished. keep state so these requests don't pile up
if (self.busySaving) return;
if (self.toSave.count) {
self.busySaving = YES;
[PFObject saveAllInBackground:self.toSave block:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
// remove just the elements that were saved, remaining aware that
// new ones might have arrived while the last save was happening
NSMutableArray *removes = [@[] mutableCopy];
for (PFObject *object in self.toSave) {
if (!object.isDirty) [removes addObject:object];
}
[self.toSave removeObjectsInArray:removes];
[self doSaves];
}];
}
}
现在,我们可以处理小批量,而不是处理单个保存。用户滑动会导致一次保存,并且我们会阻止其他请求,直到当前请求完成为止。在当前请求期间,随着用户继续交互,我们让更多的保存排队。我们在保存后递归调用自己,以防一条或多条记录排队。如果 none 是,则递归调用立即结束。
编辑 - 只保存一个对象更容易,只需在最后执行相同的阻塞技巧和递归调用,但无需跟踪或保存批次...
@property(nonatomic, assign) BOOL busySaving;
// on swipe
[self doSaves];
- (void)doSaves {
if (self.busySaving) return;
if (currentUserImagesRow.isDirty) {
self.busySaving = YES;
[currentUserImagesRow saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
[self doSaves];
}];
}
}
丹让我找到了答案。我这边有一个问题导致了上面评论中提到的问题。每次滑动后都使用相同的 ID,因为我没有将它从保存我的用户对象的数组中删除。以下是我如何解决这个问题并使用 Danh 的答案找到我的解决方案。
-(void)cardSwipedRight:(UIView *)card
{
NSString *swipedUserId = [[[userBeingSwipedArray objectAtIndex:0] valueForKey:@"user"] valueForKey:@"objectId"];
// I save the swiped users id and the key for the column it will
// be saved in e.g. if liked then "acceptedUsers" if notLiked then
// "rejectedUsers" so that the doSave method saves to correct column
NSArray *array = @[swipedUserId, @"acceptedUsers"];
[self.toSave addObject: array];
//remove user from array since he/she is now saved
[userBeingSwipedArray removeObjectIdenticalTo:[userBeingSwipedArray objectAtIndex:0]];
[self doSaves];
然后:
- (void)doSaves {
if (self.busySaving) return;
if (self.toSave.count) {
self.busySaving = YES;
NSArray *arrayWithSwipedUsersIdAndKeyForColumn = [self.toSave objectAtIndex:0];
[currentUserImagesRow addUniqueObject:[arrayWithSwipedUsersIdAndKeyForColumn objectAtIndex:0] forKey:[arrayWithSwipedUsersIdAndKeyForColumn objectAtIndex:1]];
[currentUserImagesRow saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
//remove object that was just saved seeing as it is no longer needed
[self.toSave removeObjectIdenticalTo:arrayWithSwipedUsersIdAndKeyForColumn];
[self doSaves];
}];
}
}
如果有 Internet 连接,现在 100% 的时间都可以保存。我可以随心所欲地快速滑动,对象总是会被保存。
我已经实现了类似于 tinder 的滑动功能,但是 运行 在保存对象时遇到了问题。
我的数据库中当前用户的行中有 2 列。一列包含一组 acceptedUsers(用户已被点赞),另一列是 rejectedUsers 列,包含一组被拒绝的用户(已被刷过的用户)。
这是我的数据库在滑动时更新的方式:
-(void)cardSwipedLeft:(UIView *)card;
{
NSString *swipedUserId = [[[userBeingSwipedArray objectAtIndex:0] valueForKey:@"user"] valueForKey:@"objectId"];
[currentUserImagesRow addUniqueObject:swipedUserId forKey:@"rejectedUsers"];
[currentUserImagesRow saveInBackground];
当我在两次滑动之间留出大约 2 秒以上时,这很好用。然而,快速滑动会导致一些保存失败。
有没有更好的方法可以在不破坏应用用户体验的情况下做到这一点?
在使用 for 循环之前,我已经将多行保存到我的数据库中,这对我来说一直很有效。我以为 parse.com 可以处理保存的速度。
我在这个项目中同时使用 swift 和 objective-c。
感谢您的宝贵时间
这是一个有趣的问题。我认为要走的路是将滑动和节省更多地分离。从收集需要保存的东西开始...
@property(nonatomic, strong) NSMutableArray *toSave;
@property(nonatomic, assign) BOOL busySaving;
// on swipe
[self.toSave addObject: currentUserImagesRow];
[self doSaves];
- (void)doSaves {
// we get called because of user interaction, and we call ourselves
// recursively when finished. keep state so these requests don't pile up
if (self.busySaving) return;
if (self.toSave.count) {
self.busySaving = YES;
[PFObject saveAllInBackground:self.toSave block:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
// remove just the elements that were saved, remaining aware that
// new ones might have arrived while the last save was happening
NSMutableArray *removes = [@[] mutableCopy];
for (PFObject *object in self.toSave) {
if (!object.isDirty) [removes addObject:object];
}
[self.toSave removeObjectsInArray:removes];
[self doSaves];
}];
}
}
现在,我们可以处理小批量,而不是处理单个保存。用户滑动会导致一次保存,并且我们会阻止其他请求,直到当前请求完成为止。在当前请求期间,随着用户继续交互,我们让更多的保存排队。我们在保存后递归调用自己,以防一条或多条记录排队。如果 none 是,则递归调用立即结束。
编辑 - 只保存一个对象更容易,只需在最后执行相同的阻塞技巧和递归调用,但无需跟踪或保存批次...
@property(nonatomic, assign) BOOL busySaving;
// on swipe
[self doSaves];
- (void)doSaves {
if (self.busySaving) return;
if (currentUserImagesRow.isDirty) {
self.busySaving = YES;
[currentUserImagesRow saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
[self doSaves];
}];
}
}
丹让我找到了答案。我这边有一个问题导致了上面评论中提到的问题。每次滑动后都使用相同的 ID,因为我没有将它从保存我的用户对象的数组中删除。以下是我如何解决这个问题并使用 Danh 的答案找到我的解决方案。
-(void)cardSwipedRight:(UIView *)card
{
NSString *swipedUserId = [[[userBeingSwipedArray objectAtIndex:0] valueForKey:@"user"] valueForKey:@"objectId"];
// I save the swiped users id and the key for the column it will
// be saved in e.g. if liked then "acceptedUsers" if notLiked then
// "rejectedUsers" so that the doSave method saves to correct column
NSArray *array = @[swipedUserId, @"acceptedUsers"];
[self.toSave addObject: array];
//remove user from array since he/she is now saved
[userBeingSwipedArray removeObjectIdenticalTo:[userBeingSwipedArray objectAtIndex:0]];
[self doSaves];
然后:
- (void)doSaves {
if (self.busySaving) return;
if (self.toSave.count) {
self.busySaving = YES;
NSArray *arrayWithSwipedUsersIdAndKeyForColumn = [self.toSave objectAtIndex:0];
[currentUserImagesRow addUniqueObject:[arrayWithSwipedUsersIdAndKeyForColumn objectAtIndex:0] forKey:[arrayWithSwipedUsersIdAndKeyForColumn objectAtIndex:1]];
[currentUserImagesRow saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
self.busySaving = NO;
//remove object that was just saved seeing as it is no longer needed
[self.toSave removeObjectIdenticalTo:arrayWithSwipedUsersIdAndKeyForColumn];
[self doSaves];
}];
}
}
如果有 Internet 连接,现在 100% 的时间都可以保存。我可以随心所欲地快速滑动,对象总是会被保存。