从0到1---“保多多”APP的开发(一)
2015年8月份,我正式接手了公司保多多APP的开发(和另一个同事一起)。
我之前并没有过从0开始创建一款APP,这次能有这样的机会,实在让我感到兴奋。因为我相信,作为这款APP的主要开发人员,在这一过程中我一定能学到太多我之前没有接触过的技术。而且从目前的进度来看,我的想法没有错。今天我主要想记录一些开发这款APP的心得,虽然APP尚未完成,但确实感触颇多。
以下内容均为最新版xcode6.4上的
首先,我们创建一个程序的启动界面,就是你点击一个APP后看到的一个界面,这个界面一般是一张关于APP的背景图,APP的名称以及版权所属公司。我们可以在LaunchScreen.xib中用UIImageView和一些label完成这个界面。
启动界面之后,我们便可以进入Main.storyboard,这是程序的主入口,一般这个里面是写用户登录的信息。在保多多中,这个界面是让用户填写登录名和密码的(也有忘记密码的按钮)。可以在stroyboard里面添加多个视图控制器,并实现它们之间的跳转关系,但是在保多多中我们没有这么做。我们只在其中添加了一个视图控制器,命名为SignInViewController。注意这里要同时在工程中创建一个同名的类,在这个类中实现逻辑代码,要注意的是,在stroyboard中要将该视图控制器与SignInViewController这个类相关联。在SignInViewController类中,我们要实现用户输入用户名和密码后的登录,核心代码:
- (void) signInAction { if ([self.userNameText.text isEqualToString:@""]) { [self showAlertView:@"用户名不能为空"]; return; } if ([self.passwordText.text isEqualToString:@""]) { [self showAlertView:@"密码不能为空"]; return; } [NetworkUtil signInApplicationWithUsername:self.userNameText.text andPassword:self.passwordText.text onSuccess:^(BOOL successful, NSDictionary *message) { //NSLog(@"message:%@",message); NSDictionary *resultMes = message[@"resultMessage"]; NSString *errorMes = resultMes[@"errorMessage"]; ) { [self showAlertView:errorMes]; return ; } NSDictionary *data = message[@"data"]; NSString *ID = data[@"UserID"]; User *user; if (ID) { user = [[User alloc] initWithID:ID]; } //属性设置 [user setValuesForKeysWithDictionary:data]; self.easeInsurance.user = user; NSUserDefaults *uds = [NSUserDefaults standardUserDefaults]; [uds setObject:self.userNameText.text forKey:UserDefaults_USERNAME]; [uds setObject:self.passwordText.text forKey:UserDefaults_PASSWORD]; [uds synchronize]; [self.navigationController pushViewController:self.easeInsurance.mainTabBarController animated:YES]; } onFailure:^(NSError *error) { }]; }
填写完用户名和密码之后,我们用一个网络请求来判断二者是否一致,如果不一致就返回错误信息,如果一致就登录成功,跳转到mainTabBarController。那么问题来了,这个mainTabBarController在哪里在什么时候初始化的?
原来,在项目中有一个AppDelegate类,程序执行时这里面的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
rerurn YES;
}方法会最先执行,在保多多中,我们在这个类里面加了个方法:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[EaseInsurance instance] launchService];
return YES;
}
这里的EaseInsurance又是什么?这个EaseInsurance类,我们称它为公共服务类,并将它设计为单例,里面放一些全局的变量并进行一些初始化工作。全局的变量有:
@property (retain) User *user;//User类,代表着用户,里面有用户所有的信息
@property (retain) UITabBarController *mainTabBarController;//分栏控制器
@property (retain) UIColor *mainColor;//APP中用到的主要的颜色
@property (assign) CGSize kScreenSize;//动态获取设备尺寸
@property (retain) NSMutableDictionary* htmlDict;//存放程序中所有的h5接口
这样,我们就明白了,我们是在AppDelegate类中,调用EaseInsurance的launchService方法,从而完成程序的一些初始化工作,而具体的初始化方法分为两个:
- (void)initializeAppearance { self.mainColor = [UIColor colorWithRed:]; [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}]; [UINavigationBar appearance].backgroundColor = self.mainColor; [[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.kScreenSize = [UIScreen mainScreen].bounds.size; }
- (void)initializeMainTabBarController { NSDictionary *selectedTitleAttributes = @{NSForegroundColorAttributeName: self.mainColor}; QuotationViewController *quotation = [[QuotationViewController alloc] initWithNibName:@"QuotationViewController" bundle:[NSBundle mainBundle]]; quotation.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"报价" image:[[UIImage imageNamed:@"HomepageIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]selectedImage:[[UIImage imageNamed:@"HomepageSelectedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; [quotation.tabBarItem setTitleTextAttributes:selectedTitleAttributes forState:UIControlStateSelected]; CarsManagementViewController *carsManagement = [[CarsManagementViewController alloc] initWithNibName:@"CarsManagementViewController" bundle:[NSBundle mainBundle]]; carsManagement.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"车辆" image:[[UIImage imageNamed:@"CarsIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"CarsSelectedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; [carsManagement.tabBarItem setTitleTextAttributes:selectedTitleAttributes forState:UIControlStateSelected]; ActivityViewController *activity = [[ActivityViewController alloc] initWithNibName:@"ActivityViewController" bundle:[NSBundle mainBundle]]; activity.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"活动" image:[[UIImage imageNamed:@"ActivityIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"ActivitySelectedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; [activity.tabBarItem setTitleTextAttributes:selectedTitleAttributes forState:UIControlStateSelected]; MineViewController *mine = [[MineViewController alloc] initWithNibName:@"MineViewController" bundle:[NSBundle mainBundle]]; mine.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"我" image:[[UIImage imageNamed:@"MineIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] selectedImage:[[UIImage imageNamed:@"MineSelectedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; [mine.tabBarItem setTitleTextAttributes:selectedTitleAttributes forState:UIControlStateSelected]; self.mainTabBarController = [[UITabBarController alloc] init]; self.mainTabBarController.tabBar.tintColor = [UIColor clearColor]; self.mainTabBarController.viewControllers = @[quotation, carsManagement, activity, mine]; }
我们可以很清楚的看到,第一个方法主要设置一些颜色和大小,第二个方法是用来创建mainTabBarController。这一切都完成之后,我们点击SignInViewController类的登录按钮,便可以进入mainTabBarController,进入后展现在我们面前的就是mainTabBarController的第一个视图控制器QuotationViewController(首页)。
进入保多多APP后主要分为4个板块:QuotationViewController(首页),CarsManagementViewController(车辆),ActivityViewController(活动),MineViewController(我)
这四个类都是继承与一个ViewController类,这样它们就都有了一个easeInsurance属性,这个属性是整个程序中唯一的,公用的。现在ViewController类中暂时没有其他的,就这一个属性,继承了这个类后都可以获得这个属性。以后我们可能加一些其他的属性或方法进去,看需要吧。
说到APP的登录,还有一点要补充,我们都知道,现在很多APP都有快速登录的功能,就是说只要你没有点击退出登录或者注销什么的按钮,你退出程序后,再次进入就不用再次输入用户名密码了,可以直接进入APP。我们的保多多也做了这样的功能。用法很简单,在用户第一次登录时,我们用 NSUserDefaults将用户名和密码保存,当用户再次打开APP时,我们先从 NSUserDefaults中取用户名和密码,然后判断:if(userName&&userPassword),如果不为空,再做类似于SignInViewController中的网络请求,没有错误的话那么直接进入,否则就无法进入。这个方法也是写在EaseInsurance的launchService方法中,因为这里是整个程序最先执行的,如果能直接进入,那么Main.storyboard便不再加载出来。
接下来我还想说说点击退出登录按钮会执行哪些方法:
-(void) clickLogout{ self.easeInsurance.user = nil; NSUserDefaults *uds = [NSUserDefaults standardUserDefaults]; [uds removeObjectForKey:UserDefaults_USERNAME];//删除本地用户的信息 [uds removeObjectForKey:UserDefaults_PASSWORD]; [uds synchronize]; [self.navigationController popToRootViewControllerAnimated:NO]; self.easeInsurance.mainTabBarController.selectedIndex = ;//这个细节也要注意 }
可以看到每次退出登录都会将self.easeInsurance.user赋空,所以我们每次无论是普通登录还是快速登录都要在进入之前(登录的网络请求成功之后)创建一个新的User对象,并将网络请求返回的用户的信息赋给它,在将这个User赋给EaseInsurance的user属性。
好了,今天的保多多APP心得就告一段落了,项目还在进行中,以后有了新的想法还会继续更新,敬请期待!
从0到1---“保多多”APP的开发(一)的更多相关文章
- 从0到1---“保多多”APP的开发(二)
今天继续记录宝多多开发过程中的一些值得注意的知识点: 1.验证车牌格式的正则表达式函数: //车牌号验证 - (BOOL)validateCarNo:(NSString *)carNo { NSStr ...
- 从0到1搭建移动App功能自动化测试平台(0):背景介绍和平台规划
本文作者: 伯乐在线 - debugtalk .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 转载地址:http://blog.jobbole.com/101221/ 背景 最近新加入DJI的 ...
- Python爬虫入门教程 42-100 爬取儿歌多多APP数据-手机APP爬虫部分
1. 儿歌多多APP简单分析 今天是手机APP数据爬取的第一篇案例博客,我找到了一个儿歌多多APP,没有加固,没有加壳,没有加密参数,对新手来说,比较友好,咱就拿它练练手,熟悉一下Fiddler和夜神 ...
- 从0到1搭建移动App功能自动化测试平台(2):操作iOS应用的控件
转自:http://debugtalk.com/post/build-app-automated-test-platform-from-0-to-1-Appium-interrogate-iOS-UI ...
- 基于vue2.0的一个豆瓣电影App
1.搭建项目框架 使用vue-cli 没安装的需要先安装 npm intall -g vue-cli 使用vue-cli生成项目框架 vue init webpack-simple vue-movie ...
- 用weexplus从0到1写一个app
说明 基于wexplus开发app是来新公司才接触的,之前只是用过weex体验过写demo,当时就被用vue技术栈来开发app的开发体验惊艳到了,这个开发体验比react native要好很多,对于我 ...
- android 7.0拍照问题file:///storage/emulated/0/photo.jpeg exposed beyond app through ClipData.Item.getUri
Android7.0调用相机时出现新的错误: android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exp ...
- Appium 从 0 到 1 搭建移动 App 功能自动化测试平台 (1):模拟器中运行 iOS 应用
转载:https://testerhome.com/topics/4960 在上一篇文章中,我对本系列教程的项目背景进行了介绍,并对自动化测试平台的建设进行了规划. 在本文中,我将在已准备就绪的iOS ...
- (转载)安卓6.0之前的系统 判断app是否有录音权限
卓6.0之前的系统 判断app是否有录音权限 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...
随机推荐
- win10查看连接过的wifi密码
cmd窗口 运行 “netsh wlan show profiles name="linasd" key=clear”
- Linux下的PostgreSQL简单安装手册
1. 安装环境 linux版本: CentOS release 6.2 (Final) pg版本 : postgresql-9.5.0 2. pg数据库下载地址 --http ...
- oracle 金额格式化
一般金额要显示成 XXX,XXX,XXX.XX的格式,可以这样做: to_char(column, 'FM999,999,999,990.00')
- R实战之热点图(HeatMap)
快速实现是搜索帮助文档的首要目的,所以此处涉及实战的文章一概略去传统帮助文档的理论部分,直接上代码加注释! 本文将介绍R语言下利用ggplot2包制作heatmap的代码 -------------- ...
- winform开发框架之模块维护
前言:模块维护试图解决的问题, 模块加载只用MEF的方式: MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库. 应用程序开发人员可利用该库 ...
- 利用backtrace和objdump进行分析挂掉的程序
转自:http://blog.csdn.net/hanchaoman/article/details/5583457 汇编不懂,先把方法记下来. glibc为我们提供了此类能够dump栈内容的函数簇, ...
- Struts2拦截器初涉
Struts2拦截器初涉 正在练习struts,本例是从一个pdf上摘抄的例子,那本pdf都不知道叫什么名字,不过感觉很适合初学者. 在这里要实现一个简单的拦截器"GreetingInter ...
- SQL Server 查询表的记录数(3种方法,推荐第一种)
http://blog.csdn.net/smahorse/article/details/8156483 --SQL Server 查询表的记录数 --one: 使用系统表. SELECT obje ...
- java编写一个可以上、下、左、右移动的坦克
唉,本人学习进度缓慢,但依然会坚持不懈!有感兴趣的朋友可以在下面留言. 源代码献上: /* * 画出我的坦克,使他可以上下左右移动 */package com.test4; import javax. ...
- iOS 推送通知处理
//这是程序杀死后再通过点击通知进入时调用的方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...