利用bmob平台,使用云端逻辑在Xcode上实现用户注册、登录
阅读原文时间:2023年07月10日阅读:1

思路: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

有兴趣的伙伴,可以留言相互讨论!