在开发项目中,我们会经常用到数据查询和分页加载。我们先了解一下 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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。