美文网首页iOS收藏v2panda的技术专题iOS开源&高仿项目精选
「iOS」行车服务app 「客户端、后端思路+代码」

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

作者: halohily | 来源:发表于2017-05-22 23:34 被阅读7088次
  • 最近开发了一个行车服务项目,iOS客户端采用Objective-C编写, 后端采用PHP搭建,部署在阿里云,操作系统为Linux CentOS 7.3,数据库MySQL,服务器为Apache,是比较基础的LAMP组合。
  • iOS端代码部分我会讲述整体的开发思路,一些有意思的功能点也会详细说说。
  • 后端代码比较简单,想要自己尝试开发API的iOS开发者可以参考。
  • 发这篇文的主要目的是对最近的开发做一个整体回顾,同时希望对有需要的同学提供到一些帮助,有很多不尽合理和完善的地方,也请求各位同学不吝赐教,感谢大家!

首先上整体的效果图:


show.gif

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

这里是 iOS项目地址后端项目地址 。如果有帮助,希望点一下Star以示鼓励,感谢~

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

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

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

项目功能点

  • 账户、用户资料管理
  • 参照饿了么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
  • 项目初始化时采用Tabbar VC作为rootController,如果此时没有账户信息,则采用模态弹出方式弹出登录页面。

  • 这部分比较简单,客户端会先对用户输入的信息进行简单的合法判断,然后调用登录接口。

  • 有一些关于TextField的点击空白和Return回收键盘以及呼出键盘时控件移位防止遮挡的代码可以注意一下。

  • Tabbar VC初始化时,第一个tab栏的VC会进行定位操作,如果此时为已登录状态,则直接调用发送历史足迹的接口。在未登录状态下,用户点击登录按钮,登录成功时,会向第一个tab栏VC发送一个调用历史足迹接口的通知

  • 主界面(tabbar栏首页)

IMG_2009.PNG IMG_2010.PNG
  • 地理位置和天气部分。
    • 这部分是单独封装的View,UI参考了饿了么。地理位置和通知列表按钮的点击事件采用代理交由当前VC实现。
    • 由于模拟器定位获取的坐标无法使用高德地图的国内API,我对运行环境做了一下判断,如果是模拟器运行,则设置了默认坐标,对应地点大概是北京市海淀区北京理工大学
    • 当前VC加载过程中,开启定位,在地理位置反编码的成功回调中调用天气信息的接口。注意地理位置和天气信息的UI更新放在主线程执行。
    • 点击地理位置的文字时,会模态弹出重新定位的界面,重新定位按钮的点击事件使用代理交由主界面VC实现,避免在此界面再次实例化定位相关的对象。
  • 功能栏
    • 使用UICollectionView展示。各个CellIcon使用阿里巴巴的iconfont图标,将以往的图片素材转为字体来使用,对于素材整理、高清保真、代码方便来说有极大的效率提升。在Web移动客户端开发领域已经非常广泛地在使用。
  • 某一功能VC
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
    • 在页面view加载的最开始,将loading页的view加入到当前VC的view中。在页面数据加载完成的回调中,调用tableviewreload方法,而后将loading页移除。
    • loading页使用basicAnimation制作了简单的呼吸动画,keyPath为logo图标的透明度。
  • 第一个cell的POI地点默认可预约,显示预约图标,点击进入预约界面。

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

IMG_2014.PNG
  • 这里没有花费过多的精力。数据预置了网易新闻相关数据。界面UI参考了我常常使用的Max+iOS客户端的资讯功能。第一个Cell以全图为背景,可以用来突出显示重点内容。

  • 资讯详情页是一个简单的webView。同样使用了自己封装的Loading图。移除时机就简单放在了webViewfinishLoad回调方法中。其实对于Webview真正加载完成时机的判断还有很多可以聊的东西,日后补充。

  • 设置页面

IMG_2015.PNG
  • 这个页面显而易见是采用两个sectiontableview实现。在页面的viewWillAppear方法中,需要调用获取缓存数据大小的方法,单独更新清除缓存cell的内容。因为在每次切换tab的过程中,缓存数据都有可能发生变化。

  • 个人信息
    • 页面依然采用tableview实现。在信息编辑页面,仿照了微信信息更改页面的逻辑。页面出现时,立即弹出键盘。关于使textField在页面加载完成时即成为第一响应者的问题,需要重写- (BOOL)becomeFirstResponder方法。代码如下:
    - (BOOL)becomeFirstResponder
    

{
[super becomeFirstResponder];
return [self.textInput becomeFirstResponder];
}
```


IMG_2016.PNG
  • 历史足迹、历史预定、积分信息
IMG_2017.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代码,我已上传至后端项目

如果大家有兴趣,以后我可以再讲述一下server端的代码,当然,后端我也是初学者的水平,仅供想要入门的同学参考。

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

代码已开源,地址在文章首部。如果点一下star,我真的会非常感谢~
halo

相关文章

网友评论

  • 当地比较英俊的男子:超级简单的APP,我两个小时写完:stuck_out_tongue_closed_eyes:
  • DDB_CS:iOS客户端上计算缓存的话我记得应该是1M=1000K的,不是计算机中的1024
    halohily:@DDB_CS 啊,是吗:joy:,还真不知道这个,我去查证下,谢啦:wink:
  • 玉思盈蝶:就想问你们PHP怎么学的:smile: 有学习资料么,哈哈。。前段时间看了下基础,发现现在忘光了。。。
  • 小小白衣:你这个服务器还能启动一下么
  • 牛奶你个面包:后台服务器关了吗
  • brance:现在是直接注册不行了吗?
  • TryToFlyHigher:你要是不嫌麻烦我送你一台阿里云学生机 我在阿里云卖服务器
  • TryToFlyHigher:亲 你这个注册不了啊 服务器到期了?
  • TryToFlyHigher:阿婆主能告知一下如何用真机测试吗
  • 583036d2aafd:你好 请问下注册不了账号是怎么回事?
    halohily:@池大王 好的
    583036d2aafd:@halohily 哈哈 好吧 能用的时候可以通知下吗 学习下 谢谢
    halohily:@池大王 刚毕业,学生机服务器到期了:joy: 后端现在项目没跑着
  • 颜值不够才华来凑:麻烦问下 单用PHP写API的话都需要学哪些啊
    颜值不够才华来凑:@halohily希望博主能出更多的此类开源项目和教程😆
    halohily:@SunCoder 简单的sql,就没什么了,这种简单的api项目也没涉及到优化涉及到安全之类的:wink:
  • 颜值不够才华来凑:d=====( ̄▽ ̄*)b厉害
  • zl520k:有乘客端吗?
    halohily:@zl520k 没有,乘客也没需求点呀
  • 小蜜蜂Bee:你好,为什么我下载你的代码之后,真机调试的时候不能定位,定位里面一直显示“重新定位”,没有其他的任何的位置信息,这是为什么?QQ:834537795,谢谢!
    halohily:@小蜜蜂Bee 这是因为目前代码里的bundle id和我在高德地图给的key不一致。你如果需要的话可以自己随意改一个bundle id,然后在高德地图开发者中心重新注册一个对应的key,很简单的
  • 雪_晟:一定要下载下来看看 打算转后台了
    halohily:@雪_晟 加油:wink: 我新发布了一篇关于后端的简析,希望有帮助
  • 44d3387e09f3:感谢分享
    halohily:@Marcello_Gong 谢谢:wink:
  • 大尾巴熊Johnny:纯代码写控件,这代码量就够呛了,改用SB来画吧,看起来直观些!
  • halohily:刚刚修复了pch文件预编译地址问题,和一个接口调用时的bug,感谢大家的issues!
  • 可以叫我汤包呀:偶遇Dotaer
    可以叫我汤包呀:@halohily max+ 出卖了你
    halohily:@灌汤包丶 哈哈,这都能发现
  • Dayon:代码里没有任何封闭概念
    halohily:@Dayon 对于项目里的一些模块是可以这么说的,不过以后整理代码的时候可以再处理~有些比如loading页单独封装出来,页面数据传值用分类,是不是可以符合你说的类实现封闭呢
  • RBNote:全栈啊。
  • 午夜大鸟王:厉害了我的哥!点个赞!
    halohily:@Wiimz 谢谢:wink:
  • SHY圆圆圈圈圆圆:UI做的很棒,赞一个。另外阿里云部署的简易教程可否提供一下学习。
    SHY圆圆圈圈圆圆:@南人在外 直接注册登陆
    钱刀为:是真实的注册成功登陆,或者说有某一个手机号码才可以登录?
    halohily:好的
  • ebay_Happy:大神厉害了,全栈牛逼。加油
  • 042a0e1be73f:你这么做,你老板知道吗:smile:
    halohily:@iOSwift 哈哈,这个是没任何经济利益的纯个人项目:stuck_out_tongue:
  • layjoy:厉害了,我以前做iOS,这两年在做PHP,但还没自己一个人做过完整的app开发,学习了!
    halohily:@layjoy 有帮助就好:wink::wink:
  • e2e8db4f6858:请教个问题,我是纯iOS开发者,也想学习后台的东西,自己搞点东西,PHP跟java,自学哪个好呢?
    e2e8db4f6858:@音乐君 谢谢,我了解下
    halohily:@ZNKL 我自己的经验来看,如果只是自己项目需要一些简单API开发的话,与java相比php是很好入门的,开发部署也很方便。当然,也可以参考楼上朋友的意见
    slimsallen:学 node 或者go吧
  • xiao小马哥:不错 赞!
    halohily:@xiao小马哥 谢谢:blush:
  • 捏捏你的脸:放点 PHP的入门吧 作者
    halohily:我已经发布了关于后端代码的文章~http://www.jianshu.com/p/1bd426ad2f2b
    halohily:@捏捏你的脸 好,后续会再写一篇
  • PlusNie:数据库表结构没有吗?
    halohily:@NiePlus 好的,收到反馈
    PlusNie:@halohily 需要,数据结构这里可以详细写一下:kissing_heart:
    halohily:@NiePlus 需要的话我后续会写一篇关于后端的文章~ 现在暂时还没整理
  • 7fb33034b19a:整体的页面效果和交互设计是如何搭建的?都有现成的嘛?
    halohily:@reid312 交互方面只少量使用了MBProgress HUD,其他都是自己实现的,比如loading、页面滑动的特性
  • 请输入账号名:正在从iOS转其他的坑了。。前端的冬天来了。
    Colin_狂奔的蚂蚁:@halohily 你的hybrid 框架是用的什么库?
    halohily:@请输入账号名 其实也还好。我前段时间在做React Native和Hybrid框架iOS端的工作,这块在现在前端业界算是非常火热的领域
  • footSInRoad:牛 !!!
    halohily:@不以物喜_不以己悲 希望能有帮助:blush:
  • 阿兹尔:下载下来有点问题,报了错了
    阿兹尔:@halohily 我自己弄好,一个pod 问题 一个 pct 文件
    halohily:项目使用CocoaPods集成第三方库,之前我对Pods文件夹做了ignore,刚刚已经重新上传了。你可以重新下载一份,并且使用后缀名为'xcworkspace'的文件打开,是可以直接运行的~
  • 莫浅浅:哈哈,同行!你这个定位是为车主服务的?
    iOS_渔翁:同行iOS开发,想转PHP, 这两天在看PHP, 能给一些建议吗?
    莫浅浅:腻害腻害:smile:
    halohily:@莫浅浅 对的,车主根据定位信息进行周边poi检索:smile:
  • 喵呜呜喵:学习了!
    halohily:@喵呜呜喵 :yum:有帮助就好

本文标题:「iOS」行车服务app 「客户端、后端思路+代码」

本文链接:https://www.haomeiwen.com/subject/mvbixxtx.html