如何动态调用 C 函数

2016-7-5 评论(13) 分类:技术文章 Tags:

JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用:

require('JPEngine').addExtensions(['JPCFunction'])
defineCFunction("malloc", "void *, size_t")
malloc(10)

我们一步步来看看怎样可以做到动态调用 C 函数。

函数地址

首先若要动态调用 C 函数,第一步就是需要通过传入一个函数名字符串找到这个函数地址,这里一个必要的前提条件就是 C 编译后的可执行文件里必须有原函数名的信息,才有可能做到通过函数名字符串找到函数地址。我们写个简单的程序来看看它编译后可执行文件的内容有没有这个信息:

//main.m
void test() {
}

int main() {
  return 0;
}

编译这个文件,并用otool看下它的汇编:
(更多…)

北京之旅

2016-6-29 评论(5) 分类:生活

前几天受邀去北京一个技术分享会 GMTC 分享 JSPatch 相关内容,记录一下这次旅程。

分享

这次在 GMTC 分享的主题是 JSPatch 成长之路,PPT现在可以在[这里]看到,视频等后面出来了再补上。主要分享了 JSPatch 一开始碰到的一个难题,在发展过程中怎样完善补全周边功能,以及下一步计划。这是我第一次对外做分享,作为一个非常容易紧张的人,这第一次上台分享时竟然一点也不紧张,出乎我意料,当时在台下等待时还挺紧张,上了讲台后就很放松了,可能因为准备得比较充分,现场也没出现什么意外,都在把握之中吧,状态很好,分享效果感觉也还不错。

关于线下演讲分享和线上文章分享,我一直觉得技术领域要学东西的话线上文章分享是最好的形式,一是它传播广,触达用户多;二是耗时少,写一篇文章或看一篇文章都比听一个分享花的时间少很多;三是可沉淀,读者可以反复看细节,可以沉淀下来不断被人搜索到。

这次分享后我观点没有太大变化,但我也体会到了线下分享的好处,对分享者来说可以展示个人魅力,提升沟通能力,更有动力去认真准备内容,能比写文章更好地梳理自己的思路。对听众来说可以得到分享者这份精心准备的内容,同时可以面对面沟通交流,得到更多信息。当然更重要的是可以认识多些人。相对来说分享者得到的好处会更多些,我就觉得这次分享我自己收获挺多。不过线下分享无论是分享者和听众,时间成本都很高,而且收益会随着参加次数增多而减少,第一次的收益应该是最高的,后面参加多了可能就没什么帮助了,个人觉得不应该频繁参加。

在台下听了一些分享,印象比较深的是覃超的《Facebook iOS App技术演化十年之路》,讲 Facebook 客户端演进的过程,技术选型犯的错误和原因,反思世上没有能一次性解决所有问题的技术,跨平台是个陷阱,它要付出很多代价,牺牲很多东西,导致效果不佳,效率和效果是一种权衡,应该面向用户开发而不是面向工程师。其他精彩分享篇幅有限这里就不多说了,在[这里]都可以看到。

沙龙

这次顺便也参加了一个iOS开发者沙龙,T技术沙龙,跟会议分享不同的是只邀请少数人,鼓励多进行沟通交流,台上演讲分享只是辅助开启话题,这个有点像公司内部分享,还挺不错,跟多人大会比起来各有好坏吧,优点在于这样的交流更有效率,可以交流到更细节的东西,缺点在于分享不会那么精心准备,也就没有前面说的那些好处,另外因为更注重双向交流,效果好不好得看参会的人怎样。

在沙龙同样分享了 JSPatch,交流比较多,大家也提出了很多自己的看法,第二场sunny分享了《Calling Conventions》,阐述一个函数在汇编层面是怎样被调用的,objc_msgSend 的实现,最后还分享了一个 swift 理论上可行的方法替换的实现方式,十分黑魔法,但前提是得越狱,很赞的分享,长了见识。第三场因为有约就提前走了,小有遗憾。

北京

距上次来北京已经时隔五年多了,再次踏入北京的感觉有点亲切和怀旧,感叹时间过得越来越快,现在一回忆起什么事来动不动就是五年前十年前。当时在百度实习三个月,对北京的印象挺好,可能是待的时间短还没来得及看到它不好的地方,没碰到过大雾霾的天气。给我的感受北京跟广州最大的不同是人的多样性,这里汇集了全国各地的人,不同性格不同背景不同经历的人互相交流进步,而且北方人(广东以北的人)大多性格外向豪爽,跟他们聊多了自己也会变开朗些,很有意思。

跟前同事聚了下,五年来大家外貌似乎一点都没变,就是各奔东西了,有的在百度继续发展,有的跳到中小公司,有的创业,境况不一样,有的公司上市了,有的公司下滑严重,北京选择机会多,风险也大,谁能想到如日中天的一家公司说跌落就跌落,看起来一般般的公司说上市就上市,人生啊,不过大家还得工作几十年,机会多得是。

这次过来见到了很多之前只在网上交流过的朋友,有些跟网上交流感觉一致,有些很有气场,有些很有亲和力萌萌的哈哈,也认识了不少新朋友,很感谢这次各路朋友们的热情招待,非常愉快的一次旅程~

浴室沉思

2016-5-30 评论(8) 分类:随记

对于使用的东西,便捷性是比功能性更重要的,雨伞是最好的例子,下雨拿雨伞下半身还是会被淋一身,功能上并不完整,雨衣在这方面更胜一筹,能保证大部分部位不会被淋到,若再发明一种把脚也包起来的雨衣就更完美了,但这些永远做不到雨伞那样流行,因为雨伞非常方便,大家都宁愿为便捷性牺牲一些功能。

互联网影响了音乐/文学/游戏,音乐免费了,音乐人卖不了唱片,变现的路变长了,还不如搞娱乐八卦拍NC电视剧钱来得快,于是音乐也就没落了。文学上大家被互联网碎片信息冲击,信息爆炸,社会节奏快,也就更少人去买书阅读了,另外网上盗版满天飞,传统作家收入也受限了,远不如写写YY网络小说赚得多,细腻经典的文学也就变少了。游戏上以前单机游戏,追求的就是好玩,好玩就会有很多人买,就会赚到钱,而现在网络游戏,追求的不是好玩而是寻找人性的弱点,对人性把握越到位,就有越多人民币玩家投钱在你游戏里,可参照各种人民币玩家当皇帝的页游卡牌手游。

《龙珠》的超级赛亚人濒死状态疗伤恢复后战斗力会大增,应该是取材自现实,正如尼采说的,“杀不死我的,会让我变得更强大”。在受重大挫折后,只要熬过来了,内心就会变得更强大。

进化论像心灵鸡汤,咋一看很有道理,实际是怎么说都行,经不起推敲。例如人为什么会有害怕和恐惧的情绪,因为在老虎面前你不害怕和恐惧就挂了,那些不会害怕和恐惧的人已经灭绝了,但另一方面,为什么那些一害怕就腿软没有行动能力的人没有灭绝呢?他们理应逃不过虎口。

人们看重天赋>努力>外在条件,学生时期少不了一类学生总是说自己没学习,回到家偷偷学到半夜,考试成绩出来后把成绩归功于自己的天赋而不是努力。但靠努力奋斗获得成功又比靠关系靠是富二代这些外在条件获得成功更受人尊重。

很多人表达观点的时候,都会隐藏对他不利的事实,只说对他的论点有利的事实,如果这时候听者顺着他的思路,不思考提出疑问,就会陷入他构造的逻辑中,觉得很有道理,从而接受了观点,被洗脑。

XCode 代码补全插件 – JSPatchX 原理解析

2016-4-26 评论(2) 分类:技术文章 Tags:

JSPatchXJSPatch Xcode 代码自动补全插件,目前在 github 开源,效果见图:

做完一个开源项目照例写篇文章说明下实现原理,主要目的是让想对这个项目做贡献改进的人可以通过文章更容易地了解这个项目的由来,思路,核心原理和流程,降低参与这个项目开发的门槛。

由来

JSPatch 脚本一个不爽的地方就是没有代码补全,而调用 OC 方法时方法名又死长,写起来很不方便。

对此之前做了 JSPatch Convertor,可以自动把 OC 代码转为 JSPatch 脚本,这个工具的使用场景是用 JSPatch 做 hotfix 时,需要重写原 OC 的整个方法,这时用工具把这个方法的 OC 代码直接转为 JS 再进行修改,可以很大地降低工作量,缓解了这个问题。但若要用 JSPatch 开发新功能模块,就不会有 OC 代码可以去转换,这时提高编码效率的唯一方式就是做代码补全插件。

在寻找实现方案的时候得知公司内一牛人 louis 已经实现了 lua 的 XCode 代码补全插件,沟通后还很慷慨地给了源码,省去了很多研究 XCode 代码补全机制的功夫,于是参考他的编码,并且直接用了他 OC 头文件解析的代码,开发了 JSPatchX。所以这个项目算是我与 louis 联合开发的,在此感谢 louis~

插件入门

XCode 有个很坑爹的地方,就是它并不官方支持插件开发,官方没有文档,XCode 也没有开源,但由于 XCode 是 Objective-C 写的,OC 动态性太强大,导致在这么封闭的情况下民间还是可以做出各种插件,其核心开发方式就是:

  1. dump 出 Xcode 所有头文件,知道 Xcode 里有哪些类和接口。
  2. 通过头文件方法名猜测方法的作用,swizzle 这些方法,插入自己的代码实现插件逻辑。
  3. 通过 NSNotificationCenter 监听各种事件的发生。

更详细的开发教程网上有不少文章,有兴趣的自行搜索吧。

起步

对于实现 JS 代码补全这个功能来说,主要分三步:

  1. 在编辑 JS 文件时开启代码补全功能。
  2. 找到用户输入代码时的回调,按 Xcode 要求组装代码补全对象数组返回。
  3. 根据已输入文字对补全对象数组进行过滤

第一步是通过替换 DVTTextCompletionDataSource 类里的 -strategies 方法,在源文件是 JS 时生成一个 IDEIndexCompletionStrategy 对象返回,就可以针对 JS 文件走代码补全逻辑了。

第二步是替换 IDEIndexCompletionStrategy- completionItemsForDocumentLocation:context:highlyLikelyCompletionItems:areDefinitive: 方法,这个方法会在用户输入时被调用,在这里组装好应该出现的补全对象(IDEIndexCompletionItem) 列表返回,Xcode 就会自动应用返回的 items 对输入进行补全。

第三步是在 DVTTextCompletionSession-_setFilteringPrefix:forceFilter: 方法,针对第二步返回的 item 对象根据输入进行过滤。

要让自动补全插件程序跑通,只需实现上述三步。显然核心在第二步如何组装合适的补全对象 completionItem。代码里我们新增了一个 IDEIndexCompletionItem 的子类 JPCompletionItem 去表示,下面统一把这个补全对象称为 completionItem。接下来的问题就是怎样组装这些 completionItem。

实现

先看看我们需要哪些自动补全,概括起来有几种:

  1. 可能会被调用到的 OC 方法名
  2. JS 上新增的方法名,以及出现的类名
  3. JSPatch 自身的一些关键字接口,如 defineClass, require 等
  4. 当前 JS 文件里出现过的关键字

前三点应该没有异议,第四点要解释一下,实际上若要做得精细,应该加上 JS 语言本身自带的 API 和关键字(var / Math 函数 / String 函数等),以及JS 当前作用域上的变量的补全,但这样做一是 API 太多,二是实现复杂,所以用 “当前 JS 文件里出现过的关键字” 代替这两点,只要文件里出现过的单词就会有补全提示,也就是说一些关键字和变量第一次输入时没有提示,但在同个文件第二次输入就有补全提示了,sublime 默认就是这样的补全规则,实际使用效果很好,所以选择用这种简单的方式满足需求。

具体实现上,分三步走,一是解析 OC 头文件,二是解析 JS 文件,三是对解析后的数据进行缓存和组装 completionItem。

解析 OC 头文件

JPObjcFile 负责解析 OC 头文件,因为这里可以认为外部可以调用的 OC 接口都在头文件里,所以只需要解析头文件,这样处理比较简单,解析效率也很高。louis写了个 OC 头文件解析器,把头文件里的 class / protocol / import 解析出来,最终每个头文件都会解析成对应的 JPObjcFile 对象,这个对象保存着文件里 class / protocol 对应的方法的 completionItems,可以按需求直接输出。

解析 JS 文件

JPJSFile 负责解析 JS 文件,这里的解析比较简单,没有用词法语法解析器,而是直接通过正则匹配取出需要的内容,这里通过正则提取了:

  1. require() 里的 className
  2. defineClass() 里的 className
  3. defineClass() 里所有的方法名
  4. 文件里所有 keyword

同样每个 JS 文件都会生成一个 JPJSFile 对象,包含了上述提取的元素,并生成和保存了方法名和keyword对应的 completionItems列表。

组装和缓存

解决了单个 OC / JS 文件的解析,接着就是决定解析哪些文件,以什么样的形式缓存和组装返回给XCode。

JPObjcIndex

先看看 OC 的解析,JPObjcIndex 负责 OC 头文件的解析,JS 可能调用到的 OC 代码只存在于两个地方,一是系统framework,二是项目里的代码,对这些 OC 头文件要以什么样的方式解析呢?这里有两个选择:

  1. 只解析与当前编辑的 JS 文件相关的 OC 头文件
  2. 一次性把所有文件都解析好,再进行筛选

若要用方案1,只解析与当前编辑的 JS 文件相关的文件,则需要知道 JS 文件引用到了哪些 OC 文件,需要像 OC 代码那样有 #import 其他文件的规则,而 JSPatch 的规则是调用 OC 代码时不需要 import OC 文件,只需要通过 require(‘className') 接口引入类,所以线索只有 require() 里的类名,而在还没解析时是不清楚类名和 OC 文件的对应关系的,无法知道当前 JS 文件依赖了哪些 OC 头文件,所以这里只能选择一次性把所有 OC 头文件都解析好。

JPObjcIndex 默认扫描了 Foundation 和 UIKit 这两个 framework 里的所有头文件,以及当前项目里的所有 OC 头文件,在 JPObjcIndex 里以 className 为 key 进行缓存,对外提供通过 className 去取这些类相应 completionItem 的接口。

JPJSIndex

对于 JS 文件,为了简单起见,同样采用了一次性解析全部文件的方式。JPJSIndex 做了以下这些事:

  1. 解析所有 JS 文件,生成一个个对应的 JPJSFile 对象,缓存起来。
  2. 取出每个 JPJSFile 里解析的 require() 以及 defineClass() 的 className,去 JPObjcIndex 取这些 Class 对应的 completionItems。
  3. 取出每个 JPJSFile 解析好的 method completionItems。
  4. 取出每个 JPJSFile 解析好的 keyword completionItems。
  5. 本地 keyword.plist 定义了 JSPatch 常用的一些自动补全关键字,例如 defineClass, CGRect 等,在这里取出这些数据并生成 completionItems。
  6. 把 2-5 步里的 completionItems 分成两种类型,keyword 类型和 method 类型,缓存起来并返回给 XCode。
  7. 当有 JS 文件保存时,重新对这个文件生成 JPJSFile 对象,并重做 2-6 步。

第6步分出来的两种类型应用于两种场景,method 类型会在 JS 输入 . 要进行方法调用时出现,这个类型里所有的 completionItem 都是方法,包括 OC 头文件定义的方法以及 JS 里解析的方法。keyword 类型则是其他的像类名/语句关键字等这些非方法,在平常输入中出现。

在没有 JS 文件保存时,用户编辑 JS 代码每一次输入走到补全逻辑时,JPJSIndex 都是直接返回内存里已组装好的 completionItems 列表,没有其他操作,提高操作性能。第7步虽然在有文件保存时重新做了 2-6 步对数据进行重新组装,但这个过程不涉及文件解析,只需要取内存里解析好的数据进行组装,并且文件保存不会那么频繁,所以性能上没有太大问题。

整个流程就是这样,实际上很简单,总结起来就是解析所有 OC 头文件,解析所有 JS 文件,组装并缓存好 completionItem 返回。

不足

做这个项目的想法是先用最简单的方式快速做出来,满足80%的需求,导致会有一些不足,例如

  1. 没有做 JS 语法解析,没有做细致的筛选规则,粗暴地全部提示。
  2. 没有补全 include 的其他 JS 文件里的全局变量。
  3. defineClass 里写定义方法时,若要覆盖 OC 原有方法,没有方法名补全(因为方法名只有在 . 后才有补全)
  4. 没有加上除了 Foundation 和 UIKit 以外的 framework。

欢迎一起改进 JSPatchX,完善这些不足~

产品杂想

2016-4-21 评论(2) 分类:互联网

1.抄一个产品是很容易的,损一个产品也是很容易的,知道别人的产品为什么那么做,自己的产品怎样做会更好,是比较难的。

2.影响一个产品发展的只有核心的几个点,其他细节做到极致跟做到60分+对产品的影响微乎其微。细节不会决定成败,核心细节才会。

举个例子,苹果把手机系统/应用生态/品牌营销做到最好就行,AppStore iCloud iTunes 这些做得再糟糕,只要60分能用就够了(甚至AppStore老是不能用),不会对苹果销量产生多大影响。

当然整个 App 各个细节都做到极致是好的,但细节是工作量堆出来的,理想情况下资源应该尽量用在更能推动产品前进的点上,也就是用在更有性价比的地方,资源有限的情况下,理想的分配是,重要的功能点多花时间打磨细节,不重要的功能点快速做到60分,而不是追求每一个点都做到极致。资源充足或过剩的情况请便。

3.产品人员本身的想象力对团队效率影响很大,理想情况下设计时就能在脑里想象做出后的效果,并串上真实数据,假想各种条件下这样的设计会不会有问题。当然一般做不到像真实体验那样的程度,但应该尽力想象。

4.开发接到产品的需求不假思索马上动工做,看似尽责,实际很不靠谱,有时产品设计功能太多,对具体一功能一时想得不周全,或者产品不清楚技术具体实现难度/代价导致错误设计,这时开发应该补全这个缺口,有问题在动手之前沟通好。

5.有些产品新功能,开发咋一看很不靠谱,实际上产品在设计时有自己的思考逻辑,得理解他们的思考逻辑后才好吐槽。

6.做产品没有唯一正确的方式,技术导向,产品导向,传统制度,独裁都能做出好的产品。facebook是技术导向,line是传统制度,微信是独裁产品导向。

7.交互的效率第一,效果第二。只提升视觉效果,没提升效率,或者降低效率的交互是不会流行的。典型的如一些3D桌面,交互很炫,效率很低,玩完就扔。下拉刷新,既提升视觉效果又提高效率,变成标配。iOS Tabbar 视觉效果不好,但效率奇高,也成为最流行的交互。创新的交互本身就会降低效率,因为用户有学习成本,若不能带来效率的提升,就会难以为继,如facebook paper。

JSPatch更新:完善开发功能模块的能力

2016-4-6 评论(7) 分类:技术文章 Tags:

JSPatch 开源以来大部分被用于 hotfix,替换原生方法修复线上bug,但实际上 JSPatch 一直拥有动态添加功能模块的能力,因为 JSPatch 可以创建和调用任意 OC 类和方法,完全可以用 JSPatch 写功能模块,然后动态下发加载。只是之前在性能和开发体验上有些问题,还没有太多这方面的应用。这次 JSPatch 做了较大的更新,扫除这些问题,让用纯 JS 写功能模块变得实用。这里有个用 JS 写的 Dribbble 客户端 Demo,可以体验下效果。

来看看这次更新做了什么。

性能优化

通过工具可以看到使用 JSPatch 写功能模块时,耗时较多的点在于 JS 和 OC 的通信,以及通信过程中参数的转换,于是在这块寻找优化点。写功能时需要新增很多类和方法,例如:

defineClass('JPDribbbleView:UIView', {
  renderItem: function(item) {
    ...
  },
})

defineClass('JPDribbbleViewController:UIViewController', {
  render: function(){
    var view = JPDribbbleView.alloc().init();
    view.renderItem(item);
  }
});

上面两个都是新增的类,两个方法也是新增的,按之前的流程,这里的定义会传入 OC,在 OC 生成这两个类,并在这个类上添加这里定义的方法,调用时进入 OC 寻找这些方法调用。

(更多…)

iOS 组件化方案探索

2016-3-18 评论(52) 分类:技术文章 Tags:

看了 Limboy(文章1 文章2) 和 Casa (文章) 对 iOS 组件化方案的讨论,写篇文章梳理下思路。

首先我觉得”组件”在这里不太合适,因为按我理解组件是指比较小的功能块,这些组件不需要多少组件间通信,没什么依赖,也就不需要做什么其他处理,面向对象就能搞定。而这里提到的是较大粒度的业务功能,我们习惯称为”模块”。为了方便表述,下面模块和组件代表同一个意思,都是指较大粒度的业务模块。

一个 APP 有多个模块,模块之间会通信,互相调用,例如微信读书有 书籍详情 想法列表 阅读器 发现卡片 等等模块,这些模块会互相调用,例如 书籍详情要调起阅读器和想法列表,阅读器要调起想法列表和书籍详情,等等,一般我们是怎样调用呢,以阅读器为例,会这样写:

(更多…)

JSPatch 近期新特性解析

2016-3-14 评论(6) 分类:技术文章 Tags:

JSPatch 在社区的推动下不断在优化改善,这篇文章总结下这几个月以来 JSPatch 的一些新特性,以及它们的实现原理。包括脱离锁的 performSelectorInOC 接口,支持可变参数方法调用,给新增方法指定类型的 defineProtocol 接口,支持重写 dealloc 方法,以及两个扩展 JPCleaner 和 JPLoader。

performSelectorInOC

JavaScript 语言是单线程的,在 OC 使用 JavaScriptCore 引擎执行 JS 代码时,会对 JS 代码块加锁,保证同个 JSContext 下的 JS 代码都是顺序执行。所以调用 JSPatch 替换的方法,以及在 JSPatch 里调用 OC 方法,都会在这个锁里执行,这导致三个问题:

  1. JSPatch替换的方法无法并行执行,如果如果主线程和子线程同时运行了 JSPatch 替换的方法,这些方法的执行都会顺序排队,主线程会等待子线程的方法执行完后再执行,如果子线程方法耗时长,主线程会等很久,卡住主线程。
  2. 某种情况下,JavaScriptCore 的锁与 OC 代码上的锁混合时,会产生死锁。
  3. UIWebView 的初始化会与 JavaScriptCore 冲突。若在 JavaScriptCore 的锁里(第一次)初始化 UIWebView 会导致 webview 无法解析页面。

(更多…)

不可能

2016-3-12 评论(2) 分类:随记

20年前电脑战胜国际象棋冠军时,很多幻想者开始幻想电脑以后如何拥有人类的思想,以后如何统治人类,自从我学习计算机后,就对这些幻想者嗤之以鼻,因为我知道了计算机程序的大致原理,只不过是一些逻辑和循环运算组成,能战胜国际象棋冠军主要是因为计算能力强速度快,象棋每一步可能的情况又很少,计算机可以穷举,再加上一些逻辑策略的优化可以战胜世界冠军,这种能力跟人类大脑完全不沾边,没有半毛钱关系。从战胜象棋冠军就开始幻想计算机可以拥有人类一样的思想,当时觉得这些想法很傻很天真。

直到5年前我看到一本书《人工智能的未来》,这本书阐述了大脑的工作原理,以及用计算机模拟这种工作原理,造出真正与人类大脑接近的人工智能的可能性,让我叹为观止,我一直觉得不可能的事情,原来是可能的,只不过因为我自己的无知和低水平,对计算机的认知停留在已有的范式上,又觉得大脑高深不可测,才觉得这是不可能的。

这种学潮持续发展,到今天计算机的机器学习领域已经很热门,就在今天基于机器学习的 AlphaGo 对围棋世界冠军李世石第三局结束,3-0领先,5-0几乎没有悬念,让人始料未及。10年前看漫画《棋魂》,台词说到计算机可以轻易赢象棋冠军,但要赢围棋冠军,至少得100年后,这也是大家普遍的观点,因为围棋的复杂度跟象棋不在一个量级,结果计算机10年就达到了这成就。按我理解围棋是特定领域,即使在围棋上赢了世界冠军,离真正的人类大脑还有很大差距,但已经不敢嘲笑幻想者们对这种可能性的想象了,这真是可能发生的事。

我们经常基于自己的经验,很轻易地说一些事情不可能,如果我生活在五六十年代,肯定会觉得计算机大规模应用不可能,它只不过提供了一些二进制运算和数字存储能力,怎么可能面向大众提供工作娱乐功能,但硬件半导体的发展跟软件开发的分层思想让这些成了可能。Google 佩奇说,“有一类事情,人们公认不可能实现,如果你不动手去做,它也就真的不会发生。”很佩服所有致力于把这些不可能的事变成可能的人。人与人之间的差距巨大,“改变世界”在我们发展中国家不过是一句忽悠台词,而他们是真正在实践。生活在这个时代很幸福,很期待未来的世界。

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