JSPatch 平台介绍

2016-3-10 评论(4) 分类:作品

JSPatch 是一个 iOS 开源项目,只需在项目中引入极小的引擎,即可让 APP 拥有实时修复 bug 以及动态运营的能力,目前已得到广泛应用,据年前统计,已经有 1200+ 个 APP 接入 JSPatch。

JSPatch 的使用需要后台下发脚本,需要搭建后台,对脚本进行版本管理和分发,这对于很多中小 App 来说是很麻烦的事,很多小 App 甚至没有后台。另外 JSPatch 脚本权限很大,对于脚本的下发还需要考虑好安全问题,否则会有安全隐患。这导致 JSPatch 使用的门槛有点高。

JSPatch 平台 (http://jspatch.com)就是为了解决这个问题的,它可以让开发者无需自己搭建后台,也无需考虑安全问题,只需在平台注册上传脚本,App 接入 SDK 即可使用 JSPatch 为自己的 App 提供动态能力,降低 JSPatch 的使用成本。

接入 JSPatch 平台 SDK 的 App 需要在每次启动或每次唤醒时访问服务器询问是否有脚本更新,这些请求汇集到一个平台上后平台的请求量和流量都会很高,对服务器的性能和并发要求也很高。JSPatch 平台把脚本的分发逻辑转为静态文件,架构在七牛云存储上,云存储在分发静态文件上是高并发高稳定性的,所以平台在性能上没有问题,可以支持任意用户数的 App 接入并保证稳定性。

解决了服务器性能问题,还有资源消耗的问题。大量的请求会消耗不少云服务资源,而这些资源并不是免费的,需要有一定的投入。所以去年做完平台后一直没有开放注册,而是通过发邀请码的方式控制用户数量,也就一直没改进和推广。随着 JSPatch 的发展,近期还是想放开注册,同时想做一个尝试:收费。学习各个云平台,提供一定免费额度,超出的再按服务器的成本价收费,解决资源消耗问题。收费上简化为只对请求次数收费,无视带宽/存储/流量,实际上计算出来的费用是很低的,并且免费额度也足够支撑大部分 App,应该很容易接受,具体可见这里

欢迎试用 JSPatch 平台,有问题可以直接邮件 bang590@gmail.com

JSPatch – 动态更新iOS APP

2015-5-25 评论(51) 分类:作品 技术文章 Tags:

JSPatch是最近业余做的项目,只需在项目中引入极小的引擎,就可以使用JavaScript调用任何Objective-C的原生接口,获得脚本语言的能力:动态更新APP,替换项目原生代码修复bug。

用途

是否有过这样的经历:新版本上线后发现有个严重的bug,可能会导致crash率激增,可能会使网络请求无法发出,这时能做的只是赶紧修复bug然后提交等待漫长的AppStore审核,再盼望用户快点升级,付出巨大的人力和时间成本,才能完成此次bug的修复。

使用JSPatch可以解决这样的问题,只需在项目中引入JSPatch,就可以在发现bug时下发JS脚本补丁,替换原生方法,无需更新APP即时修复bug。

例子

@implementation JPTableViewController
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *content = self.dataSource[[indexPath row]];  //可能会超出数组范围导致crash
  JPViewController *ctrl = [[JPViewController alloc] initWithContent:content];
  [self.navigationController pushViewController:ctrl];
}
...
@end

上述代码中取数组元素处可能会超出数组范围导致crash。如果在项目里引用了JSPatch,就可以下发JS脚本修复这个bug:

#import “JPEngine.m"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [JPEngine startEngine];
    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cnbang.net/bugfix.JS"]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSString *script = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (script) {
      [JPEngine evaluateScript:script];
    }
}];
   ….
    return YES;
}
@end

//JS
defineClass("JPTableViewController", {
  //instance method definitions
  tableView_didSelectRowAtIndexPath: function(tableView, indexPath) {
    var row = indexPath.row()
    if (self.dataSource().length > row) {  //加上判断越界的逻辑
      var content = self.dataArr()[row];
      var ctrl = JPViewController.alloc().initWithContent(content);
      self.navigationController().pushViewController(ctrl);
    }
  }
}, {})

这样 JPTableViewController 里的 -tableView:didSelectRowAtIndexPath: 就替换成了这个JS脚本里的实现,在用户无感知的情况下修复了这个bug。

更多的使用文档和demo请参考github项目主页

原理

JSPatch用iOS内置的JavaScriptCore.framework作为JS引擎,但没有用它JSExport的特性进行JS-OC函数互调,而是通过Objective-C Runtime,从JS传递要调用的类名函数名到Objective-C,再使用NSInvocation动态调用对应的OC方法。详细的实现原理以及实现过程中遇到的各种坑和hack方法会另有文章介绍。

方案对比

目前已经有一些方案可以实现动态打补丁,例如WaxPatch,可以用Lua调用OC方法,相对于WaxPatch,JSPatch的优势是:

1.JS语言
JS比Lua在应用开发领域有更广泛的应用,目前前端开发和终端开发有融合的趋势,作为扩展的脚本语言,JS是不二之选。

2.符合Apple规则
JSPatch更符合Apple的规则。iOS Developer Program License Agreement里3.3.2提到不可动态下发可执行代码,但通过苹果JavaScriptCore.framework或WebKit执行的代码除外,JS正是通过JavaScriptCore.framework执行的。

3.小巧
使用系统内置的JavaScriptCore.framework,无需内嵌脚本引擎,体积小巧。

4.支持block
wax在几年前就停止了开发和维护,不支持Objective-C里block跟Lua程序的互传,虽然一些第三方已经实现block,但使用时参数上也有比较多的限制。

相对于WaxPatch,JSPatch劣势在于不支持iOS6,因为需要引入JavaScriptCore.framework。另外目前内存的使用上会高于wax,持续改进中。

风险

JSPatch让脚本语言获得调用所有原生OC方法的能力,不像web前端把能力局限在浏览器,使用上会有一些安全风险:

1.若在网络传输过程中下发明文JS,可能会被中间人篡改JS脚本,执行任意方法,盗取APP里的相关信息。可以对传输过程进行加密,或用直接使用https解决。

2.若下载完后的JS保存在本地没有加密,在未越狱的机器上用户也可以手动替换或篡改脚本。这点危害没有第一点大,因为操作者是手机拥有者,不存在APP内相关信息被盗用的风险。若要避免用户修改代码影响APP运行,可以选择简单的加密存储。

其他用途

JSPatch可以动态打补丁,自由修改APP里的代码,理论上还可以完全用JSPatch实现一个业务模块,甚至整个APP,跟wax一样,但不推荐这么做,因为:

  1. JSPatch和wax一样都是通过Objective-C Runtime的接口通过字符串反射找到对应的类和方法进行调用,这中间的字符串处理会损耗一定的性能,另外两种语言间的类型转换也有性能损耗,若用来做一个完整的业务模块,大量的频繁来回互调,可能有性能问题。
  2. 开发过程中需要用OC的思维写JS/Lua,丧失了脚本语言自己的特性。
  3. JSPatch和wax都没有IDE支持,开发效率低。

若想动态为APP添加模块,目前React Native给出了很好的方案,解决了上述三个问题:

  1. JS/OC不会频繁通信,会在事件触发时批量传递,提高效率。(详见React Native通信机制详解
  2. 开发过程无需考虑OC的感受,遵从React框架的思想进行纯JS开发就行,剩下的事情React Native帮你处理好了。
  3. React Native连IDE都准备好了。

所以动态添加业务模块目前还是推荐尝试React Native,但React Native并不会提供原生OC接口的反射调用和方法替换,无法做到修改原生代码,JSPatch以小巧的引擎补足这个缺口,配合React Native用统一的JS语言让一个原生APP时刻处于可扩展可修改的状态。

目前JSPatch处于开发阶段,稳定性和功能还存在一些问题,欢迎大家提建议/bug/PR,一起来做这个项目。

(更多…)

XReminder

2014-3-29 评论(1) 分类:作品

XReminder

XReminder是一个iPhone上的提醒工具,解决了快速添加提醒、稍后提醒的需求。

功能

这个APP的需求源于我自己,iOS自带的提醒工具要设个提醒十分麻烦,首先要在列表上添加一个todo->进入详情->开启“在指定日期提醒我”->点击提醒时间->选择时间->如果是重复事件再点击重复选项进入选择,这才完成一个提醒。

所以我做了XReminder,简化添加提醒的步骤,并加入我需要的其他功能。XReminder添加提醒很简单,下拉列表->输入标题->选择时间->完成,其中时间有On, After, Every三种:

On:具体时间提醒,没啥好说
After:指定时间段后提醒,例如想设置一个小时后提醒的事件,选择After再选1 hour就完成了。
Every:重复提醒,可以设每天/每周/每月/每年重复提醒

还有一个重要的功能,就是提醒时间到时有稍后再提醒的功能。我比较健忘,我用原生的提醒APP时,提醒时间到手机响后我看了一眼,如果那件事不是立刻就可以完成的,十有八九接下来我就又把它忘了,因为接下来不会再有提醒了。例如下班要带XX东西回家,提醒的时候还没能走,走的时候就又忘了这回事。我需要在我设置的提醒时间跟现实对不上的时候可以方便地让它稍后再提醒一下。XReminder就实现了这个功能,可以选择XX分钟后再提醒一次。

另外如果是一件很重要的事,提醒一次不够,一定要你看到并确认知道了才取消提醒,可以在新建任务的时候就设成snooze任务,时间到后每隔一分钟就会响一次,直到你打开APP点击DONE。

交互

整个APP就是垂直方向的上下拉动,上方是新建任务,中间是主列表,下方是设置。

添加提醒时向下拖动可以改变提醒条的颜色,这个本来是难以发现的,但在第一次使用时做了引导,第一次添加提醒时会遮罩提醒这里可以往下拖动改变颜色,只有用户拖了改变了一次颜色,这个提醒才会消失。

列表上左右拖动会出现编辑和删除按钮。左右拖动这个操作比较难发现,需要加以引导,所以点击列表时列表的元素会左右抖动一下提醒用户这个色块左右是松动的,可以试试拖动。

每个提醒主要显示了标题和剩余时间,右下角小字显示具体的提醒时间,包括重复的提醒时间的清楚表述,例如”Every Monday 10:00”。

设计

设计上,整个APP都是色块设计,看起来比较轻盈(实际上是这样比较容易做,我不会设计纹理)。按钮点击、上下切换视图和左右滑动都有声音配合。键盘和日期选择还是iOS6的风格,没有换成iOS7是因为iOS7的日期选择太丑了,更重要的是它没法选择控件字体的颜色,还没想到好的方法融入iOS7。

伊书

2012-6-10 评论(56) 分类:作品

伊书是一款追求最佳阅读体验的iPhone电子书阅读APP,可以通过开放书库获取海量书籍资源。

主页:http://yishu.cnbang.net
iTunes地址:http://itunes.apple.com/cn/app/id532812695?mt=8

3月开始在业余时间里断断续续做这个APP,5月22号提交AppStore,历经19天终于通过审核上线了,审核过程的曲折让我以为上不了线了,真不容易。

为什么做?

  • 要是一段时间我什么东西都没做出来,我会感到很不安。
  • 开发一个APP这个小愿望存在已久,用上了iPhone,有了macbook,不去实现说不过去。
  • 苦闷的生活中,它可以带来一些乐趣和一点希望。
  • 找回按自己意愿编程的感觉。
  • 喜欢创造的过程和结果。

伊书是一款epub电子书阅读软件,现在iPhone上类似的APP很多,为什么还要再做一个?因为阅读APP自己用得多,现有的APP不能满足我全部需求,所以做了。相对于其他APP有什么特色?老实说目前没有大的特色,在交互和细节上花了挺多心思,例如记录阅读时间,上拉页面查看阅读进度,仿纸质的滑动菜单和目录等。第一版做出基本功能,后面再发挥。

做个APP对我来说最大的困难就是设计了,因为设计我不在行,所以想得挺辛苦,速度也慢,花在设计上的时间估计占了有1/3,最后图标和阅读背景做得不好,但暂时做不出更好的,先这样了。

感谢以下开源项目:

ASIHTTPRequest 应该大部分用到HTTP的项目都会用它
MBProgressHUD loading菊花,简单易用
FMDB 简化数据库操作
SMXMLDocument / HTMLParser 简单封装了XML/HTML解析
EGOImageLoading EGOTextFieldAlertView enormego是天使般的公司,开源了很多好用的东西,接下来的新版本还需要继续学习和使用它的开源项目

伊书 – 苏菲的世界

2011-12-7 评论(8) 分类:作品 Tags:

伊书 – 苏菲的世界

介绍

距上次我在新浪微博发”I got an idea“已经过去快一个半月了,现在终于把这个idea完成了。

其实也不算idea,只是想认真地做一本针对iOS的电子书,webApp方式,最好精致点,取名伊书。

伊书是电子书,一本书一个APP,用webApp方式实现,打开浏览器,添加到屏幕,即可完成整本书的下载,随时离线浏览。伊书有以下特点和功能:

  1. 最基本的点击左右两侧滑动翻页
  2. 手指滑动拖动页面,在低版本的iPhone上性能会差一点,iPhone4以上较流畅
  3. 注释功能,点击正文上的注释按钮显示注释内容。
  4. 底部红条显示当前章节的进度,按住可以显示页码,拖动可以快速翻页。
  5. 夜间模式
  6. 排版:
    iOS5以上支持左右对齐的justify排版,iOS4以下不支持。
    书信开头的左顶格,落脚的右对齐,引用内容的。
    标点悬挂,将出现在行首的标点提前到上一行末。
  7. 当然它是离线的

历程

想起2001年有个网站叫E书时空(这个网站竟然还存在),提供电子书下载,一本一个exe文件,设计良好,很喜欢。想来我特别喜欢那种包装起来成一个完整个体的东西,像一本本电子书,一个个iPhone APP,还有一个个完整的FLASH游戏。像我以前做的Q版海底俄罗斯这个FLASH游戏,特别喜欢打造这样一个完整东西的感觉。

我是看到“唐茶”才想起这些的,非常喜欢唐茶这样的APP,很有苹果的风格,阅读体验上追求完美,确实是阅读新境界。手机阅读随时随地,我自己也在手机上读了不少书,自身需求较大,我想用自己的方式去实现一个。我没见过有人用web的方式做这样的电子书,算是实验尝试,也算是自娱自乐的项目。

第一本书我选择了《苏菲的世界》,觉得它很好,以非常轻松的方式让人了解整个科学哲学史。这部书原版出版于1991年,按理来说至今20年已经没有版权问题了,但翻译的版权还是存在的,所以这还是算盗版吧。整本书的内容是在网上找的,内容有非常多的错误,我见到的都一一修改了,光改内容已经花了我很多时间,相信这是网上能得到的版本最好错误最少的《苏菲的世界》。

工作后做业余项目真是不容易,时间太少,娱乐时间大部分都贡献出来了,有时是乐在其中,有时不得不去做琐碎的事情,不得不去做不擅长的设计,也是有点辛苦的。设计对我来说是个难题,设计的过程是憋出来的,一点点试出来,比较痛苦,很想自己的设计能力能提高,但很难,也很想跟好的设计师合做一个产品。

这个产品从80%到100%花了挺长时间,产品发布的页面都做了,还有在safari打开时针对高清屏的优化,总的来说,这次还是比较用心的。这样的产品,做出来感觉很快乐,但如果有人用,可以增加百倍的快乐,希望有人会喜欢吧。

iPhone webApp缺陷

苹果对webApp支持力度较大,在移动端对HTML5,对webApp支持得最好的就是iOS了,但它还是有很多缺陷。

  1. 无法阻止屏幕旋转
    只能做一个在旋转到横屏时提示“不支持横屏”的提示。
  2. 无法正常切换任务,一切换就重刷页面
    原生APP从后台切回来直接恢复状态,webApp跟iOS时代的APP一样,一切走,再切回来,就是重启应用。
  3. 不能调节亮度
    这个还可以接受,只是在阅读时比较需要这样的接口。
  4. 图标和开启页面无法使用manifest缓存
    manifest无法管到APP的图标和启动图片,每次打开应用都会去请求这两张图片。
  5. 头部状态栏无法去除
    少了一些宝贵的显示空间
  6. 性能
    iPhone4S上性能给力很多了。但是,原生APP可以流畅实现更炫的效果时,webApp不过是刚好能实现简单效果。

即连

2011-6-3 评论(9) 分类:作品

jilian

即连是一个与好友实时连接进行游戏或做其他有趣事情的网站。目前处于试验阶段,只有“陆战军棋”和“五子棋”两个游戏。http://jilian.cnbang.net

下面是啰嗦的制作过程。

在大学最后一个学期开始之前在想毕业论文要做什么题目,我想把毕业论文做成我大学最后一个作品,能发布在网上的成型产品。后来研究了一下node.js,还有Socket.IO,觉得用它来搭建实时通信的游戏挺有趣,就做了类似QQ游戏大厅那样的东西,套上以前做的“陆战军棋”,实现了军棋在线对战。它的优势是跨平台,在各种系统上都能玩,只要有浏览器。

一开始的实现跟QQ游戏大厅一样,需要注册用户,进入游戏后有很多个座位,点座位进去后按准备,对方也是准备状态的话就开始游戏,游戏中可以求和、逃跑、认输、重新开始,有不同的积分。这一系列都实现好了,论文也照着这个写了。

然后有一天突然觉得,玩个游戏用得着这么繁琐么,想修改成一进入就马上开始游戏,不用一系列操作。于是把之前做的都抛弃了,改成不用注册用户,用微博帐号登录,进入游戏后有随机模式和邀请模式,随机模式点完后只要有人也处于随机模式就能马上开始游戏。邀请模式是发链接或发微博给朋友,他进来后自动与你开始游戏,游戏中可以要求重新开始活换个人开始游戏。没有别的了。帐号的积分等东西想以后慢慢再完善,先做出个可用的完整的东西。随后对战的游戏增加了五子棋,因为可能陆战军棋对很多人都很陌生。产品名字想了挺久最后叫“即连”,即时连接好友交流,最主要的就是“连接”,连接的形式不一定是游戏。

完成后买了个便宜的VPS放上去,由于是国外的速度挺慢,只是刚好到“能玩”的地步,修复各种bug后现在偶尔还会出现错误,对node.js的了解不深入,node.js以及框架express都处于开发状态,还未到真正稳定投入生产的状态,会有一些版本问题出现,比较麻烦。开发过程中写代码的效率挺低,好像挺难集中精力一口气写完,杂事又多,做这个东西拖了挺长时间的。

在最近突然发现,这个东西用微博登录,webQQ直接有微博接口,那做成webQQ应用的话可以不用登录直接玩了,于是增加了webQQ的支持,放了上去,还在审核。

待网站可以稳定运行后想做多几个应用,可以是两个人一起画画什么的,目前还没想清楚。对这个网站,目前不知道怎么宣传~

新浪微博node.js SDK

2011-4-5 评论(2) 分类:作品 Tags:

最近用node.js做东西,要连接到新浪微博,就写了这个新浪微博node.js SDK:node-weibo-oauth,其实这应该叫库不该叫SDK吧,但官方文档里这样写我也跟着这样写了。

用了node-oauth,就是node.js的OAuth库,但我折腾老半天才会用这个库,它只支持header认证,腾讯微博目前不支持header认证,就没弄腾讯微博了。

测试这个OAuth认证时我一直盯着新浪这个教程看,结果被误导了,怎么弄都是认证完后只给授权码不跳转到callback地址。弄了很久才发现原来是要把callback地址传给oauth/authorize,我还以为只传给request token就行了,这个教程也是这么写的,为啥这里不说清楚呢,搞不懂,浪费挺多时间。

腾讯微博活跃听众检测

2010-12-25 评论(4) 分类:作品 Tags:

用一个下午的时间快速开发了一个腾讯微博小应用,叫“腾讯微博活跃听众检测“,我想知道我的听众(follower)有多少人是真正在用这个微博的,所以做了这么个东西。

目前是采取这样的方法判断某个用户是否活跃用户:如果3天内没有更新微博,直接拍死。否则会根据最后一条微博的更新时间、微博发送来源(很多只是单纯从QQ空间QQ签名同步过来)、听众数和收听人的比例这三个信息进行评分判断,具体可以看下网页源码,判断这部分逻辑是js写的。当然目前这样简单的计算方法不会那么准确,只能知道个大概。

因为想快速完成,页面也不怎么美化了,也不伺候ie用户,这个页面在ie下会比较丑。

腾讯微博API拉听众列表每次只能拉30人,不给力啊,只能循环一次次地去拉。现在限制最大检测听众数是1020人,就是拉上1020/30=34次。因为服务器放在国外,腾讯在国内,拉取数据会比较慢,耐心等等~

这是我检测的数据:已检测1020个听众, 活跃用户258人, 不活跃用户762人, 活跃率25%

没对比过其他微博,不知道25%的活跃率是怎样的水平,我觉得是非常低了。

新浪微博版twitese

2010-8-14 评论(10) 分类:作品 Tags:

sina_twitese

架设网址:http://cnbang.net/sinatwitese

项目主页:http://code.google.com/p/sinatwitese/

几个月前新浪微博找我做个实现微博所有功能的开源PHP客户端,换句话说就是把twitese改成用于新浪微博,但这样似乎没什么用,新浪微博又不用翻墙上,何必用到第三方网页客户端呢,想想可能是因为要有个微博应用的代码示例。

结果我花了点时间做出来,比较麻烦的是新浪微博的评论,下了挺多功夫的,其他都差不多,当时做到基本可以用了:

后来新浪的人有尝试修改一下外观,然后又很长一段时间毫无动静,我问了后才被告知他们不用这个了,打算自己写一个了,可能发现太难修改界面了,代码里还残留有很多twitter的东西,还不如自己写个效率高。于是我这个东西就无声无息地被埋葬了,现在掘出来晒晒太阳。

iphone webapp:模拟tweetie

2010-7-3 评论(2) 分类:作品 Tags:

img_0026

地址:http://cnbang.net/lab/tweetie (桌面浏览器只支持safari/chrome)

IPhone Safari不支持position:fixed,这点很麻烦,一般读取内容的app都是头部和尾部固定,中间内容滚动这样的形式,而在web上没有了postion:fixed这个功能就没法这样做了。有人针对这个问题做了hack,iScroll做得很好,效果很平滑,甚至连旁边的滚动黑条都模拟了,还支持android和桌面浏览器,真是好东西。想拿它做个东西试试。

想实现tweetie里拖动刷新推的效果,于是对iScroll进行了小小修改,options里增加了edge参数,即设置哪里是边界。再用自家的iquery开始试着实现。

实现过程发现IPhone Safari性能还是挺差,一不小心就会变得很卡,例如:
1.头部放个会动的loading图片就会让整个滚动变得很卡,不得不去掉换成不动的loading图。
2.头部箭头翻转如果设置了动画转动,就会卡大约半秒才开始转动,不得不去掉这个效果。

结果现在的效果并不好,拖动刷新的过程没有原版tweetie那么流畅,不知还有没有优化的空间。

做这样内容式的webapp相对于原生APP来说,除了性能差点,还有一个缺点,就是webapp无法直接获取远程数据(跨域问题),除非用jsonp,像获取twitter数据这些,得在本地搭个类似代理才行,多了个服务器流量。

没有android可以测试这个应用,不过应该是支持android的~要是tweetie没被twitter收购,这东西可能还有做下去的价值,现在似乎就没啥价值了,就不继续做下去了~只是演示下效果。

另,在IPhone/ITouch上webapp真是二等公民,实在没法跟原生APP相比,不知道在IPad上情况怎样,有机会真想试试~