干货 | 携程酒店iOS动态View的探索

逆向解析携程App私有协议:从抓包失效到数据采集的完整实战 在移动应用开发与安全分析领域,网络协议是数据通信的基石。标准HTTP/HTTPS协议因其明文或标准加密特性,易于使用抓包工具进行调试与分析。然而,为提升安全性与性能,许多大型应用采用私有通信协议,将数据封装在自定义的二进制格式中,导致传统抓包工具失效。理解协议逆向原理,掌握动态与静态分析技术,对于安全研究、性能优化及合规数据采集具有重要价值。通过Hook关键函数、分析网络流量与反编译代码,可以逐步还原协议结构、加密算法及密钥生成逻辑。这一过程常涉及Frida、IDA Pro等工具,用于突破SSL Pinni 阅读详情

作者简介

姜睿东,2009年加入携程,从事无线研发,现在大住宿事业群负责酒店无线研发工作。


一直以来,Native App因为审核的原因,新版本不能很及时地上线。尤其是iOS,碰到点审核问题,有时候一连几天都不能上架,严重影响业务和产品的体验。


大家一直都在寻求能够动态更新业务的方法,关于这方面的框架也是层出不穷。自从Facebook推出React Native以后,便以其良好的兼容性和性能优势占据了这方面的领先地位,携程也在此基础上开源了CRN框架。


如果是新业务,用CRN开发是非常合适的,开发效率高,双平台兼容性好。但如果要把已有的Native页面转CRN,复杂的核心页面成本会有点高。在不增加人手的情况下,要想同时进行业务的迭代和CRN的转换,会有点力不从心。


如果硬转,周期会很长。以携程酒店主流程页面之一的订单详情页为例,在没有额外增加人手的情况下,前后花了几个月时间,才陆陆续续完成了90%的功能转CRN,过程尤为艰辛。订单详情页是主流程页面中相对简单的,如果要转酒店详情页,光是几百行的ViewModel就已经让人望而却步了。


对此,我们考虑能不能采用一种让Native和CRN共存的方式,这样既可以保留Native的业务逻辑,又可以在UI层面做到灵活应变。最关键的是,可以分模块的开发,而不用像转CRN那样必须整个页面一起上。


当然,Native和CRN混合的解决方案早就有了,但是当CRN作为一个子View出现在Native页面里的时候,由于CRN的框架比较重量级,在性能上并不是特别理想,而且和Native的交互也不是特别方便,所以我们开始考虑有没有更为轻便的解决方案。


在比较了多种跨平台方案之后,首先排除了类似Lua这种需要依赖第三方库,且语法非主流的方案,最终决定采用原生系统就自带支持的,且语法有着广泛群众基础的JavaScript。


在iOS7之前,要在Native环境中和JavaScript交互是非常简单且功能有限的,基本上只有依靠Webview的EvaluateJavaScript 来注入执行一段JS脚本。从iOS7开始,苹果引入了JavaScriptCore这个库,顿时给iOS的开发带来了翻天覆地的变化。


为什么会这么说呢,首先来看一下JavaScriptCore中所包含的两个关键类,JSContext和JSValue:


JSContext


JSContext提供了一个在APP中执行JavaScript代码的环境,使得我们可以直接在Objective-C或Swift代码中直接调用JavaScript代码,并得到返回结果,反过来也可以暴露方法和类供JavaScript调用。


JSValue


JSValue则是一个JavaScript数据类型在Objective-C或Swift中的包装对象,借助于这个对象我们可以在Native代码和JavaScript代码之间互相传值,这两者之间的对应关系如下图所示:

 

Objective-C (and Swift) Types

JavaScript Types

nil

undefined

NSNull

null

NSString (Swift String)

String

NSNumber and primitive numeric types

Number, Boolean

NSDictionary (Swift Dictionary)

Object

NSArray (Swift Array)

Array

NSDate

Date

Objective-C or Swift object (id or AnyObject)

Objective-C or  Swift class (Class or AnyClass)

Object

Structure types:

NSRange, CGRect, CGPoint, CGSize

Object

Objective-C block (Swift closure)

Function

 

简单总结一下,JSContext提供JavaScript和Native互相调用的接口,JSValue提供互相调用之间的数据类型转换,这样的调用方法比之前的Webview要强大灵活许多,想象空间也大了很多。所以我们接下去就准备在这基础之上做点文章。


第一步,先创建一个JavaScript对象,用来描述对应iOS中的UIView,代码用ES6如下:



 
Class View {	
    constructor() {	
         this.x = 0;	
         this.y = 0;	
         this.width = 0;	
         this.height = 0;	
         this.borderWidth = 0;	
         this.borderColor = ‘’;	
         this.cornerRadius = 0;	
         this.masksToBounds = false;	
         this.subviews = [];	
     }	
     initWithFrame(x, y, width, height) {	
        ……	
     }	
     addSubview(v) {	
        ……   	
     }	
     setOnclick(click) {	
        ……   	
     }	
     ……	
}


这些属性和方法都是iOS中UIView比较常用的,如同在iOS中UILabel是继承自UIView一样,我们继续创建一个JavaScript的Label对象,并继承自刚才在上面创建的View对象。



 
Class Label extends View {	
    constructor() {	
         super();	
         this.text = ‘’;	
         this.textColor = ‘’;	
         this.textSize = 14;	
         this.fontStyle = 0;	
         this.textAlignment = 0;	
         this.lineBreakMode = 4;	
         this.numberOfLines = 1;	
    }    	
}


以此类推,我们继续创建诸如Imageview,Button,ScrollView等iOS中常用的组件,只要愿意,所有的组件都可以用这种方式来描绘。


有了这些基础的JavaScript组件,接下去就可以如同在iOS中布局一样,开始用这些组件进行布局,如下代码片段示例了如何对一张图片进行布局。



 
createImage() {	
       var container = View.initWithFrame(0, 0, 50, 50);	
       container.backgroundColor = "#FFFFFF";	
       var image = Image.initWithFrame(0, 0, 50, 50);	
       image. imageUrl = ‘http://m.ctrip.com/xxxxx.png’;	
       container.addSubView(image);	
       return container;	
 }


对于熟悉iOS开发的同学来说,会觉得这段代码非常眼熟。没错,这就是一段用JavaScript来写的iOS代码,依此类推,稍微复杂一点的布局也可以用这种方式完成。


最后来看一下布局完成以后的返回值,暂时还是先以上面的Image控件来做示例:



 
render() {	
        varcontainer = View.initWithFrame(0, 0, 50, 50);	
       container.backgroundColor = "#FFFFFF";	
       var image = Image.initWithFrame(0, 0, 50, 50);	
       image. imageUrl = ‘http://m.ctrip.com/xxxxx.png’;	
       container.addSubView(image);	
 	
       var demoView = View.initWithFrame(0,0,180,180);	
       demoView.addSubView(container)	
       return demoView;	
}


如果在浏览器或者JavaScript环境中运行上述代码,会得到一个自定义的递归对象,根对象会包含一个Subview数组,数组中的每个元素都有可能是另外一组UI对象,当然实际操作中并不建议层次太多,一般1-2层。


做到这里,JavaScript的部分暂告一段落。接下来回到Native当中,还记得上文提到的JSContext么?这是一个在Native当中的JavaScript执行环境,我们在Native环境中用JSContext来执行刚才那个Demo,就会得到一个对应的JSValue值,这个JSValue的值用[JSValuetoObjct]来转换成Object-C对象的话,最终就得到了一个字典,NSDictionary。


继续递归地拆解这个字典,拆解到底,每个元素最终都会转成OC的Object,然后根据每个Object预先定义好的Type类型,实例化成相应的Native组件,并且每个组件有一个对应的数据Model。


还是以上述那个Label为例,其对应的OC Label代码如下:



 
@implementation Label	
 	
- (void)setModel:(HTLDynamicLabelModel *)model{	
   self.dynamicViewModel = model;	
   self.text = model.text;	
   self.textColor = model.textColor;	
   self.font = model.font;	
   self.lineBreakMode = model.lineBreakMode;	
   self.numberOfLines = model.numberOfLines;	
   	
    if(model.richText && model.richText.attributedString) {	
       self.attributedText = model.richText.attributedString;	
    }	
}	
 	
@end

  

到此为止,就完成了所有之前在JavaScript中描绘的控件在Native里的转换,剩下的事情就是对这些Native组件进行渲染了,具体就不在这里描述了。


总体来说,这个思路在原理上跟RN或者CRN是一样的,但更为轻量一点,几乎0配置就能使用。通过配置增量更新,从服务端下载最新的JS文件,可以做到类似CRN在线更新的效果。


从性能上来看,因为不需要额外加载任何框架代码,JS执行的消耗几乎可以忽略,所以和Native混合在一起的时候,几乎看不出有任何延迟。


这个方案非常适合做一些轻量级的又需要经常不定期更新的UI,比如节日氛围或者城市包装的UI。这些UI经常会跟随节假日更新,用这个方案可以轻松在线更新UI,不用通过服务端下发一堆样式来控制,减轻了服务发布的压力和不必要的服务交互。


综上所述,这是我们团队对新事物的一些探讨和研究,并不存在要代替CRN或其他框架一说,每个框架都有其适用的场景,没有绝对的优劣之分。


在研究这个解决方案的过程中,我们也认真地深入了解了JavaScriptCore的一些机制,原理都是万变不离其宗的,但可以结合不同的场景,进行不同的演变,就看怎么灵活运用了。


所以,与其说本文是在探索iOS中动态View的解决方案,也不妨说成是对JSContex和JSValue如何运用的一些探讨,从实际的摸索中来看,灵活运用好JavaScriptCore,可以有无限多的可能。


【推荐阅读】



640?wx_fmt=jpeg

ios 更多 Url Schemes 蜂窝网络:prefs:root=MOBILE_DATA_SETTINGS_ID VPN — prefs:root=General&path=Network/VPN Wi-Fi:prefs:root=WIFI 定位服务:prefs:root=LOCATION_SERVICES 个人热点:prefs:root=INTERNET_TETHERING 关于本机:prefs:root=Genera 阅读详情

相关推荐

ios 旅游 APP 携程

ios 旅游 APP 携程

滴滴 iOS 动态化方案 DynamicCocoa 的诞生与起航

作者简介: 孙源(@我就叫Sunny怎么了),滴滴出行 iOS 技术专家,多年专注于 iOS 开发,现就职于滴滴 App 架构组,在技术上做探索和深挖;善于刨根问底,对未知的东西兴趣强烈,代码风格强迫症;同时喜欢写博客(http://blog.sunnyxx.com/),线上线下分享,贡献开源(forkingdog)累计 star 破万。 欢迎技术投稿、约稿、给文章纠错,请发送邮件至m...

历史上的今天 2399

ios应用源码之从上往下拉出现加载view,动态加载内容 2018127

ios应用源码之从上往下拉出现加载view,动态加载内容 .

干货 | 携程APP Native/RN内嵌Flutter UI混合开发实践和探索

作者简介Deway,携程资深工程师,iOS客户端开发,热衷于大前端和动态化技术;Frank,携程高级工程师,关注移动端热门技术,安卓客户端开发。前言随着各种多端技术的蓬勃发展,如今的移动...

携程技术 3297

保姆级教程:用Python+OpenCV实现相移法与格雷码三维重建(从生成条纹到点云生成)

本文详细介绍了使用Python和OpenCV实现相移法与格雷码三维重建的全流程,从条纹生成到点云计算。通过结构光技术,结合相移法和格雷码,实现高精度的三维重建,适用于无纹理物体表面的密集对应点生成。教程包含环境搭建、条纹生成、相位计算、三维点云重建及常见问题排查,适合计算机视觉开发者和研究人员。

weixin_33443333的博客 349

python调用海康工业相机并用opencv显示(整体实现)

python语言调用海康机器人(hikrobotics)工业相机 第一章 Python 语言下连接海康工业相机,并获取数据 文章目录 系列文章目录 前言 目录 python语言调用海康机器人(hikrobotics)工业相机 文章目录 前言 一、底层接口的准备 二、使用步骤 1.引入库 2.枚举设备 3.判断设备类型 4.输入连接设备 5.创建相机实例并创建句柄 6.打开设备 7.获取相关参数 8.主动获取图像 9.开启取流并获取每张.

qq_39570716的博客 5万+

iOS开发--UISCrollView上滑隐藏导航栏,下滑显示导航栏

简介 有时候,为了方便阅读,我们会将UINavigationBar隐藏.出现场景最多的,是配合UIScrollview的使用(UITableView和UICollectionView同样适用). 上代码 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity tar...

张福润的博客 2466

【BigWorld 游戏服务器引擎】Cell 架构设计介绍,及Java实现方案的探索

横向扩展(Scalability):通过动态增减CellApp和BaseApp的数量,可以轻松应对玩家人数的变化。世界可以做得非常大,只需增加更多的 Cell。负载分离(Load Separation):将不同性质的负载分离,避免了单一进程瓶颈。CPU 密集型的实时计算(CellApp)和 I/O 密集型的数据操作(BaseApp)互不影响。高效的视野管理(AOI):每个 Cell 只关心自己区域内和边界上的实体,大大降低了计算复杂度。容错性:某个CellApp。

代码时光 1205

干货 | 携程度假智能客服机器人背后是这么玩的

作者简介雷蕾,携程度假研发部资深算法工程师,负责智能客服算法工作。鞠剑勋,携程度假研发部算法经理,负责智能客服、知识图谱、NLP算法等工作。随着人工智能的发展,人机交互技术愈发成熟,应用场景也越来越多。智能客服是人机交互在客服领域的一个应用,服务于客人以及相关的客服人员。本文将介绍智能客服在旅游场景下的主要技术和应用。当前度假的智能客服主要用于C端(客户端)面向客人,以及客服端辅助客服的两个角色。...

携程技术 2161

blenderproc 制作位姿估计数据集

blenderproc 制作位姿估计数据集 准备工作 1.首先需要去下载blenderproc的源码blenderproc,按照作者的readme文件进行编译。 2.其次需要下载bop_toolkit源码,链接如下bop_toolkit 3.说明:blenderproc主要用来生成数据,包括depth,rgb,位姿标签文件(scene_gt.json),bop_toolkit主要用来生成mask和mask_visib,scene_gt_info.json,用于判断物体的可见区域比例,如果遮挡太多考虑去掉。做

qq_43814359的博客 5697

ad23新版Geber导出-官方教程(22.11版本后)

AD23新版本geber文件导出(含官方教程)-22.11之后的版本均可用此教程

安和的博客 3万+

iOS开发 - 商品详情页两种分页模式,只提供思路和实现方式。

上面的效果是商品详情页常用的两种模式,分页和不分页。首先请忽略博主懒得去写界面,真正的效果见下面: 不分页模式 分页模式然后先来依次说明下原理: 分页模式:看着和下拉刷新上拉加载的时候像不像?没错,博主这里用的MJRefresh写的效果,往上时下拉改变底部scrollView的偏移量,往下时加载结束改变底部scrollView的偏移量。其他的布局按照正常的界

CodingFire的博客 6137

Apollo EM Planner中路径-速度解耦优化的数学建模与仿真分析

摘要 Apollo EM Planner采用路径-速度解耦优化策略解决自动驾驶运动规划问题。该算法将时空轨迹规划分解为路径规划和速度规划两个子问题:首先在静态环境下生成几何最优路径,再优化沿路径的速度曲线。通过五次多项式表示路径和速度,构建包含平滑性、安全性、舒适性的多目标优化函数,并引入弹性模型处理动态障碍物约束。算法具有解耦优化、弹性适应、实时求解等特点,适用于高速公路、城市交叉口等多种场景。数学建模包括路径几何优化、速度动态优化和弹性势能函数,最终生成满足车辆动力学和环境约束的安全轨迹。

走向CTO的路上... 933

ios 页面向导航栏内嵌的时候需要把导航栏的穿透效果关闭

 self.navigationController.navigationBar.translucent = NO;

zhao15127334470的博客 1262

分数间隔均衡器的基本原理及应用(使用Matlab)

通过对接收信号进行加权求和,分数间隔均衡器可以抵消信号在传输过程中受到的频率响应失真。Matlab提供了丰富的工具和函数,可以方便地实现分数间隔均衡器,并进行性能评估。分数间隔均衡器(Fractional Interval Equalizer)是一种数字信号处理技术,用于均衡带通信道中的信号失真。分数间隔均衡器的基本原理是通过对接收信号进行加权求和,以抵消信号在传输过程中受到的频率响应失真。分数间隔均衡器在通信系统中具有广泛的应用。最后,我们通过比较均衡后的信号和发送数据的阈值来进行解调,并计算误码率。

2301_79325657的博客 675

【AI编程】Vibe Coding 开发环境搭建与项目实战操作详解

Vibe Coding 开发环境搭建与项目实战操作详解

congge 7334

人生第一次电话面试-(携程ios开发)

就在前五分之前,刚刚接到携程ios开发的电话面试。因为现在也算是实习招聘的高分期。这段时间因为个人的原因也是最后决定找这个方面,携程这边我投了今天是第四天了,上午我的同学还在问我有没有接到电话面试,我还说没有呢;好吧;下面就跟大家说说具体问了什么;      人生总是有第一次。刚刚接到电话的那一刻还是激动了,携程那边的人口音听起来特别的像我现在的同学。所以感觉还是特别的没有距离,一上来就让我自我

sundaowei1990的专栏 2240

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

iOS 导航连续退出2个页面

// 取navigationCtroller中的Controllers NSArray * ctrlArray = self.navigationController.viewControllers; // 取出后,执行, [self.navigationController popToViewController:[ctrlArray objectAtIndex:0] animated

迟浩东 iOS开发博客 1399

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

iOS UITableView拉伸图片,悬停控件和渐变导航栏效果

一、实现效果: 1.表单下拉放大顶部图片,弹簧效果 2.表单上拉逐渐显示导航栏 3.悬停视图停止在导航栏底部 二、效果图 三.建立工程实现

qq_28913211的博客 5002

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

iOS应用中检测第三方app是否安装及跳转解决方案

最近在做支付宝支付,需要验证客户端是否安装支付宝钱包App,可通过Url Scheme框架实现。 参考文档 :http://www.jianshu.com/p/28f517775214  1、 以支付宝为例,验证是否安装支付宝开发步骤:      step1.  验证手机端是否安装 支付宝应用 NSURL * alipay_app_url = [NSURL URLWithString:@"

w6524587的博客 9505

干货:iOS APP与小程序UI设计对比

腾讯和苹果公司都对用户体验非常重视,都很擅长产品设计,所以今天就拿小程序和苹果的HIG(Human Interface Guidelines)做个比较,其实两者在一些大的原则处理上可以说是一致的。 关键词一:友好礼貌 对应于苹果:Less is more 苹果在iOS7时做了一个非常大的界面调整,以突出内容为主,去除掉了所有会干扰用户的界...

weixin_34159110的博客 502

干货 | 浅谈Node.js在携程的应用

作者简介潘斐斐,携程无线平台研发部高级研发工程师。2008年加入携程,目前负责携程Node.js技术栈的基础平台研发工作。携程在2017年9月份正式上线了Node.js应...

携程技术 591

iOS从App跳转至系统设置菜单

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34088838的博客 162
上一篇: 干货 | Electron在DevTools中的探索与实践
下一篇: 程里人 | 听说携程技术GG们去划龙舟了
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值