思路:bmob上構建雲端邏輯,xcode經過http請求來在不引入bmob SDK的狀況下,遠程操做bmob上構建的數據庫,實現註冊、登陸。javascript
xcode導入html
AFNetWorking-----------------網絡請求,AFNetworking請求回的數據默認爲nsdictionary,無需進一步轉換java
MBProgressHUD--------------------異步加載時的菊花顯示
git
1.bmob雲端邏輯構建github
首先bmob註冊,建立應用,拿到secretKey數據庫
雲端邏輯的調用連接是:json
http://cloud.bmob.cn/secretKey/functionName數組
雲端邏輯的編寫使用的js,沒基礎的可學下JS的基礎用法,這裏提一下xcode
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
有興趣的夥伴,能夠留言相互討論!