「iOS」行车服务app 「客户端、后端思路+代码」

  • 最近开发了一个行车服务项目,iOS客户端采用Objective-C编写, 后端采用PHP搭建,部署在阿里云,操做系统为Linux CentOS 7.3,数据库MySQL,服务器为Apache,是比较基础的LAMP组合。
  • iOS端代码部分我会讲述总体的开发思路,一些有意思的功能点也会详细说说。
  • 后端代码比较简单,想要本身尝试开发API的iOS开发者能够参考。
  • 发这篇文的主要目的是对最近的开发作一个总体回顾,同时但愿对有须要的同窗提供到一些帮助,有不少不尽合理和完善的地方,也请求各位同窗不吝赐教,感谢你们!

首先上总体的效果图:
ios

show.gif
show.gif

在POI检索结果页面,地图控件显示为空白,是由于模拟器运行的缘由,真机效果良好git

这里是 iOS项目地址后端项目地址 。若是有帮助,但愿点一下Star以示鼓励,感谢~

这里是后端代码简析的文章后端代码简析github

「Tips」:对于发现代码运行报错的同窗,项目使用CocoaPods进行第三方库的集成。以前为了方便我对Pods文件夹作了ignore操做。刚刚已经更新,你们能够直接打开后缀为xcworkspace的项目文件运行。不过这样Github上面的项目体积会比较大。web

简单介绍:项目UI总体尽可能保持了饿了么的蓝色风格,其中某些页面参考了高德地图饿了么Max+的设计风格。sql

项目功能点

  • 帐户、用户资料管理
  • 参照饿了么UI的定位、天气模块
  • 基于高德地图API开发的POI检索,同时界面也加入了一些和高德地图app相似的特性
  • 自定义交互逻辑的预约及结果通知功能
  • 简单参照Max+app的资讯模块
  • 用户历史足迹、历史事件维护

项目使用到的API及第三方库

  • 高德地图API
  • 和风天气API
  • 本身搭建的后端相关接口
  • AFNetworking 3.0
  • SDWebImage
  • MBProgressHUD
  • 项目内的Icon大量使用阿里巴巴的iconfont图标,极力推荐

项目涉及的技术点

  • 高德地图API的相关使用。包括地图POI检索导航等功能。
  • GCD的使用示例。包括耗时操做的后台执行、UI更新相关操做等。
  • NSUserDefaults维护帐户信息。这里是为使用方便,仅供参考。
  • Core Animation的使用。因为TableView加载时采用HUD的用户体验不是很友善,我本身封装了Loading页面。

开发思路

  • 登陆注册页面

    IMG_2008.PNG
    IMG_2008.PNG

    • 项目初始化时采用Tabbar VC做为rootController,若是此时没有帐户信息,则采用模态弹出方式弹出登陆页面。
    • 这部分比较简单,客户端会先对用户输入的信息进行简单的合法判断,而后调用登陆接口。
    • 有一些关于TextField的点击空白和Return回收键盘以及呼出键盘时控件移位防止遮挡的代码能够注意一下。
    • Tabbar VC初始化时,第一个tab栏的VC会进行定位操做,若是此时为已登陆状态,则直接调用发送历史足迹的接口。在未登陆状态下,用户点击登陆按钮,登陆成功时,会向第一个tab栏VC发送一个调用历史足迹接口的通知
  • 主界面(tabbar栏首页)

    IMG_2009.PNG
    IMG_2009.PNG

IMG_2010.PNG
IMG_2010.PNG

  • 地理位置和天气部分。
    • 这部分是单独封装的View,UI参考了饿了么。地理位置和通知列表按钮的点击事件采用代理交由当前VC实现。
    • 因为模拟器定位获取的坐标没法使用高德地图的国内API,我对运行环境作了一下判断,若是是模拟器运行,则设置了默认坐标,对应地点大概是北京市海淀区北京理工大学
    • 当前VC加载过程当中,开启定位,在地理位置反编码的成功回调中调用天气信息的接口。注意地理位置和天气信息的UI更新放在主线程执行。
    • 点击地理位置的文字时,会模态弹出从新定位的界面,从新定位按钮的点击事件使用代理交由主界面VC实现,避免在此界面再次实例化定位相关的对象。
  • 功能栏
    • 使用UICollectionView展现。各个CellIcon使用阿里巴巴的iconfont图标,将以往的图片素材转为字体来使用,对于素材整理、高清保真、代码方便来讲有极大的效率提高。在Web移动客户端开发领域已经很是普遍地在使用。
  • 某一功能VC

    IMG_2011.PNG
    IMG_2011.PNG

    • 这部分UI参考了高德地图附近界面UI以及部分特性。导航栏隐去,最上面是一个地图控件,以及透明的返回按钮。下面是POI信息的tableview。在tableview向下滑动时,地图隐去,tableviewframe上移,导航栏出现。向上滑动到顶部时,tableview下移,地图出现,导航栏隐去。
    • tableview滑动时特性的实现:经过scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate代理方法,判断滑动的方向,从而对tableviewframe以及导航栏等元素进行操做。
      代码以下:数据库

      //判断滑动手势方向,决定tableview的frame改变
      -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
      {
      CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];
      if (translation.y>0) {
          NSLog(@"ssssss");
          {
              NSIndexPath *dic = self.poiList.indexPathsForVisibleRows.firstObject;
              if (self.poiList.frame.origin.y == 64 && dic.row == 0){
                  [UIView animateWithDuration:0.2 animations:^{
      
                      NSLog(@"visible:::%@",dic);
                      showMap = YES;
                      self.navigationController.navigationBar.hidden = YES;
                      self.poiList.frame = listFrame;
                  }];
              }
          }
      }else if(translation.y<0){
          NSLog(@"tttt");
          if (self.poiList.frame.origin.y == 300){
              [UIView animateWithDuration:0.2 animations:^{
                  showMap = NO;
                  self.navigationController.navigationBar.hidden = NO;
                  self.poiList.frame = listFullFrame;
              }];
          }
      }
      }复制代码
  • 在界面加载时,使用了本身封装的loading页面:
    后端

    IMG_2018.PNG
    IMG_2018.PNG

    • 在页面view加载的最开始,将loading页的view加入到当前VC的view中。在页面数据加载完成的回调中,调用tableviewreload方法,然后将loading页移除。
    • loading页使用basicAnimation制做了简单的呼吸动画,keyPath为logo图标的透明度。
  • 第一个cell的POI地点默承认预定,显示预定图标,点击进入预定界面。
    api

    IMG_2012.PNG
    IMG_2012.PNG

    • 这个部分的和后端的交互逻辑是本身定义的。通常的预定过程是预定请求发送成功后,一段时间内由店家进行赞成或拒绝操做,然后客户端收到结果回执。因为本项目简单模拟此过程,均使用http协议进行通讯。因此个人实现方式是后端收到预定请求后,直接采用随机数方式模拟店家的接受或拒绝。必定时间后,客户端调用结果查询的接口来获取预定结果。
    • 实现方式为,点击预定按钮,若预定接口调用成功,按钮字样变为预定中,钟表icon开始转动,而且按钮变为不可点击状态。与此同时,使用performSelector方式延时调用获取预定结果的接口。在此网络请求的成功回调中,向主界面发送通知,然后主界面通知按钮右侧显示通知数量的红色图标。如图。
    • 这里通知列表的数据是存在UserDefaults中的,不一样设备之间没法同步。其中涉及到一些userDefaults中数据要求的知识,具体能够参考代码。这里是由于需求是临时想出,若是常规实现方式须要开发获取通知数据的接口。我为了节省开发时间因此采用这种方式来模拟实现了。这个地方在之后能够完善~
      IMG_2013.PNG
      IMG_2013.PNG
  • 资讯Tab栏

    IMG_2014.PNG
    IMG_2014.PNG

    • 这里没有花费过多的精力。数据预置了网易新闻相关数据。界面UI参考了我经常使用的Max+iOS客户端的资讯功能。第一个Cell以全图为背景,能够用来突出显示重点内容。
    • 资讯详情页是一个简单的webView。一样使用了本身封装的Loading图。移除时机就简单放在了webViewfinishLoad回调方法中。其实对于Webview真正加载完成时机的判断还有不少能够聊的东西,往后补充。
  • 设置页面

    IMG_2015.PNG
    IMG_2015.PNG

    • 这个页面显而易见是采用两个sectiontableview实现。在页面的viewWillAppear方法中,须要调用获取缓存数据大小的方法,单独更新清除缓存cell的内容。由于在每次切换tab的过程当中,缓存数据都有可能发生变化。
    • 我的信息
      • 页面依然采用tableview实现。在信息编辑页面,仿照了微信信息更改页面的逻辑。页面出现时,当即弹出键盘。关于使textField在页面加载完成时即成为第一响应者的问题,须要重写- (BOOL)becomeFirstResponder方法。代码以下:
      - (BOOL)becomeFirstResponder
      {
      [super becomeFirstResponder];
      return [self.textInput becomeFirstResponder];
      }复制代码

      IMG_2016.PNG
      IMG_2016.PNG

    • 历史足迹、历史预约、积分信息
      IMG_2017.PNG
      IMG_2017.PNG

      IMG_2019.PNG
      IMG_2019.PNG
      • 这部分也依然使用了封装的loading页面。若是数据条目为空,则不显示tableview,提示暂无相关信息,如图。
    • 清除缓存
      • 这里其实只使用了SDImageCache的相关方法。咱们还能够清除本app的缓存数据所在目录来达到真正清除缓存的目的,往后讨论。
      • 缓存数据获取的初始单位是B,咱们须要除以10241次、2次来判断当前数据是在KB级别仍是MB级别,并做正确显示。
    • 退出登陆
      • 点击此按钮,清除userDefaults中相关数据,而后模态弹出登陆页面。
      • 这里能够注意的一点是,咱们在模态弹出登录页,而且再次登陆以后,界面是在退出登陆以前的页面的,也就是tab栏的第三个页面。若是想要再次登陆以后,界面出如今tab栏的首页,咱们能够在模态弹出登陆页的完成回调中,对当前tabVC的selected index进行设置。代码以下:
        DELoginViewController *loginVC = [[DELoginViewController alloc] init];
              [self presentViewController:loginVC animated:YES completion:^{
                  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                      // 耗时的操做
                      dispatch_async(dispatch_get_main_queue(), ^{
                          // 更新界面
                          AppDelegate * appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
                          appDelegate.tabbarVC.selectedIndex = 0;
                      });
                  });
              }];复制代码

代码的主要开发思路基本讲述完,具体的细节你们能够和我继续交流~项目中有许多不尽合理的实现方式,小部分是考虑到时间因素。欢迎你们进行讨论、指教。
有相关的问题,欢迎你们进行留言。项目中使用的自有接口,部署在个人阿里云服务器中,可外网访问。请求你们合理使用。
缓存

后端项目数据库相关的sql代码,我已上传至后端项目bash

若是你们有兴趣,之后我能够再讲述一下server端的代码,固然,后端我也是初学者的水平,仅供想要入门的同窗参考。

个人我的博客网站地址: Halo的我的博客 ,欢迎你们访问。

代码已开源,地址在文章首部。若是点一下star,我真的会很是感谢~
halo

相关文章
相关标签/搜索