2011.4.20,风和日丽的一天。两个年轻人蹲在海淀黄庄地铁站外,决定以独立开发者的形式去App Store淘金。我指着中关村大厦对Yan说“等咱有了钱…”“把这楼买下来?”“在北京买套房子…”“OK开搞…”
一晃小三年过去了,买房、结婚,我也有了小孩。合作关系结束了,我们也实现了当时的目标。但对于北漂来说,只是个好的开始。我跟他说过“少个合伙人,多个朋友,不亏”,希望Yan和他的家人都好。
算下来一共三十个月,共获得了1750万下载量,App Store给全世界的开发者提供了一个前所未有的舞台。跟同年龄的朋友比,我们是幸运的。在这个过程中,得到了很多朋友的帮助。可能你们根本不认识我们,或者素未谋面。我读你们的博客,学习你们的代码,甚至冒昧的直接发邮件或者打电话过去。没有你们的帮助,我们不可能做到这些。
App Store的独立开发者经历,对我是非常宝贵的。验证了自己的一些想法,也学习了很多Human Nature的东西。对于工程师来讲,世界的运转就是抽象的0和1,其实不(完全)是这样的。技术和积累往往是线性的,但人生的感悟却是阶跃式的。
这三年来,离职、“创业”;结婚生子、买房装修。感谢老婆,一生有你。最近这十八个月,一直不在北京,在福建的一个五线城市陪伴家人。一个朋友对我说“你错失了移动互联网最黄金的一段时间”。他说的可能是对的,可能不是,但我不后悔。一直以为,我的天花板不够高,这两年就算是一个高原期吧。我相信付出终有回报,只不过在时间点、形式上有所差异吧。
Yan去做了新的事情,IndieBros Studio变成了我的one man show。IndieBros Studio还会继续存在,但我会只拿出5%的精力来打理它。下个月就回京了,不知道北京的雾霾怎么样了?质量好的话,我就省掉了烟钱:)
最近一直在思考新一年的职业规划。顺便问一下?需要小二么?

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog。
产品经理版本
后台获取
- App进入后台后,可以主动发起获取数据请求,时长30秒
- 频率和时机受iOS调度,不能做到完全确定
- 常与后台传输服务结合使用
- 用例:社交网络应用,每隔一段时间获取最新文本内容、缩略图
远程(推送)通知
- 由server发起,可以远程唤醒App执行后台任务,时长30秒
- 技术上是一种静默的远程推送,用户不知情
- 频率受苹果控制,不能滥用
- 常与后台传输服务、本地推送结合使用
- 用例:服务器向视频、杂志应用订阅用户发送通知,后台静默下载,用户打开应用时即显示最新内容
后台传输
- 常与前两种结合使用,也可单独使用
- 传输时机受iOS调度,不能做到完全确定;iOS设备电量较好(高电量或接入电源),并连接WiFi时运行的可能性较高
- 适用大文件传输,没有运行时长限制
- 用例:云存储同步、视频订阅后后台下载
工程师版本
Background Fetch
- Info.plist, Required background modes key添加fetch value
- 设置最短fetch间隔:默认是
UIApplicationBackgroundFetchIntervalNever
,如果改变此值将永远不会fetch;UIApplicationBackgroundFetchIntervalMinimum
是可以设置的最短间隔;另外可以设置一个NSTimeInterval类型的值。无论作何设置,都只是建议,不作保证,最终的fetch间隔由OS决定。
- 实现
application:performFetchWithCompletionHandler:
。completionHandler需要一个UIBackgroundFetchResult
类型的参数,告知OS三种情况:NewData/NoData/Failed。BackgroundFetch的超时限制是30秒,如果需要超出此限制,需要使用Background Transfer Service API。
- 两种模拟Background Fetch的方法:一种通过Simulator菜单;另一种通过Xcode->Scheme,选中Launch due to a background fetch event选项。
- 限时30秒
Remote Notifications
- Info.plist, Required background modes key添加remote-notification value
- Notification Payload: 添加
{content-available: 1}
键值对
- 实际上是Silent Push Notifications,可以远程唤醒应用来处理远程推送通知,用户并不知情。
- 典型的use case: Remote Notifications静默通知app有新的内容,app初始化一个Background Download Task,完成后以Local Notifications的形式通知用户有新的内容。
- 与Background Fetch的区别:Background Fetch由客户端主动发起,由OS调度,适合高频率请求;Remote Notifications由server发起,受apns server控制,适合并不频繁的内容更新。
- 实现
application:didReceiveRemoteNotification:fetchCompletionHandler:
。之后的处理与Background Fetch类似。
- 限时30秒
Background Transfer Service
- 基于NSURLSession,支持HTTP/HTTPS,由OS调度
- 实现
application:handleEventsForBackgroundURLSession:completionHandler:
方法。
- discretionary/non-discretionary: 如果
discretionary==YES
,则更可能在设备电量良好且有WiFi连接时被执行,后台运行的NSURLTask此值必须为YES。
- 不限传输时长
Reference
附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog。
NSURLConnection大概有10年的历史了,很多api的设计都比较陈旧,否则AFNetworking不会这么火。好在苹果在iOS 7/Mavericks 引入了新的网络类NSURLSession,用以替代NSURLConnection。
新的网络框架设计中,原有的NSURL/NSURLRequest/NSURLResponse这些类及相关概念都得以沿用;除了支持iOS 7的一新新特性(background download/upload),与AFNetworking 1.x很多api设计非常相似。
NSURLSession
- Foundation中NSURLConnection的替代
- 支持后台运行的网络任务
- 暂停、停止、重启网络任务,不再需要NSOperation封装
- 请求可以使用同样的配置容器中
- 不同的session可以使用不同的私有存储
- block和委托可以同时起作用
- 直接从文件系统上传下载
NSURLSessionConfiguration
- defaultSessionConfiguration - 缓存、cookie、证书全局非私有;近似于NSURLConnection
- ephemeralSessionConfiguration - 缓存、cookie、证书全局私有但非持久化(in memory)
- backgroundSessionConfiguration - 适合于应用被挂起或收到remote notification
NSURLSessionConfiguration的一些properties
摘录一些常用的:
- HTTPAdditionalHeaders: HTTP协议头部信息
- allowsCellularAccess/discretionary: 前者允许运营商网络/后者对于后台网络任务进行优化(有WiFi/设备电量情况好的时候)
- timeoutIntervalForRequest/timeoutIntervalForResource: 前者每次有新data到达时重置;后者限制了整个资源请求时长,不要搞混了
- HTTPMaximumConnectionsPerHost: 对于一个host的最大并发连接数
NSURLSessionTask
继承关系如图(image from objc.io)

- 可以发送cancel/resume/suspend消息
- NSURLSessionDataTask - 返回NSData
- NSURLSesssionDownloadTask - 返回(临时)文件,下载进度可以恢复
- NSURLSessionUploadTask - 上传NSData/File/Stream
- Task默认都是挂起的,记得要向task发resume消息
最后附上NSURLConnection to NSURLSession delegate methods Mapping Table by Mattt Thompson
Reference:
附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog。

从iOS 6开始,App Store就支持增量更新。增量更新只支持App Store,对企业开发者的Adhoc更新无效。增量更新对于开发者以及用户都是透明的。但我们需要理解其中的机制。iOS 6与iOS 7的机制又有所不同。
感谢@洪亮狗豆_车内逃脱的总结:iOS 6是rysnc机制,iOS 7是diff机制;后面都是我的啰嗦文字,不看也罢= =
iOS 6的增量更新
对于更新app的用户,App Store会提供一个增量安装包。这个增量是文件级别的,如果两个版本中有新加入的文件则增加;有修改的文件则修改;有删除的文件就移除(我用不用说得这么啰嗦)。用diff就可以判断文件是否被修改,并且苹果建议不要依赖于文件的创建时间及修改时间。
iOS 7的增量更新
iOS 7的增量更新更智能。假如有一个文件是10MB,只修改了1 bit:
- iOS 6下会更新10MB
- iOS 7下只会更新该文件变化的部分
iOS 7的好处是最大化地降低了更新包的大小,但会增加安装的时间。
Reference: QA1779
附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog。