做iOS开发的程序员,都经常需要查看自己的应用的沙盒目录, 本篇主要提供一个python工具,快速定位模拟器中应用的沙盒目录,包括App、Extension以及App Group目录。
Xcode 8以前,苹果对插件基属于放养的状态,我们可以通过一定的方式,直接往 Xcode 注入代码。 对于Xcode插件的入门,可以看我的另一篇文章:《制作自己的Xcode插件》
到了Xcode 8,苹果为了避免类似 Xcode Ghost 事件的发生,禁用了插件, 然后开放了另一种形式:Source Editor extensions,但是这种形式局限性太大。能做的事情太少了。网上有方法可以去除Xcode的签名,这样使得 Xcode8 也可以继续使用插件了。感兴趣的可以搜一下update_xcode_plugins。
由于签名被移除,所以它的安全性又重回 Xcode 7 时代,也就是还有可能受到类似 Xcode Ghost 的攻击。所以不推荐用改过的Xcode来提交应用到 Appstore。
我之前也写了一个寻找沙盒的Xcode插件版,由于上面的原因,插件用着不方便,我就做了这个python简化版。
模拟器的各项数据,被苹果存在了~/Library/Developer/CoreSimulator目录内,只需要分析这个文件夹的组成,就能快速定位到自己需要的目录。
首先看看一个完整的App沙盒路径:
~/Library/Developer/CoreSimulator/Devices/
E6C54E8C-3EBD-4BDD-89AB-FF9B86FDDD5E/data/Containers/Data/Application/
4B09C4D0-5C25-40B2-8084-B6AE0CA79A32/Documents
同理,我们还可以发现Extension和App Group也有自己的目录,分别是:
~/Library/Developer/CoreSimulator/Devices/
E6C54E8C-3EBD-4BDD-89AB-FF9B86FDDD5E/data/Containers/Data/PluginKitPlugin/
F3B497F6-1649-4972-8032-9065C572DBE2/Documents
和
~/Library/Developer/CoreSimulator/Devices/
E6C54E8C-3EBD-4BDD-89AB-FF9B86FDDD5E/data/Containers/Shared/AppGroup/
F022AD7A-ACD8-4EA7-990D-BE57E0BF0A1C/
是的,Extension和App Group也有自己的沙盒,程序员在开发这两个功能的时候,可以看看这两个目录,可以快速确定这两个的存储是否符合自己的预期。
可以看到,上面每个路径都有两个UUID,第一个UUID都是E6C54E8C-3EBD-4BDD-89AB-FF9B86FDDD5E,标识的是某台模拟器设备,比如iOS 10.2 的 iPhone 7。
对于第二个UUID,标识的是对应的具体项目,比如4B09C4D0-5C25-40B2-8084-B6AE0CA79A32标识的是某个应用。层级结构非常的明显,问题在于怎么识别这些UUID。
在~/Library/Developer/CoreSimulator/Devices/目录下,有两个pist文件.default_created.plist和device_set.plist,内容差不多,后者信息更全一点,里面显示了每个UUID对应的设备型号,以及系统类型。
想要找到自己目前使用的设备的UUID,可以通过plist库,把这些数据读出来,然后指定对应的key。
allOSVersions = readPlist(devicesSetPath)['DefaultDevices']
devices = allOSVersions.get("com.apple.CoreSimulator.SimRuntime." + osVersion)
deviceId = allDevices.get("com.apple.CoreSimulator.SimDeviceType." + device)
应用UUID的获取,没有设备UUID方便,没有一个plist来统一显示每个应用对应的UUID。不过还好,这里的文件层级结构很明显,App、Extension、App group分别放在对应的文件夹下了。虽然缺少一个统一的plist来查看UUID,但是和设备UUID一样,在每个应用UUID文件夹下同样有一个plist文件,里面包含了这个UUID对应的bundleId。
我们可以遍历所有的UUID,根据BundleId找到我们需要的那个应用。
def getBundles(deviceDataPath, bundleId):
for appId in os.listdir(deviceDataPath) :
appPlist = os.path.join(deviceDataPath, appId, ".com.apple.mobile_container_manager.metadata.plist")
if os.path.isfile(appPlist) == False:
continue
appPlistDic = readPlist(appPlist)
plistBundleId = appPlistDic["MCMMetadataIdentifier"]
if plistBundleId == bundleId:
return os.path.join(deviceDataPath, appId)
return None
本脚本使用了两个工具argparse和biplist,没有安装过的可以通过以下命令安装:
pip install argparse
pip install biplist
或
sudo easy_install argparse
sudo easy_install biplist
命令行参数工具,使用了现成的库argparse,支持4个参数
➜ ./gotoDoc.py -h
usage: gotoDoc.py [-h] [-t TYPE] [-o OSVERSION] [-d DEVICE] [-b BUNDLEID]
Go to simulator documents, bundleId support partial input.
optional arguments:
-h, --help show this help message and exit
-t TYPE type: `app`,`extension`,`group`
-o OSVERSION osVersion: iOS-10-2
-d DEVICE device: iPhone-7
-b BUNDLEID bundleId: `com.hzch.gotoDoc`
t意为type,表示需要跳转的类型,不加默认为app
o意为osVersion,表示系统版本,不加默认为iOS-10-2
d意为device,表示设备型号,不加默认为iPhone-7
b意为bundleId,不加的话会根据type而使用不同默认值。
以上默认值均可以在脚本的开头指定好。
DEFAULTTYPE = "app"
DEFAULTOS = "iOS-10-2"
DEFAULTDEVICE = "iPhone-7"
DEFAULTBUNDLEIDAPP = "com.hzch.gotoDoc"
DEFAULTBUNDLEIDEXTENSION = "com.hzch.gotoDoc.shareExtension"
DEFAULTBUNDLEIDGROUP = "group.com.hzch.gotoDoc"
一切配置正常的情况下,通常只需要使用默认参数就可以直接打开对应的文件夹了。但是有的时候,我们需要跳转到非默认路径,这个时候需要输入参数,但是参数的具体值忘记的怎么办呢,比如系统版本很可能就会错误输入,比如ios10.2。
当脚本在没有找到对应的信息是,会自动把相关的信息自动打印在控制台,第二次输入基本上就不成问题了。
➜ ./gotoDoc.py -o ios10.2
[I] Open: type:app
[E] Version error!
[I] All os version:
====================
watchOS-2-2
tvOS-9-2
tvOS-10-0
tvOS-10-1
iOS-9-3
watchOS-3-1
watchOS-3-0
iOS-10-0
iOS-10-1
iOS-10-2
====================
另外由于bundleId一般比较长,而且不好记,所以bundleId支持模糊匹配,当模糊匹配项多于一条时,也会在控制台中输出。
Zsh 是一款功能强大终端(shell)软件,推荐使用。通过Zsh,可以更快的打开对应的沙盒。比如,通常我们的命令行停留在项目的根目录,笔者通常使用../python/gotoDoc.py来打开沙盒。使用Zsh,只需要输入..+ ↑就可以找到历史命令,快速执行了。
当然Zsh的功能很强大,不当当只有这么点,大家自行使用。
另外也很多其他的方法可以快速执行脚本,比如定义快捷命令,大家自行研究。
由于不能这里不支持传.py类型的文件,在文件后加了.txt,下的时候可以直接把.txt删除。
如果出现permission denied,可以加一下权限chmod +x gotoDoc.py
python经验较少,欢迎吐槽。
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者江春辉授权发布。