图片描述

在开发项目中,我们会经常用到数据查询和分页加载。我们先了解一下 Query 的几个方法,然后实现分页加载。关于分页加载,在传统(有后端服务)的开发中,一般得需要后端同学的协助,给前端同学返回数据,再让前端同学实现功能,这样会费事费人力。目前,给大家介绍一下 Wilddog 无后端开发分页加载,你可以自定制实现该功能。

1.SQL Queries 和 Wilddog Queries 之间的转化

1.1 通过 ID 选 user (WHERE id = x)

将我们的用户存到了 /user 节点下面,所以,我们可以这样获取用户信息:

Wilddog *ref = [[Wilddog alloc]initWithUrl:@"https://example-data-sql.wilddogio.com/user/1"];
[ref observeSingleEventOfType:WEventTypeValue withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"I fetched a user %@",snapshot.value);
}];

1.2 通过 email address 寻找 user (WHERE email = x)

Wilddog *ref = [[Wilddog alloc]initWithUrl:@"https://example-data-sql.wilddogio.com/user"];
WQuery *query = [ref queryEqualToValue:@"kato@wilddog.com"];
[query observeSingleEventOfType:WEventTypeValue withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"accounts matching email address %@",snapshot.value);
}];

1.3 获取一段时间发送的信息(WHERE timestamp BETWEEN x AND y)

Wilddog *ref = [[Wilddog alloc]initWithUrl:@"https://example-data-sql.wilddogio.com/messages"];
Query *query = [ref queryStartingAtValue:startTime];
query = [query queryEndingAtValue:endTime];
[query observeSingleEventOfType:WEventTypeValue withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"messages in range %@",snapshot.value);
}];

2.介绍几个方法

2.1 – queryStartingAtValue:返回一个WQuery引用,这个引用用来监测数据的变化,这些被监测的数据的值均大于或等于startValue

//筛选出高度大于等于3m的恐龙
Wilddog *ref = [[Wilddog alloc] initWithUrl:@"https://dinosaur-facts.wilddogio.com/dinosaurs"];
WQuery *query = [ref queryOrderedByChild:@"height"];
query =[query queryStartingAtValue:@3];
[query observeEventType:WEventTypeChildAdded withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"%@",snapshot.key);
}];

2.2 - queryEndingAtValue:返回一个WQuery引用,这个引用用来监测数据的变化,这些被监测的数据的值均小于或者等于endValue

//筛选出高度小于等于1m的恐龙
Wilddog *ref = [[Wilddog alloc] initWithUrl:@"https://dinosaur-facts.wilddogio.com/dinosaurs"];      
WQuery *query = [ref queryOrderedByChild:@"height"];
query =[query queryEndingAtValue:@1];
[query observeEventType:WEventTypeChildAdded withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"%@",snapshot.key);
}];

2.3 - queryLimitedToFirst:返回一个新WQuery引用,获取从第一条开始的指定数量的数据

//筛选出数据库前100只恐龙
Wilddog *ref = [[Wilddog alloc] initWithUrl:@"https://dinosaur-facts.wilddogio.com/dinosaurs"];
WQuery *query = [ref queryLimitedToFirst:100];
[query observeEventType:WEventTypeChildAdded withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"%@",snapshot.key);
}];

2.4 - observeEventType:withBlock:获取初始数据和监听某一节点处数据的变化

//获取初始的那些恐龙和监听实时增加的恐龙
Wilddog *ref = [[Wilddog alloc] initWithUrl:@"https://dinosaur-facts.wilddogio.com/dinosaurs"];
[ref observeEventType:WEventTypeChildAdded withBlock:^(WDataSnapshot *snapshot) {
     NSLog(@"%@",snapshot.key);
}];

3.实现分页加载

现在用一个笔记本的实例来举例实现下拉加载,结合 - queryOrderedByChild: 、– queryStartingAtValue: 、– queryLimitedToFirst: 等方法实现分页加载。
在 .h 文件中

@interface NoteService ()
@property (nonatomic,strong) Wilddog *wilddog;
@property (nonatomic,strong) NSNumber *lastUpdatetimeOnPrevPage;
@end
@implementation NoteService
-(instancetype)init
{
     if (self = [super init]) {
         _wilddog = [[Wilddog alloc] initWithUrl: @"https://<your-noteapp-name>.wilddogio.com/note"];
         _lastUpdatetimeOnPrevPage = [NSNumber numberWithLong:0];
     }
     return self;
}

假如我们按照最后编辑时间作为排序,一次性把所有的笔记都拉下来,我们可以这样写(这儿不是分页):

-(void)getAllNotes:(void (^)(NSArray *))complete
 {
     WQuery *query = [self.wilddog queryOrderedByChild:@"lastUpdate"];
     [query observeSingleEventOfType:WEventTypeValue withBlock:^(WDataSnapshot *snapshot) {
        if (snapshot) {
            NSMutableArray *noteList = [NSMutableArray new];
            [snapshot.value enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
                NoteModel *model = [[NoteModel alloc] initWithDict:obj];
                [noteList addObject:model];
            }];
            if (complete) {
                complete(noteList);
            }
        }
     }];
 }

回到重点,我们实现分页加载:

-(void)getNotesWithPate:(int)page complete:(void (^)(NSArray *))complete
    {
         BOOL isFirstPath = page == 0; 
    
         NSString *orderKey = @"lastUpdate";
         WQuery *query = [self.wilddog queryOrderedByChild:orderKey];
         query = [query queryStartingAtValue:_lastUpdatetimeOnPrevPage];
    
         // kDefaultLimitPerPage 一次定义拉取多少条
         query = [query queryLimitedToFirst:kDefaultLimitPerPage + (isFirstPath ? 0 : 1)];      //queryStartingAtValue 是大于等于上次页最后一个的值,所以要 kDefaultLimitPerPage + 1个,然后去掉这个上一页最后一个。
         [query observeSingleEventOfType:WEventTypeValue withBlock:^(WDataSnapshot *snapshot) {
              if (snapshot) {
                  NSMutableArray *noteList = [NSMutableArray new];
                  WDataSnapshot *child = nil;
                  NSEnumerator *enumerator = snapshot.children;
                  while (child = [enumerator nextObject]) {
                      NoteModel *model = [[NoteModel alloc] initWithDict:[child value]];
                      if ([self.lastUpdatetimeOnPrevPage longLongValue] == model.lastUpdate) {
                           continue; //去掉重复的一个
                      }
                      NSLog(@"model.lastUpdate %lld",model.lastUpdate);
                      [noteList addObject:model];
                  }
                  if (noteList.count > 0) {
                      self.lastUpdatetimeOnPrevPage = @([(NoteModel *)noteList.lastObject lastUpdate]);
                  }
                  if (complete) {
                        complete(noteList);
                  }
             }
          } withCancelBlock:^(NSError *error) {
    
        }];
    }

在上拉加载的时候,只要将参数 page 自加传入即可。当每一次数据加载完成之后,我们用 complete block 将参数回调。

数据的查询和加载,更多需要的接口可以参考 iOS API


野狗
2.3k 声望116 粉丝

野狗|安全可靠的实时通信云