思路:bmob上构建云端逻辑,xcode通过http请求来在不引入bmob SDK的情况下,远程操作bmob上构建的数据库,实现注册、登录。
xcode导入
AFNetWorking-----------------网络请求,AFNetworking请求回的数据默认为nsdictionary,无需进一步转换
MBProgressHUD--------------------异步加载时的菊花显示
1.bmob云端逻辑构建
首先bmob注册,创建应用,拿到secretKey
云端逻辑的调用链接是:
http://cloud.bmob.cn/secretKey/functionName
云端逻辑的编写使用的js,没基础的可学下JS的基础用法,这里提一下
a.js数组创建 new Array()、动态添加arr.push(element)
b.字典是一种特殊的数组,通过key访问value,字典创建var dic = {"key":"value"}
c.调用response.send(obj)来返回云端函数处理的结果到xcode,以进一步处理
举个粒子:
function example(request,response,modules) { //客户端有参数上传,使用的post请求,request拿到相应参数 var curname = request.body.name; var curPsd = request.body.password; //response将云端执行的结果返回SDK respose.send(obj) modules提供各种对象处理的模块,如oData数据库对象、oFunctions云端逻辑对象 var db = modules.oData; db.find( { "table":"tableName" },functions(err,data) { }); }
具体的数据库操作,方法之间的调用,看bmob开发文档!
我这里创建了4个云端函数,多说无益,附上doLogin、registerUser的代码
function onRequest(request, response, modules) { var functions = modules.oFunctions; var nameArr = new Array(); var str = ""; functions.run({ "name":"getAllUserName" },function(err,data){ //data为二进制流,转换一下 var jsonObj = JSON.parse(data); // response.send(jsonObj); for(var o in jsonObj){ var tmpstr = jsonObj[o]; if(tmpstr){ //非空字符串 nameArr.push(tmpstr); } } // response.send(nameArr); var curname = request.body.username; var curpassword = request.body.password; //设立boolean变量,0-false,1-true var flag = 1; //构建输出端口 var finalArr = {"code":"","msg":""}; for(var i in nameArr){ var tmpStr = nameArr[i]; // response.send(tmpStr); if(tmpStr == curname){ flag = 0; finalArr["code"] = "100"; finalArr["msg"] = "用户名已注册"; // response.send("用户名已注册!"); response.send(finalArr); break; } } if(flag){ var db = modules.oData; finalArr["code"] = "200"; if(curname && curpassword){ db.insert({ "table":"TestUser", "data":{"name":curname,"password":curpassword} },function(err,data){ if(err){ // response.send(err); finalArr["msg"] = err; }else{ // response.send("注册成功"); finalArr["msg"] = "注册成功"; } response.send(finalArr); }); } } }); }
function onRequest(request, response, modules) { var functions = modules.oFunctions; var nameArr = new Array(); functions.run({ "name":"getAllUserName" },function(err,data){ var jsonObj = JSON.parse(data); for(var o in jsonObj){ var tmpstr = jsonObj[o]; if(tmpstr){ nameArr.push(tmpstr); } } // response.send(nameArr); var curname = request.body.username; var curpassword = request.body.password; var flag = 0; //构建responseObj var responseObj = {"code":"","msg":""}; for(var o in nameArr){ var tmpstr = nameArr[o]; if(curname == tmpstr){ flag = 1; break; } } if(flag == 0){ // response.send("用户名未注册!" responseObj["code"] = "100"; responseObj["msg"] = "用户名未注册!"; response.send(responseObj); }else{ var db = modules.oData; db.find({ "table":"TestUser" //单条数据必须使用objectID查询 // "name":curname },function(err,data){ // response.send(data); //遍历data,拿到相应name的password var jsonObj = JSON.parse(data); var arr = jsonObj["results"]; // var loginFlag = 0; for(var o in arr){ var theName = arr[o].name; if(theName == curname){ var thePassword = arr[o].password; if(thePassword == curpassword){ // response.send("登录成功!"); responseObj["code"] = "200"; responseObj["msg"] = "登录成功!"; }else{ // response.send("密码错误!"); responseObj["code"] = "201"; responseObj["msg"] = "密码错误!"; } response.send(responseObj); break; } } }); } }) }
云端函数的调试有两种方式,一种直接浏览器上链接
另一种函数写完,直接测试(推荐),网页链接仅指向最近的一次正确提交,显示不了错误
Xcode发起请求,并拿回处理结果
1.afnetworking封装(不在赘述)
// AFNetWorkingHelper.m // DateCorner // // Created by 小儿黑挖土 on 16/12/2. // Copyright © 2016年 小儿黑挖土. All rights reserved. #import "AFNetWorkingHelper.h" static AFNetWorkingHelper *_instance = nil; @interface AFNetWorkingHelper () @property (nonatomic,strong)AFHTTPSessionManager *manager; @end @implementation AFNetWorkingHelper +(instancetype) defaultHelper{ static dispatch_once_t token; dispatch_once(&token, ^{ _instance = [[super allocWithZone:NULL] init]; [_instance initialization]; }); return _instance; } //重写alloc,copy的调用方法,instanc只初始化一次,实现单例 +(id)allocWithZone:(struct _NSZone *)zone{ return [AFNetWorkingHelper defaultHelper]; } -(id)copyWithZone:(struct _NSZone *)zone{ return [AFNetWorkingHelper defaultHelper]; } #pragma mark HTTP -(void)sendRequestWithURLString:(NSString *)urlString parameters:(NSDictionary *)parameters success:(void (^)(NSURLSessionDataTask *,id))success failure:(void (^)(NSURLSessionDataTask *,NSError *))failure cache:(BOOL)useCache{ // _manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; if(useCache){ _manager.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad; }else{ _manager.requestSerializer.cachePolicy = NSURLRequestUseProtocolCachePolicy; } if(parameters != nil){//post [_manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { @try{ success(task,responseObject); }@catch(NSException *exception){ NSLog(@"[%@] throws exception:%@",NSStringFromSelector(_cmd),exception); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { @try{ failure(task,error); }@catch(NSException *exception){ NSLog(@"[%@] throws exception:%@",NSStringFromSelector(_cmd),exception); } }]; }else{//get [_manager GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { @try{ success(task,responseObject); }@catch(NSException *exception){ NSLog(@"[%@] throws exception:%@",NSStringFromSelector(_cmd),exception); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { @try{ failure(task,error); }@catch(NSException *exception){ NSLog(@"[%@] throws exception:%@",NSStringFromSelector(_cmd),exception); } }]; } } -(void)sendRequestWithURLString:(NSString *)urlString parameters:(NSDictionary *)parameters success:(void (^)(NSURLSessionDataTask *,id))success failure:(void (^)(NSURLSessionDataTask *,NSError *))failure{ [self sendRequestWithURLString:urlString parameters:parameters success:success failure:failure cache:NO]; } -(void)sendRequestWithURLString:(NSString *)urlString success:(void (^)(NSURLSessionDataTask *,id))success failure:(void (^)(NSURLSessionDataTask *,NSError *))failure cache:(BOOL)useCache{ [self sendRequestWithURLString:urlString parameters:nil success:success failure:failure cache:useCache]; } -(void)sendRequestWithURLString:(NSString *)urlString success:(void (^)(NSURLSessionDataTask *,id))success failure:(void (^)(NSURLSessionDataTask *,NSError *))failure{ [self sendRequestWithURLString:urlString parameters:nil success:success failure:failure cache:NO]; } -(void)uploadWithURLString:(NSString *)urlString data:(NSData *)data success:(void (^)(NSURLResponse *,id))success failure:(void (^)(NSURLResponse *,NSError *))failure{ NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request addValue:@"b21fbd9b0ce4879dc618f6f685c223e0" forHTTPHeaderField:@"X-Bmob-Application-Id"]; [request addValue:@"8f397fe28f5e02d316d9af109b3fcdc9" forHTTPHeaderField:@"X-Bmob-REST-API-Key"]; [request addValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:data]; [request setHTTPMethod:@"POST"]; NSURLSessionDataTask *task = [_manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { @try{ if(error != nil){ /*error NSError * domain: @"com.alamofire.error.serialization.response" - code: 18446744073709550605 0x0000600000440a50*/ failure(response,error); }else{ success(response,responseObject); } }@catch(NSException *exception){ NSLog(@"throw exception:%@",exception); } }]; [task resume]; } #pragma mark private -(void)initialization{ self.manager = [AFHTTPSessionManager manager]; } @end
2.封装参数,post请求
-(void)uploadPara{ NSString *username = _usernameField.text; NSString *password = _passwordField.text; NSDictionary *para = @{@"username":username,@"password":password}; AFNetWorkingHelper *helper = [AFNetWorkingHelper defaultHelper]; [helper sendRequestWithURLString:KURLTypeRegister parameters:para success:^(NSURLSessionDataTask *task, NSDictionary *jsonObj) { [self successWithTask:task response:jsonObj]; } failure:^(NSURLSessionDataTask *task, NSError *error) { [self failureWithTask:task error:error]; }]; }
3.拿回结果,进行相应的逻辑处理
//登录状态 -(void)successWithTask:(NSURLSessionTask *)task response:(NSDictionary *)data{ if(data){ //hud显示在异步网络请求前,消失在数据回传之后 [hud hideAnimated:YES]; NSString *msg = data[@"msg"]; NSInteger code = [data[@"code"] integerValue]; [self tipsAniamtion:msg]; if(code == 200){ [self performSelector:@selector(doDismiss) withObject:nil afterDelay:3]; } } } -(void)failureWithTask:(NSURLSessionTask *)task error:(NSError *)error{ // NSLog(@"register with error:%@",error.localizedDescription); // [self tipsAniamtion:error.localizedDescription]; }
项目效果如下:
源项目地址:https://github.com/xuanyuelin/BmobRegister/tree/master
有兴趣的伙伴,可以留言相互讨论!