双十一大家“买买买”了吗?我猜你们要么是躺在沙发上,要么是躲在被窝里用手机和 Pad 下的单,因为我就是这么干的。当然我也不是瞎猜,天猫官方微博公布的数据为证:无线端交易额占比一路保持在 70% 以上,最后定格在 68%(据说峰值数据更是丧心病狂,具体数据未公布,大家猜猜吧)。
“Mobile First” 真的已经不是喊喊口号而已!部分业务形态甚至直接 “Mobile Only” 了。当然所谓的 “Mobile” 绝不局限于 Native App,Web 页面仍是不可替代存在,我始终坚信不管是手机端还是其他终端 Web 模式依然代表着未来。
不过开发手机上的 Web 页面调试一直是一个老大难问题。 虽然 Chrome DevtTools 可以模拟手机的环境,但与真实环境差别还是比较大的,另外 Chrome 模拟的环境对 App 内 Webview 场景也无能为力(手机淘宝上的无线 Web 页面有非常多的功能需要调用 Webview 提供的 JSBridge 接口实现)。所以真机调试和模拟器调试是无线 Web 开发必备技能。
真机相对复杂留到下次讲,今天我们先看看怎么在 iOS 模拟器里调试 Web 页面。
iOS 模拟器(iOS Simulator)是捆绑在 Xcode 里的,所以这篇文章的操作系统环境仅限 Mac OS,且已安装 Xcode。强烈建议大家从 App Store 下载 Xcode,理由你们都懂。
启动 iOS Simulator
常规的方式就是先启动 Xcode,再从 Xcode 菜单中启动模拟器。对于我们只是用模拟器来调试 Web 页面而言,每次都启动 Xcode 显然效率太低,是否可以跳过 Xcode 直接启动模拟器呢?
虽然模拟器捆绑在 Xcode 中,但是本身是一个单独的应用程序,安装路径在:
/Applications/Xcode.app/Contents/Developer/Applications/iOS Simulator.app
Tips:上面是 Xcode 6 中的应用名,Xcode 7 已改名为:Simulator.app,路径不变。
通过常规的方式启动模拟器后,发现 Dock 菜单上多出了一个模拟器的图标,这时即便退出 Xcode,模拟器任然能正常工作。为了方便下次开启模拟器,可以在 Dock 模拟器图标上右键选择:“在 Dock 中保留”,这样下次就可以通过直接点击图标启动了:
模拟器默认加载的是上次退出时使用的设备,需要更换的话到 “Hardware > Device” 菜单下选择即可。
接下来就简单了,在模拟器中用 Safari 打开你要调试的页面,再打开 Mac 上的 Safari,在“开发 > iOS Simulator”菜单下选中模拟器中打开的页面就可以调试了。如果没有“开发”菜单,请到“偏好设置 > 高级”中开启。
在模拟器中安装 App
如果只是在手机上的 Safari 中调试页面,那么跟直接在 Mac 的 Safari 中并没有太大区别,完全没有必要花大力气在模拟器中搞。我们的最终目标是要调试 App Webview 中的 Web 页面,接下来我们看看怎么把 App 装到模拟器里,这里我们以手机淘宝 App 为例。
模拟器上是没有 App Store 的,也不能下载 ipa 文件安装。只能安装基于源代码打包出来的 App Bundle,为了演示我已经预先从手机淘宝的 App 开发那里获得了名为: taobao.app 的 App Bundle。
另外 Xcode 提供了一个 simctl 命令,可以对模拟器做各种操作。simctl 命令的路径是:
/Applications/Xcode.app/Contents/Developer/usr/bin/simctl
在终端执行命令:
/Applications/Xcode.app/Contents/Developer/usr/bin/simctl install booted taobao.app
就可以把手机淘宝安装在前面启动的模拟器中了(参数 booted 指的是当前启动的模拟器)。嫌每次执行 simctl 的路径太长,可以使用 xcrun 命令,它会自动查找并启动已注册的 Xcode 命令行开发工具,比如: xcrun simctl xxx
。
App 安装好了,接下来我们让 App 打开我们要调试的页面,依旧还是使用 simctl 命令:
xcrun simctl openurl booted taobao://h5.m.taobao.com/guang/index.html
Tips: taobao://
是模拟器在安装 taobao.app 时注册的协议(scheme),当出现次协议的 URL 请求时默认会使用手机淘宝打开。不同的 App 在系统注册的协议各不相同,需要根据实际情况填写。如果需要在 Safari 中打开直接用 http://
协议头即可。
OK,成功在手机淘宝的 Webview 打开页面。后面怎么做就不用教了吧!在 Mac 上打开 Safari, “开发 > iOS Simulator” 菜单下选中模拟器中打开的页面,看图:
Tips:simctl 更多功能可以执行 xcrun simctl help
命令查看。
还有么有优化空间
在模拟器中安装 App,在 App 中打开 Web 页面都是在终端完成的,启动模拟器可不可以也在终端完成呢?答案是肯定的。
前面已经提到其实模拟器是一个独立的应用程序,所以我们可以通过 Mac 自带的 open 命令来运行,命令如下: open -a "iOS Simulator"
。还可以在启动的时候指定模拟哪个设备: open -a "iOS Simulator" --args -CurrentDeviceUDID <udid>
。udid 可以通过命令: xcrun simctl list
获得,执行后会列出当前已下载的设备列表,如图:
中间那串数字就是 udid,启动设备为 “iPhone 4S” 的 iOS 模拟器,命令应该是这样的:
open -a "iOS Simulator.app" --args -CurrentDeviceUDID "FCE2CFE8-64C3-4DBE-906B-B9BF4180DE49"
如果已升级到 Xcode 7 命令为:
open -a "Simulator.app" --args -CurrentDeviceUDID "FCE2CFE8-64C3-4DBE-906B-B9BF4180DE49"
至此,“启动模拟器”、“安装 App”、“打开 Web 页面” 我们都可以通过终端命令执行了。不过每次调试都要执行一遍这一点都不符合前端爱装 “X” 的个性。也许你想到了把这些命令封装到一个 shell 脚本中,如果这是这样的话也太小看我们装 “X” 的功力了。
现在不是“云”很火吗!我们也上个“云”。试想一下:所有的前端只要打开一个固定的网站,网站就会显示您当前系统支持启动哪些设备的 iOS 模拟器,只要在网站上轻轻一点本地的模拟器就启动起来了。不仅如此,网站还可以控制模拟器安装指定的 App,用指定的 App 打开的网页。像这样:
这是淘宝前端团队内部系统:MDS(Mobile pages Develop & Debug Solution)的一个局部界面(不知道大家有么有发现,文章写到这里,我的 Xcode 版本已经从 6 升级到了 7 ^ ^!吐槽下 App Store,真的很慢~~~)。
光有个网站就能启动本地的模拟器那是气功大师才干的出来的事儿,配合网站还需要一个安装在本地电脑的 SDK(npm)。为了启动个模拟器搞个网站又搞个 SDK?如果你是这么认为的,那是真的认为我们只是在装 “X” 了。MDS 要处理的事情远远比想象地要多,比如本地怎么才能获取最新的手机淘宝 App Bundle。 另外,MDS 还集成了一个云端的 DevTools 工具,这块内容下次有机会再细讲。