文章目录
  1. 1. 前言
  2. 2. 项目介绍
  3. 3. 项目使用的第三方开源库
    1. 3.1. AFNetworking
    2. 3.2. FMDB
    3. 3.3. MBProgressHUD
    4. 3.4. MJRefresh
    5. 3.5. SDWebImage
    6. 3.6. RDVTabBarController
    7. 3.7. Toast
    8. 3.8. XMPPFramework
    9. 3.9. TPKeyboardAvoiding
    10. 3.10. AMR
    11. 3.11. TQRichTextView
    12. 3.12. CSGrowingTextView
    13. 3.13. MJExtension
  4. 4. 工具和插件介绍
    1. 4.1. Xcode
    2. 4.2. SimPholders2
    3. 4.3. VVDocumenter-Xcode
  5. 5. 集成友盟
    1. 5.1. 关于推送
    2. 5.2. 关于第三方登录和分享
  6. 6. 即时通讯
  7. 7. 项目总结

前言

本 人14年12月份,从网站开发组转到了移动开发组,自己的java两年半工作经验变成了objective-c零经验。2015年1月份新启动了一个移动 项目,年后因为人事变动,自己从辅助开发变成了”核心”开发,目前项目基本接近尾声,下面进行总结,希望对一些人能有帮助, 另外也希望iOS大牛进行指导

项目介绍

项目属于一款社区类软件,包含小组/帖子,视频,文章,评论,推荐搜索,即时通讯,好友,第三方登录/分享,推送等,涵盖常用app的基本功能

项目使用的第三方开源库

http://github.ibireme.com/github/list/ios/整理了比较常用的iOS第三方组件,以及github上的统计

项目使用了CocoaPods(类似java中的maven)管理常用的第三方库,一些特殊的单独引用,下面介绍下比较好用的几个

AFNetworking

目前比较推荐的iOS网络请求组件,默认网络请求是异步,通过block回调的方式对返回数据进行处理。

需要注意的是AFNetworking对服务器返回的ContentType要求比较严格,默认只支持application/json的返回。所以可能需要添加对text/html返回的支持,否则可能无法获得返回数据。

另外就是文件上传,这里推荐使用第二种
[formData appendPartWithFormData: name:];

[formData appendPartWithFileData: name: fileName: mimeType:];

第一种只需要传入表单名和文件流,源码也是根据文件流获得对应的文件名和文件类型,然后调用第二种方法。但是楼主遇到了使用第一种方法,提交后后台判断为非文件上传,无法获得文件流。还有如果后台是根据文件后缀文件类型,那么第一种也无法使用。

AFNetworking是异步的,也可以使用同步的网络请求方法.

FMDB

对sqlite数据库操作进行了封装,demo也比较简单

MBProgressHUD

也是iOS项目常用的一个组件,用于显示过渡效果的,比如网络请求之前显示loading,网络结束隐藏loading。建议封装在BaseViewController中,所有ViewController继承就能使用

MJRefresh

这 个是传智播客李明杰老师的作品,自己的oc基础就是看他的视频半个周末就基本拿下了。MJRefresh主要用于刷新操作,提供了常用的刷新操作,还有刷 新动画,用着很好用。建议把方法封装在BaseViewController中,这样修改刷新操作时,就只需要改动一份。(之前用的旧版 MJRefresh,只支持普通的刷新,不支持动画,后来更新后版本变化比较大,旧的方法已经不推荐使用了,所以还是封装基类中使用比较好,方便以后修 改)

SDWebImage

也 是iOS最常用的一个组件,用户加载网络图片,可以缓存到本地。大概原理时,第一次加载后,会根据url加密作为文件名缓存在本地,如果再次加载图片时, 就直接从本地加载。用着也比较简单。这里也分享遇到的一个问题,先从网络加载一张小图,然后小图作为占位图,再从网络加载一张大图
[imageView sd_setImageWithURL:[NSURL URLWithString:imageURLString] placeholderImage:DefaultPostPic];

[imageView sd_setImageWithURL:[NSURL URLWithString:_bigImageURLStringArray[i]] placeholderImage:imageView.image options:SDWebImageDelayPlaceholder completed:^(UIImage image, NSError error, SDImageCacheType cacheType, NSURL *imageURL) {

}];

RDVTabBarController

一个TabBar组件,可以方便设置底部菜单的文字图片,点击效果,小红点提示等

Toast

类似android的toast提示效果,封装在BaseViewController中,需要的地方进行提示

XMPPFramework

iOS唯一的xmpp类库,作者在去年8月份添加了xep-0198协议支持(流管理,用于xmpp断线重连),但是通过pod进行更新时,无法下载到最新版本,可能0198还没有完善好,无法作为正式版。

TPKeyboardAvoiding

用户键盘弹出自动计算高度,进行屏幕滚动操作

AMR

做即时通讯的音频处理,目前我们的即时通讯使用的录音文件是m4a,便于web端的音频播放

TQRichTextView

用于做富文本视图控件显示,用于即时通讯的表情显示,以及资源评论的富文本显示

CSGrowingTextView

用作即时通讯文本框和评论文本框使用,可以显示多行输入

MJExtension

也是李明杰老师的作品,用于json转model进行使用,有点类似于java中谷歌的Gson。转换效率据说也很高,使用也比较简单,只要前后台约定好,json直接就转成了model。一个工作多年的iOS朋友说,一个项目主要的是对model层的管理,他推荐的是Mantle。不过MJ这个更轻量级点,用着也更加简单。

工具和插件介绍

Xcode

iOS开发的官方工具,也没别的选择。有些功能做的确实挺帅的,比如StroyBoard的拖拽事件绑定。不爽的地方就是没有代码格式化,另外点击方法,可能跑到另外一个类中了!!另外左边的目录也不会自动发生变化,定位到对应文件,需要command+shift+j

SimPholders2

可以快速找到模拟器对应的沙盒目录,启动后右侧顶部工具栏有个类似关闭按键的按钮,显示最近的几个应用,点击就进入到了对应的沙盒目录

VVDocumenter-Xcode

xcode工具,///生成注解模板,xcode这功能都不给集成,唉

其他的基本就不用介绍了,有的也不怎么好用。SVN可以使用Cornerstone,Git可以使用SourceTree,sqlite可以使用SQLite Professional(不过是收费的,免费的只能查看),还可以用火狐浏览器的sqlite插件。

集成友盟

友盟,提供了App和运用的一站式解决方案。公司上个移动项目用到了友盟的推送服务,这个项目中, 还使用了分享,第三方登录的功能,自己也亲自参与到了相关集成。友盟的开发者文档还算是比较全的,遇到问题可以联系客服或者到友盟的论坛找解决方案。

关于推送

iOS 推送分为本地推送和远程推送,本地推送是指本地自己弹出信息,另外一个就是远程推送,当应用未启动时,也能收到相关推送信息。我们项目没有使用本地推送, 使用的都是友盟的远程推送。包括消息(聊天)和通知(用户信息通知)中。用户在聊天过程中,手机除了发送即时通讯以外,也调用后台接口,发送友盟推送。另 外用户的帖子,评论,关注,点赞等都会由后台调用友盟的推送。

友盟推送(另 外一个域名)包括单播,列播,和广播,其中广播限定次数每天3次,可以和友盟申请提高次数,其他不限定次数,目前来看单播速度还是挺快的。使用友盟推送, 需要在苹果开发者账号中,新建两个推送证书,提交给友盟(友盟有详细的文档,可以参考)。可以在友盟后台,把测试设备的deviceToken加到友盟推 送的后台,从友盟后台发起推送。(需要64位token,需要通过方法进行计算,直接在xcode或者ituns中拿到token不行)

推 送的大概流程就是,手机在第一次启动app的时候开启推送服务,手机在启动app的时候,注册友盟服务,同时把deviceToken提交到自己的后台, 后台可以在需要的时候拿着deviceToken调用友盟的推送接口,友盟再去发起苹果的推送服务,使对应的设备收到远程推送信息。

关于第三方登录和分享

这 块儿都在友盟的社会化分享中,里面提供了比较全面的文档。建议第三方分享模块不用自己特殊设计,可以使用友盟的默认分享模块(我们项目的分享模块自己进行 了设计,包括了收藏,所以整块都需要自定义写UI和写分享代码)。关于友盟的第三方登录和分享需要注意的时,QQ和微信登录分享,都需要手机上安装应 用,appstore审核会卡这点,所以需要判断手机是否安装应用,隐藏没有安装应用的图标,这块儿友盟的sdk已经有相关的判断方法(应该是友盟集成了 QQ和微信sdk,QQ和微信sdk提供了判断方法)。

第 三方登录分享需要到相关的平台注册开发者账号。微信开发者账号(注意不是订阅号)第三方登录需要交钱才能开通,可以支持微信和朋友圈分享。QQ开发者账号 可以支持QQ和QQ空间分享(QQ微博好像需要微博开发者账号)。新浪微博需要微博开发者账号。QQ分享开发阶段需要把测试账号加成开发者账号的好友才能 测试,微博也类似。

第三方登录自己遇到了QQ提示不是最新版的文本,在友盟论坛中找到了解决方案。

第三方登录,我们项目集成了QQ,微信,新浪微博登录。三个平台都能获得用户的screen_name(用户名称),以及对应的平台唯一的id,其中QQ和微信都是openid,新浪是userid。

第三方分享,文档提供了分享图片,视频,语音。如果是分享url,需要设置对应平台的分享地址,参考解决方案,比如
[UMSocialData defaultData].extConfig.qqData.url = shareUrl;
[UMSocialData defaultData].extConfig.qzoneData.url = shareUrl;
[UMSocialData defaultData].extConfig.wechatSessionData.url = shareUrl;
[UMSocialData defaultData].extConfig.wechatTimelineData.url = shareUrl;

另外分享到QQ空间,必须指定一张图片,否则不能分享成功。

第三方分享建议封装到一个类中,我们项目是几个详情页都有分享,评论,举报,收藏,点赞等功能。封装在一个BaseDetailViewController中的,相关页面继承,同时传入对应的资源类型,只用维护一份代码。

即时通讯

即 时通讯网上有第三方的解决方案,比如环信,融云等。我们是自己搭的xmpp服务器,服务器使用的tigase,之前写过相关的博客,自己去年也做了对应的 webim。前段时间看了环信webim的sdk,使用的也是strophe的js类库,相关实现跟我们的差不多,但是自己搭建xmpp会遇到了不少问 题,比如丢消息!所以如果想比较快速的实现im,推荐使用第三方的解决方案。

移 动端的丢消息大概是这个样子。A和B通讯,A发了一条消息给服务器,服务器发给B,但是B网络不好掉线了,而服务器却不知道B退出了(B正常退出会给服务 器发下线通知),所以消息丢失了。XMPP中有xep-0184协议(消息回执),A给B发消息,消息体中带一行代码(要求消息回执),当B收到消息后发 送一条回执,证明我收到了。后来XMPP又有了xep-0198协议(流管理),断线后快速重链,同时判断一定时间收不到消息,就把消息写离线消息,减少 丢消息情况。但是可能网络情况复杂,加上各种不确定因素,还会出现丢消息的问题。目前比较靠谱的方法就是存所有的聊天记录,由手机端根据时间点去数据库拉 消息,只要别人发出的消息就不会丢。

这 次即时通讯模块进行了相关改动,也是参考了之前开发人员的一些建议。比如用户返回home的时候,断开xmpp连接(iOS进入后台后,只有5秒的处理时 间,特殊方法可延长到10分钟,如果内存不够,应用随时就被杀死了)。所以返回home时就断开,进入应用再连接。同时应用使用状态下,有心跳检测,判断 是否保持连接。

考 虑到iOS的特殊性,我们采取了xmpp和远程推送都走的方法,推送的自定义消息体和xmpp消息体一样,消息的处理方法一样。用户聊天发送xmpp消息 的同时也调用我们的消息推送接口调用友盟push(push可以设置过期时间,避免特殊情况,推送延时,聊天结束了才收到推送)。一是解决iOS应用未启 动时的推送接收,二是解决xmpp丢消息的问题。

关 于推送,AppDelage中有两个方法,一个是使用中收到推送,不会提示,会直接处理推送信息。另外是程序非使用状态,收到推送,会进行提示,可以点击 推送消息进入应用,获取这一条推送消息的推送消息(需要注意,点击推送启动应用拿到信息时view还没有加载,消息不能立刻处理)。

android 端因为是真后台,可以后台一直保持运行,无论收到xmpp消息还是友盟推送,都可以自己进行处理,然后自己弹一个本地推送(也有弊端,如果android 程序杀死,就无法接受消息和推送)。iOS端因为后台不可控,所以推送使用远程推送,进入应用连接xmpp再收全部离线消息(不保证友盟推送能否保证及 时)。当然大部分都还是正常情况,网络情况比较好的条件下,就实时收到了xmpp的消息或者远程推送。我们又不是QQ和微信,只要保证用户看到的数据能保 持一致性就行了(所以QQ和微信就是diao啊)。

根据测试反馈的情况,iOS这个应用的丢消息情况比上个应用有一定改善。具体情况再进一步观察把。

我 们的即时通讯也包括语音和图片,采用的是http的解决方案(xmpp也支持二进制的传输,但是估计没人那样用)。具体流程就是先把附件传到附件服务器拿 到附件服务器的地址,再封装到消息体。接收方收到消息解析的时候,再从附件服务器拿到对应的资源,加载到本地。 同时屏蔽,取消屏蔽等一些实时操作也都会发xmpp,第一时间双方更新状态。

项目总结

目 前项目已经接近尾声了,再过不到半月就要上线了。自己算是项目的主要负责人了。项目前期iOS和android有一周多前期准备和框架搭建,另外就是我根 据页面原型,定义接口文档开发计划,协调开发。可能大家项目经验也都不多把,框架和接口或多或少都会有点问题,随着经验慢慢积累肯定都会越来越好的。关于 iOS的总结下:

  1. 框架搭建的时候,要考虑好App中各功能点的实现方案。设计好相关文件目录,封装相关类文件。

  2. 封装整理相关方法,比如BaseViewController中包括,基本ui,顶部导航条,左按钮,右按钮,标题,相关点击事件,显示/隐藏 loading,网络请求失败统一处理方法,上拉/下拉刷新绑定,刷新显示/隐藏。分析项目中的功能相同模块,封装对应操作,相同功能代码维护一份。

  3. 考虑好刷新机制,比如A页面进入B页面,B更新后,返回后A页面的刷新,如果采用block/delegate的方法,可以统一进行设计。或者多个页面之间的数据刷新,采用通知的方式(KVO),进行更新操作。尽量开发阶段,就把可能出现的问题提前解决。

  4. 确定是否进行相关页面统计,比如加友盟的页面统计,需要设置相关view的viewWillAppear和viewWillDisappear()

  5. ViewController中初始化view和数据请求后刷新view代码分离,封装整理好网络请求前和请求后的操作,考虑好下拉刷新页面和上拉加载更多的相关数据请求和处理。考虑有网状态下的数据缓存以及无网状态下的缓存数据加载

  6. 提前做好相关页面的跳转,代码解耦,不断优化和重构代码。发现问题或者有更好的解决方案,尽量早期就进行修改,避免修修补补,方便后期维护和扩展。在可以接受的情况下,可以牺牲一些系能,保持逻辑简单,便于维护。

  7. 通过代码写view计算坐标时,尽量参考上一个元素的坐标和宽高,这样当一个元素位置或宽高发生变化时,其他元素基本都能随着发生变化。

  8. 数据处理能放在服务器端处理就由服务器端处理,前台就进行无脑显示

  9. 考虑程序的兼容性,32位和64位一些变量的值不同,注意值的越界问题。注意程序的内存问题,和使用过程中的内存变化

  10. 考虑信息的安全性,沙盒存储的信息可以被查看修改,重要信息请加密

来自:蛙牛的博客


本文出处程序员头条:http://www.iswifting.com/2015/07/03/从Java转iOS第一个项目总结/
转载请在开头注明本文出处。

欢迎关注本站微信公众号:为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等.并不定期奉送各种福利.
微信公众号猿圈:CodePush

文章目录
  1. 1. 前言
  2. 2. 项目介绍
  3. 3. 项目使用的第三方开源库
    1. 3.1. AFNetworking
    2. 3.2. FMDB
    3. 3.3. MBProgressHUD
    4. 3.4. MJRefresh
    5. 3.5. SDWebImage
    6. 3.6. RDVTabBarController
    7. 3.7. Toast
    8. 3.8. XMPPFramework
    9. 3.9. TPKeyboardAvoiding
    10. 3.10. AMR
    11. 3.11. TQRichTextView
    12. 3.12. CSGrowingTextView
    13. 3.13. MJExtension
  4. 4. 工具和插件介绍
    1. 4.1. Xcode
    2. 4.2. SimPholders2
    3. 4.3. VVDocumenter-Xcode
  5. 5. 集成友盟
    1. 5.1. 关于推送
    2. 5.2. 关于第三方登录和分享
  6. 6. 即时通讯
  7. 7. 项目总结