iOS中 Query 的几个方法和如何使用 Wilddog 实现分页加载

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

一、SQL Queries 和 Wilddog Queries 之间的转化

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);
}];

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);
}];

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);
}];

二、介绍几个方法

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、- 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);
}];

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);
}];

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

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

三、实现分页加载

现在用一个笔记本的实例来举例实现下拉加载,结合 – 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

 

-END-

知识共享许可协议
本站内容采用知识共享署名 4.0 国际许可协议进行许可。

热门文章:

扒一扒HTTPS网站的内幕

凭什么苹果设计师年赚110万,给产品和设计的一堂课

创业公司可以从坚果手机中学到的5点经验

Node.js与实时Baas云开发实践

发表评论

电子邮件地址不会被公开。