BOMB开发文档

简介

Bmob平台为您的移动应用提供了一个完整的后端解决方案,我们提供轻量级的SDK开发包,让开发者以最小的配置和最简单的方式使用Bmob平台提供的服务,进而完全消除开发者编写服务器代码以及维护服务器的操作。

使用CocoaPods安装BmobSDK

如何使用CocoaPods安装BmobSDK可查看我们提供的文档: https://github.com/bmob/bmob-ios-sdk/blob/master/InstallCocoaPods.md

应用程序

在Bmob平台注册的每个账户都可以创建多个应用程序,每个应用程序都有其独自的应用程序ID,在后续程序编写中,所有的应用程序将凭其ID来使用Bmob SDK。同一个应用可以分别在测试环境和生产环境中部署不同的版本。

应用安全

请大家在使用Bmob开发应用程序之前,认真阅读我们给大家提供的“数据与安全”的文档,确保你的应用在发布时安全。文档的链接地址是:http://docs.bmob.cn/datasafety/index.html?menukey=otherdoc&key=datasafety

数据类型

目前为止,我们支持的数据类型有NSString、int、Boolean、NSDate、NSArray、NSDictionary以及BmobObject 对象类型。

对象

数据对象

Bmob存储的数据是建立在BmobObject基础上的,每个BmobObject包含键(Key)-值(value)对的JSON兼容数据。这个数据是无模式的,这意味着不需要提前指定每个BmobObject存在什么键。你只需要设置你想要的键值对让我们在后端存储。

例如,假设你要记录一个游戏的得分。一个单一的BmobObject对象可能包含:score: 1337, playerName: "Sean Plott", cheatMode: false。键必须是字母、数字的字符串。值可以是字符串、数字、布尔值、Json数组、和BmobObject对象等。

每个BmobObject有一个ClassName,它对应后台的表名。例如,我们可以调用的游戏分数对象的ClassName为GameScore,那么它在后台对应的表名就是GameScore。

特殊对象

为了提供更好的服务,BmobSDK中提供了BmobUser、BmobInstallation两个特殊的BmobObject对象来完成不同的功能,在这里我们统一称为特殊对象。 BmobUser对象主要是针对应用中的用户功能而提供的,它对应着web端的User表,使用BmobUser对象可以很方便的在应用中实现用户的注册、登录、邮箱验证等功能,具体的使用方法可查看文档的用户部分。 BmobInstallation对象主要用于应用的安装设备管理中,它对应着web端的Installation表,任何安装了你应用的设备都会在此表中产生一条数据标示该设备。结合Bmob提供的推送功能,还可以实现将自定义的消息推送给不同的设备终端,具体的使用方法可查看文档的消息推送部分。

添加数据

添加一条数据有两步,一是构造数据,一是保存数据至服务器上,具体的代码模板如下:

    BmobObject *<#objectName#> = [BmobObject objectWithClassName:@"<#tableName#>"];
    [<#objectName#> setObject:<#columnValue#> forKey:<#columnName#>];
    <#code of set column value#>
    [<#objectName#>saveInBackgroundWithResultBlock:^(BOOL isSuccessful, NSError *error){
      
        if (isSuccessful) {
      
            //添加成功后的动作
            NSLog(@"%@",@"successful");
        } else if (error){
      
            //发生错误后的动作
            NSLog(@"%@",error);
        } else {
      
            NSLog(@"Unknow error");
        }
    }];

比如,在一个游戏的应用中,当需要保存游戏分数、玩家信息到服务器中的时候,就可以创建GameScore表来添加数据,添加数据的形式类型与iOS中的NSMutableDictionary对象类似

    //在GameScore创建一条数据,如果当前没GameScore表,则会创建GameScore表
    BmobObject  *gameScore = [BmobObject objectWithClassName:@"GameScore"];
    //score为1200
    [gameScore setObject:[NSNumber numberWithInt:1200] forKey:@"score"];
    //设置userName为小明
    [gameScore setObject:@"小明" forKey:@"playerName"];
    //设置cheatMode为NO
    [gameScore setObject:[NSNumber numberWithBool:NO] forKey:@"cheatMode"];
    //设置age为18
    [gameScore setObject:[NSNumber numberWithInt:18] forKey:@"age"];
    //异步保存
    [gameScore saveInBackgroundWithResultBlock:^(BOOL isSuccessful, NSError *error) {
      
        if (isSuccessful) {
      
            //创建成功后会返回objectId,updatedAt,createdAt等信息
            //打印objectId
            NSLog(@"objectid :%@",gameScore.objectId);
        } else if (error){
      
            //发生错误后的动作
            NSLog(@"%@",error);
        } else {
      
            NSLog(@"Unknow error");
        }
    }];

运行完以上代码后,数据即可保存到服务器端了。为了确认数据是否真的 已经保存成功,你可以在Bmob服务器端你的应用程序的数据浏览项目中查看。你应该看到类似这样的结果:

objectId: "0c6db13c", score: 1200, playerName: "小明", cheatMode: false, createdAt:"2012-03-29 10:32:54", updatedAt:"2012-03-29 10:32:54"

你也可以通过[gameScore saveInBackgroundWithBlock:^ (BOOL isSuccessful, NSError *error){}];来确认是否创建成功。

这里需要注意几点:

  1. 在运行以上代码时,如果服务器端你创建的应用程序中已经存在GameScore数据表和相应的score、playerName、cheatMode等字段,那么你此时添加的数据和数据类型也应该和服务器端的表结构一致,否则将保存数据失败。
  2. 如果服务器端不存在GameScore数据表,那么Bmob将根据你第一次(也就是运行的以上代码)保存的GameSocre对象在服务器为你创建此数据表并插入相应数据。
  3. 每个BmobObject对象有几个默认的键(数据列)是不需要开发者指定的,objectId是每个保存成功数据的唯一标识符。createAt和updateAt代表每个对象(每条数据)在服务器上创建和最后修改的时间。这些键 (数据列)的创建和数据内容是由服务器端来完成的。
  4. 在 [gameScore saveInBackgroundWithResultBlock:^(BOOL isSuccessful, NSError *error)中,成功创建后,error返回的是nil,可以通过[[error userInfo] objectForKey:@"error"]查看返回的错误信息,之后的类似于 xxInBackground 中的error也是一样的结构。
  5. objectId,updatedAt,createdAt这些系统属性在调用创建函数(saveInBackground)的时候不需要进行设置,创建成功后,会返回objectId,updatedAt,createdAt。

上述方法中每添加一条数据需要设置一次键值对,如果觉得过于繁琐,可以通过一个NSDictionary来添加数据,利用以下方法即可:

    -(void)saveAllWithDictionary:(NSDictionary*)dic;

这个函数。

如:

    BmobObject  *gameScore = [BmobObject objectWithClassName:@"GameScore"];
    //设置playerName列的值为小黑和age列的值18
    NSDictionary *dic = @{@"playerName":@"小黑",@"score":@18};
    [gameScore saveAllWithDictionary:dic];
    //异步保存
    [gameScore saveInBackgroundWithResultBlock:^(BOOL isSuccessful, NSError *error) {
      
        if (isSuccessful) {
      
            //创建成功后的动作
        } else if (error){
      
            //发生错误后的动作
            NSLog(@"%@",error);
        } else {
      
            NSLog(@"Unknow error");
        }
    }];

查询数据

查询多条数据

在某些情况下,当需要查询表中多条元素的时候,可以直接使用findObjectsInBackgroundWithBlock函数获取查询结果,默认100条。

BmobQuery   *bquery = [BmobQuery queryWithClassName:@"GameScore"];
//查找GameScore表的数据
[bquery findObjectsInBackgroundWithBlock:^(NSArray *array, NSError *error) {
      
        for (BmobObject *obj in array) {
      
            //打印playerName
            NSLog(@"obj.playerName = %@", [obj objectForKey:@"playerName"]);
            //打印objectId,createdAt,updatedAt
            NSLog(@"obj.objectId = %@", [obj objectId]);
            NSLog(@"obj.createdAt = %@", [obj createdAt]);
            NSLog(@"obj.updatedAt = %@", [obj updatedAt]);
    }
}];

这里需要注意的是:

1.默认情况下,系统实际上并不会返回所有的数据,而是默认返回10条数据记录,你可以通过setLimit方法设置返回的记录数量。更多细节可点击查看分页查询一节。

2.当查询的是用户表这种系统表的时候,返回的是BmobUser的数组,设备表,角色表也是这样的。

3.查询用户表,设备表、角色表为:

BmobQuery   *bquery = [BmobUser query]; //用户表
BmobQuery   *bquery = [BmobInstallation query]; //设备表
BmobQuery   *bquery = [BmobRole query]; //角色表

查询单条数据

在某些情况下,如果知道某条数据的objectId,而且想得知该条数据的内容,可以使用BmobQuery检索得到一个完整的BmobObject:

//查找GameScore表
BmobQuery   *bquery = [BmobQuery queryWithClassName:@"GameScore"];
//查找GameScore表里面id为0c6db13c的数据
[bquery getObjectInBackgroundWithId:@"0c6db13c" block:^(BmobObject *object,NSError *error){
      
  if (error){
      
          //进行错误处理
  }else{
      
        //表里有id为0c6db13c的数据
      if (object) {
      
            //得到playerName和cheatMode
          NSString *playerName = [object objectForKey:@"playerName"];
          BOOL cheatMode = [[object objectForKey:@"cheatMode"] boolValue];
          NSLog(@"%@----%i",playerName,cheatMode);
          //打印objectId,createdAt,updatedAt
          NSLog(@"object.objectId = %@", [object objectId]);
          NSLog(@"object.createdAt = %@", [object createdAt]);
          NSLog(@"object.updatedAt = %@", [object updatedAt]);
      }
  }
}];

条件查询

当然了,在大多数情况下,开发者还是会通过特定的条件来筛选,过滤某些数据来进行查询。BmobQuery也提供了对应的查询方法。

如果要过滤特定键的值可以使用- (void)whereKey:(NSString *)key notEqualTo:(id)object。比如需要查询playerName不等于”小明”的数据时可以这样写:

当然,你也可以在你的查询操作中添加多个约束条件,来查询符合要求的数据。

BmobQuery   *bquery = [BmobQuery queryWithClassName:@"GameScore"];
//添加playerName不是小明的约束条件
[bquery whereKey:@"playerName" notEqualTo:@"小明"];

各种不同条件的比较查询,还有

各种不同的比较查询:
[bquery whereKey:@"age" lessThan:[NSNumber numberWithInt:18]];//age小于18
[bquery whereKey:@"age" lessThanOrEqualTo:[NSNumber numberWithInt:18]]; //age小于或等18
[bquery whereKey:@"age" greaterThan:[NSNumber numberWithInt:18]]; //age大于18
[bquery whereKey:@"age" greaterThanOrEqualTo:[NSNumber numberWithInt:18]]; //age大于或等于18

这里有点需要注意的是

时间搜索的话,等于的情况因为服务器是精确到微秒值,所以比较的值要加1秒。

如果你想查询匹配几个不同值的数据,如要查询“小明”,“小红”,“小白”三个人的信息是,可以使用

- (void)whereKey:(NSString *)key containedIn:(NSArray *)array;

函数,如下面所示:

[bquery whereKey:@"playerName" containedIn:[NSArray arrayWithObjects:@"小明",@"小红",@"小白", nil]];

相反,要排除这几个人的信息可以用

- (void)whereKey:(NSString *)key notContainedIn:(NSArray *)array;

函数,如下所示:

[bquery whereKey:@"playerName" notContainedIn:[NSArray arrayWithObjects:@"小明",@"小红",@"小白", nil]];

其他的约束条件有

//设置查询后返回的字段数组    
-(void)selectKeys:(NSArray*)keys;
//设置查询中该字段是有值的结果
-(void)whereKeyExists:(NSString *)key;
//设置查询中该字段是没有值的结果
-(void)whereKeyDoesNotExist:(NSString *)key;

例如:

//指定返回查询的结果包括score和playerName两列的数据
[bquery selectKeys:@[@"score",@"playerName"]];
//查询表中score列有值的数据
[bquery whereKeyExists:@"score"];
//查询表中score列没有值的数据
[bquery whereKeyDoesNotExist:@"score"];

模糊查询

对字符串值的模糊查询 比如查询包含字符串的值,有几种方法。如下:

//使用正则表达式查询
-(void)whereKey:(NSString*)key matchesWithRegex:(NSString*)regex;
//查询以特定字符串开头的值
-(void)whereKey:(NSString *)key startWithString:(NSString*)start;
//查询以特定字符串结尾的值
-(void)whereKey:(NSString *)key endWithString:(NSString*)end;

分页查询

有时,在数据比较多的情况下,你希望查询出的符合要求的所有数据能按照多少条为一页来显示,这时可以使用limit方法来限制查询结果的数据条数来进行分页。默认情况下,Limit的值为10,最大有效设置值1000(设置的数值超过1000还是视为1000)。

bquery.limit = 3;//限制得到的结果条数为3条

在数据较多的情况下,在limit的基础上分页显示数据是比较合理的解决办法,skip属性可以做到跳过查询的前多少条数据来实现分页查询的功能。默认情况下Skip的值为10。

bquery.skip = 3;//跳过3条数据

结果排序

对应数据的排序,如数字和字符串,可以使用升序或降序的方式来控制查询数据的结果顺序:

// 升序
- (void)orderByAscending:(NSString *)key ;
// 降序
- (void)orderByDescending:(NSString *)key ;

例如,分数由高到低的排序可以写成

[bquery orderByDescending:@"score"];

统计对象数量

如果你只是想统计满足查询对象的数量,你并不需要获取所有匹配的对象的具体数据信息,可以直接使用count替代find。例如,查询一个特定玩家玩的游戏场数:

BmobQuery *bquery = [BmobQuery queryWithClassName:@"GameScore"];
[bquery whereKey:@"playerName" equalTo:@"Barbie"];
[bquery countObjectsInBackgroundWithBlock:^(int number,NSError  *error){
      
         NSLog(@"%d",num);
}];

对于对象数量超过1000个的查询,这种计数请求可能会出现请求超时。它可能会遇到超时错误或者返回一个近似的值。因此,请仔细设计你的应用架构来避免依赖这种计数查询。

复杂查询

当简单的查询条件,不能满足查询要时,BmobQuery也提供了2种复合查询的方法。

//并查询
-(void)addTheConstraintByAndOperationWithArray:(NSArray*)array;
//或查询
-(void)addTheConstraintByOrOperationWithArray:(NSArray *)array;

支持的有

Key Operation 
$lt 小于 
$lte 小于等于 
$gt 大于
$gte 大于等于
$ne 不等于
$in 在数组中
$nin 不在数组中
$exists 值不为空
$or 合成查询中的或查询
$and 合成查询中的与查询
$regex 匹配PCRE表达式

例如:

//查询score列中值大于150或者小于5的数据
NSArray *array =  @[@{@"score":@{@"$gt":@150}},@{@"score":@{@"$lt":@5}}];
[bquery addTheConstraintByOrOperationWithArray:array];
//查询score列中值大于5和小于150的数据
NSArray *array =  @[@{@"score":@{@"$gt":@5}},@{@"score":@{@"$lt":@150}}];
[bquery addTheConstraintByAndOperationWithArray:array];

其中日期类型和pointer类型构造的方法比较特殊。 例如要查询要个时间段的数据,可以构造时间

//createdAt大于或等于 2014-07-15 00:00:00
 NSDictionary *condiction1 = @{@"createdAt":@{@"$gte":@{@"__type": @"Date", @"iso": @"2014-07-15 00:00:00"}}}; 
//createdAt小于 2014-10-15 00:00:00
NSDictionary *condiction2 = @{@"createdAt":@{@"$lt":@{@"__type": @"Date", @"iso": @"2014-10-15 00:00:00"}}};
NSArray *condictonArray = @[condiction1,condiction2];
//作用就是查询创建时间在2014年7月15日到2014年10月15日之间的数据
[bquery addTheConstraintByAndOperationWithArray:condictonArray];

如果查询的条件刚好是pointer类型的话,例如要查询某篇文章的作者是A或者B的话,可以这样构造数据:

BmobQuery *query = [BmobQuery queryWithClassName:@"Post"];
//列author为pointer类型,指向用户表
//假设用户A的objectId为aaaa ,其中classname为表名
NSDictionary *condiction1 = @{@"author":@{@"__type":@"Pointer",@"className":@"_User",@"objectId":@"aaaa"}};
//假设用户b的objecId为bbbb
NSDictionary *condiction2= @{@"author":@{@"__type":@"Pointer",@"className":@"_User",@"objectId":@"bbbb"}};
NSArray *condictionArray = @[condiction1,condiction2];
//查找作者为用户A或者作者为用户B的数据
[query addTheConstraintByOrOperationWithArray:condictionArray];
[query findObjectsInBackgroundWithBlock:^(NSArray *array, NSError *error) {
      
}];

统计查询

如果你想对表进行统计查询,可以采用以下方法。

统计方法

统计方法共有以下几种,分别用于计算总和、平均值、最大值、最小值

- (void)sumKeys:(NSArray *)keys
- (void)averageKeys:(NSArray *)keys
- (void)maxKeys:(NSArray *)keys
- (void)minKeys:(NSArray *)keys

设置完成后使用下面的方法来返回结果。

- (void)calcInBackgroundWithBlock:(BmobObjectArrayResultBlock)block

例如,如果我们要计算GameScore表所有玩家的得分总和,可以使用以下代码:

    BmobQuery *bquery = [BmobQuery queryWithClassName:@"GameScore"];
    NSArray *sumArray = [NSArray arrayWithObject:@"score"];
    [bquery sumKeys:sumArray];
    [bquery calcInBackgroundWithBlock:^(NSArray *array, NSError *error) {
      
        if (error) {
      
            NSLog(@"error is:%@",error);
        } else{
      
            if (array) {
      
                NSLog(@"%@",array);
                NSDictionary *dic = [[NSDictionary alloc] init];
                dic = [array objectAtIndex:0];
                NSLog(@"sum of score:%d",[[dic objectForKey:@"_sumScore"] intValue] );
            }
        }
    }];

计算总和只对Number类型的列有效,列名使用数组存放。返回的字典key值为_sum+首字母大写的列名,其它计算方法与sum类似,其返回的字典key值见下表

关键字 key值 例子
sum _sum+首字母大写 _sumScore
average _avg+首字母大写 _avgScore
max _max+首字母大写 _maxScore
min _min+首字母大写 _minScore
分组

分组可用于获取并不复的列值,如我想知道playrName列中有多少个不同的玩家名字,可使用以下代码:

    BmobQuery *bquery = [BmobQuery queryWithClassName:@"GameScore_LT"];
    NSArray *groupbyArray = [NSArray arrayWithObject:@"playerName"];
    [bquery groupbyKeys:groupbyArray];
    [bquery calcInBackgroundWithBlock:^(NSArray *array, NSError *error) {
      
        if (error) {
      
            NSLog(@"error is:%@",error);
        } else{
      
            if (array) {
      
                NSLog(@"%@",array);
                for (NSDictionary *dic in array) {
      
                    NSString *playerName = [dic objectForKey:@"playerName"];
                    NSLog(@"player:%@",playerName);
                }
            }
        }
    }];

另外,groupby可以结合计算函数来使用,比如我想统计每个玩家的总分,可以使用以下代码:

    BmobQuery *bquery = [BmobQuery queryWithClassName:@"GameScore"];
    NSArray *groupbyArray = [NSArray arrayWithObject:@"playerName"];
    NSArray *sumArray = [NSArray arrayWithObject:@"score"];
    [bquery groupbyKeys:groupbyArray];
    [bquery sumKeys:sumArray];
    [bquery calcInBackgroundWithBlock:^(NSArray *array, NSError *error) {
      
        if (error) {
      
            NSLog(@"error is:%@",error);
        } else{
      
            if (array) {
      
                NSLog(@"%@",array);
                for (NSDictionary *dic in array) {
      
                    NSString *playerName = [dic objectForKey:@"playerName"];
                    NSString *sum = [dic objectForKey:@"_sumScore"];
                    NSLog(@"player:%@\tsum:%@",playerName,sum);
                }
            }
        }
    }];
添加条件

利用计算方法返回来的值可以通过限制条件来获取我们想关注的结果。添加条件使用以下方法。

 -(void)constructHavingDic:(NSDictionary *)havingDic

该方法通过构造havingDic来添加限制条件,其使用方法与复杂查询类似。

例如,我们统计每个玩家的总分,但我们只需要得到总分大于50的玩家,可以使用以下代码得到:


  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值