当我们修改了 Xcode 的配色方案后,在以下 ~/Library/Developer/Xcode/UserData/FontAndColorThemes
目录会有一个后缀名为 xccolortheme
的配置文件,将其拷贝到其它目录。重新安装 Xcode 之后再将该文件拷贝回 FontAndColorThemes
目录即可。
如果没有修改配色方案的话需要手动创建
FontAndColorThemes
目录
当然,也可以直接拷贝此目录
代码块存储在 ~/Library/Developer/Xcode/UserData/CodeSnippets
下,进入该目录可以看到每个代码块都被存储为一个文件,后缀名为 codesnippet
。
与导出字体配色方案一样,同样将相应的文件或目录拷贝到其它目录,在 Xcode 重装之后再拷贝回去。
需要注意的是,如果在将文件拷贝回去之前已经打开了 Xcode 的话,需要重新启动才可以看到相关配置
最近需要通过 Xcode 8 运行项目验证某些问题,但是发现原来正常运行的工程在 Xcode 8 上编译的时候出现了链接错误。错误提示如下:
因为直接点击无法跳转到详细的 log 页面,所以通过 右击 -> Reveal in Log
进入该页面。
进入了详细的 log 页面之后可以看到更具体的信息如下:
这里提示的是链接的过程中找不到 IOSurface
这个 Framework,进而导致了链接失败。通过一番 Google 发现这是 Xcode 9 新增的 Framework。将其从 Xcode 9 拷贝到 Xcode 8 中即解决了该问题。路径为:Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/
不过解决了该问题后又因为找不到另一个名为 FileProvider
的 Framework 而链接失败,同样从 Xcode 9将其拷贝到 Xcode 8 即可解决。
就这么水了一篇。。。
]]>通过 homebrew 安装:brew install privoxy
通过 vim 编辑配置文件
|
|
加入以下两个配置项
|
|
通过以下命令启动 privoxy
|
|
如果是通过 Privoxy官网 下载安装包进行安装,还可以通过其提供的脚本文件启动
|
|
查看是否成功启动
|
|
若成功启动可看到以下信息
查看是否监听端口
|
|
以下信息表示正在监听
启动之后并不会直接转发网络请求,还需要通过以下命令开启或关闭:
|
|
更方便的方式是在 .bash_profile
文件加入开关函数。
|
|
修改完成之后通过 source .bash_profile
使配置文件立即生效。然后可以通过以下命令进行开关:
|
|
通过 ps aux | grep privoxy
找到 privoxy 的进程 id,通过 kill
命令关闭对应的进程。
如果是通过安装包安装,可以通过其提供的脚本文件关闭
|
|
10 月底看到第三方服务商关于公司项目的性能监控报告后发现卡顿率特别高,因此在小组会议上主动提起需要对项目的流畅度进行优化,恰好老大也觉得首页列表的卡顿很严重,后来询问了我关于这个模块优化的想法之后便把这项任务交给了我。其实当时还是挺虚的,虽然看过相关的内容,但并没有实践过,不过对于一个新人来说既然有机会可以做一些业务以外的工作就得好好把握,于是硬着头皮把任务给做了下来。
优化前:
优化后:
经过查阅资料,图像显示到屏幕需要经过如上图所示的过程进行处理。
首先,CPU 把视图创建、布局计算、图片解码、文本绘制等显示内容计算好提交给 GPU;然后 GPU 对内容进行变换、合成、渲染并将渲染结果放入帧缓冲区 FrameBuffer;最后视频控制器通过垂直同步信号(V-Sync)逐行读取帧缓冲区的数据并转换后传递给屏幕显示。
iOS 设备为了提升效率使用了双缓冲机制。其原理是 GPU 先将一个渲染结果放入一个缓冲区让视频控制器读取,当下一个内容渲染完成后,GPU 会将视频控制器的指针直接指向第二个缓冲区。
但双缓冲机制会因为视频控制器读取速度与 GPU 渲染速度的不同步造成图像撕裂的情况。
为了解决这个问题,GPU 采用了垂直同步机制,即等待显示器的 VSync 信号发出后才进行新的渲染和缓冲区的更新。
双缓冲和垂直同步两种机制的使用提升了屏幕刷新的效率和画面的流畅度,但也增加了资源的消耗。
已知垂直同步机制中一个 VSync 信号产生将会引起一个新的内容计算和渲染的流程,在下一个 VSync 信号产生之前,就需要完成从 CPU 的计算到屏幕的显示这个流程。但是并不能保证每一 CPU 或者 GPU 都能够在两个 VSync 之间的时间内完成任务,而这个没有及时完成的任务将会被舍弃,此时屏幕的内容就没有被更新,所以造成了卡顿。如下图所示:
因此,我们需要从 CPU 和 GPU 在这个过程中所执行的任务入手,找到可以进行优化的地方。
CPU 执行的任务主要是:
这里每个任务都有可优化的地方,而我在优化的过程中则根据项目的实际情况对几个任务进行了优化。
由于列表中只有一个 UITableViewCell
中的一个子控件需要响应触摸事件,所以我将原来使用的 UIView
、UIImageView
等控件改为使用 CALayer
。这里主要是因为 CALyer
相对来说更加轻量,而且原来的控件有很多属性的设置其实还是在对 CALayer
进行操作。
原来项目中使用 Masonary
对控件进行布局,这在开发的时候非常方便,但是程序在运行的时候计算量很大,同时还需要对控件的 frame/bounds/center
等属性进行调整,需要消耗很多的资源进而造成性能的损失。
因此,我将自动布局改为通过 frame 布局,在获取到数据的时候提前对布局进行计算并存储到布局模型中,TableView 可以直接从布局模型获取 Cell 的高度,Cell 也可以直接获取各个子控件的位置和尺寸等信息,避免多次计算,节省资源的消耗和内存的占用。
原项目中使用 UILabel
显示文本,由于对行高有特别的要求,需要将内容处理为富文本。这些都是在 Cell 初始化的时候进行操作的,并且是在主线程操作,这对主线程造成了一定的阻塞。
由于项目中刚好引用了 YYKit
,我决定使用文本布局类 YYTextLayout
进行文本的计算和富文本的绘制并将其保存在布局模型中以供后面渲染使用;使用 YYLabel
来做文本的异步渲染,将渲染的工作放到子线程进行。既避免了阻塞主线程,还减少了使用 UILabel
时的很多计算。
因为原来项目中调整对象的操作比较少,而图片则使用了
YYWebImage
进行异步加载,所以这两处没有进行处理。
至于对象的销毁,目前并没有造成多大的影响。为了避免由于操作不当造成问题,所以没有从这个方面入手。
GPU 执行的任务是:
相对来说 GPU 执行的任务类型没有 CPU 那么多。在这个环节我从混合视图和生成图形两个方面入手进行优化。
开发过程中为了实现某些需求常常会使得一个视图上有很多个控件层叠在一起,导致视图层级太多、结构复杂。特别是对于透明的控件,GPU 需要计算多个视图混合后的效果,这个过程会消耗更多的资源。
这里我做的就是将能够组合在一起的视图绘制成富文本或者与其它视图一起合成一张图片,减少视图的层级。同时将不需要透明的视图都设置了与父视图一样的颜色,将 opaque 设置为 YES。
原项目的列表中几乎每个 Cell 都有一个圆形的图标,实现这个需求的做法是通过设置 CALayer
的 cornerRadius
和 masksToBounds
完成的。众所周知,这两个属性分开使用的时候没问题,但是一起使用的话就必定会造成离屏渲染(Off-Screen rendering)。
离屏渲染需要先在屏幕外(Off-Screen)渲染完成后再绘制到当前屏幕(On-Screen),这里需要另外分配一块内存进行渲染,而且 On-Screen 和 Off-Screen 之间的上下文环境切换的过程需要很大的开销。
网上有很多解决离屏渲染的方法,我采用了比较彻底的解决方法,直接在后台通过重绘将图片裁剪为圆角。
优化思路很简单,但是实际操作起来工作量比较大,也有不少坑,这里说一下最大的坑 CALayer
的光栅化属性 shouldRasterize
。
在调研的时候看到网上的资料说设置这个属性可以提高性能,便在优化的时候尝试了一下,将圆角图标的圆框设置了这个属性,但是结果却不尽人意。当页面出现比较多的圆角图标时,加载几页的内容之后就会变得异常卡顿,肉眼能够非常明显的感受到,FPS 也极速下降,但是通过 Time Profile 和 Core Animation 工具无法排查出问题,后来通过对控件的删减排查才知道是这个属性导致的问题。
开启 shouldRasterize
后 CAlayer
会被光栅化为位图 bitmap 保存在缓存中以备重用,可以加快渲染过程。但是使用的过程需要注意几个问题:
如图为 WWDC 2014 的内容:
而我在优化过程中犯的错误就是第一个需要注意的问题:
把添加到 TableViewCell 的 layer 进行了光栅化,而 TableViewCell 由于复用的原因需要频繁的进行重绘,对已经光栅化的内容进行了更新,导致大量的离屏渲染,所以列表的流畅度才会极速下降。
这次优化中查询了很多资料,了解到不少的原理知识,对于视图是如何绘制到屏幕上也更加了解,也更能针对性地进行分析和优化,在这个过程中也学会了如何使用 Time Profile 和 Core Animation 工具进行检测。
从这次的踩坑领悟到了不应该人云亦云,对于别人提出的东西要自己去验证是否正确、是否适合运用到自己的项目中。一旦出现无法直接判断、工具也无法排查出的问题应该要逐步去对代码进行校验定位问题所在。
WWDC心得:Advanced Graphics and Animations for iOS Apps
高性能添加图片圆角方法原理:cornerRadius,layer.shouldRasterize,layer.setShadowPath和透明图片
]]>庆哥在 README 中已经写清楚了该工具的用法,我是根据他给的步骤进行的,以下是操作步骤:
frida 的安装很简单,我是直接 Google 搜索 frida ,然后根据官网上的文档进行安装的。
frida 依赖于 python,macOS 已经自带 python 所以不需要再去安装。官网提供了两种安装的方式,我选择使用 pip 自动安装。在终端中输入以下命令回车,然后输入密码即可:sudo pip install frida
在这里我遇到了一个问题,导致安装失败。失败的提示主要是:
Operation not permitted: '/tmp/pip-uW0fNP-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'
这里是说无权限对 six 进行操作,经过一番 Google 之后在 pip 仓库的一个 issue 中找到了解决方法:即安装的时候忽略已安装的 six。
最后通过以下命令安装成功。
sudo pip install frida --ignore-installed six
这里应该是我没有关闭 SIP 而导致的问题,因为在公司的电脑上进行并没有出现这个问题。(PS:公司的电脑是从我的个人电脑迁移数据过去的,除了当时尝试全屏使用 iOS 模拟器而关闭 SIP 之外,没有其它不同的地方)
官网同时提供了针对越狱手机和非越狱手机安装的方法。这里我只是在越狱手机上进行了安装,至于非越狱的手机暂时还没有尝试。
越狱手机的安装步骤如下:
添加软件源
软件源 Sources
-> 编辑 Edit
(左上角)-> 添加 Add
(右上角)-> 输入 https://build.frida.re
通过刚才添加的软件源安装 frida 插件。根据手机进行安装:iPhone 5 及之前的机器为 32 位,5s 及之后的机器为 64 位。
两个端都安装完成之后可以用 USB 连接手机在 mac 终端中通过 frida-ps -U
命令测试,若输出手机上安装的 App 名称则说明安装成功。
有两种方式连接手机:WiFi 和 USB。WiFi 连接仅需在手机上安装 OpenSSH 即可,USB 连接还需要在 mac 上安装一个工具 iproxy。
在 Cydia 中安装即可。步骤:Cydia
-> 搜索 OpenSSH
-> 点击安装
默认用户 root 的密码是:alpine ,连接成功之后使用passwd
命令修改密码。
首先需要找到设备的 ip,在 WiFi 详情里可以看到。然后在终端中通过 ssh 连接,命令为 ssh root@ip
。
这种方式的速度比较慢一点,建议使用 USB 连接。
frida-ios-dump 要求通过 USB 连接手机
有两个工具包都带了 iproxy
libimobiledevice
usbmuxd
这两个都可以通过 homebrew 安装。安装命令为:brew install libimobiledevice
和 brew install usbmuxd
安装完成之后在终端中通过 iproxy 命令映射端口:iproxy 2222 22
,如图:
然后在另一个终端窗口中通过 ssh -p 2222 root@localhost
进行连接即可。
在终端中使用 cd
命令进入 frida-ios-dump 脚本所在的文件夹通过 ./dump.py app名称
命令即可进行砸壳。脚本运行完成之后会在文件夹中生成一个已砸壳的 ipa 文件,非常地方便。
整个过程并不难,如果本来就有逆向基础的话应该非常快就可以做完环境准备,或者说可以直接使用工具了。而我因为没有相关知识,花费了比较多的时间去 Google,不过最后成功砸壳还是挺有成就感的。同时也需要继续学习,搞清楚原理,不能停留在工具的使用上。
]]>前天在微博上看到庆哥 @Alone_Monkey 放出了一个砸壳工具就一直手痒痒想要试一下,无奈手上没有越狱机器。今天终于按捺不住把一直在吃灰的 iPhone 4s 拿了出来,上网搜了一下 4s 的 9.2.1 版本越狱。本想直接使用盘古团队的工具进行越狱,但是他们的工具并不支持 32 位版本的机器进行 9.+ 系统的越狱,最后使用了威锋上一个帖子分享的工具进行越狱。这里做一下记录。
注意:在开始越狱之前记得进行备份
将对应平台的 Impactor 和 ipa 下载完成之后,打开 Impactor 可见若正常连接的话会显示该 iPhone 的名称以及序列号。
将 MixtapePlayer.ipa 拖入上图中 install Cydia Extender 位置后点击 Start,或点击 “Device” -> “Install Package” 从目录中选择文章进行安装。
在安装开始之前,Impactor 会要求输入 Apple ID 和密码,这里注册一个新的账号比较方便,因为账号若被锁或者开启了双重认证是无法被该工具用于安装 ipa 的。
当 Impactor 成功将 ipa 安装到手机之后,我们可以在手机上看到一个名为 Home Depot 的 App。
进入“设置“->”通用“->”设备管理“,点击刚才输入的 Apple ID 进入,然后再点击“信任「Apple ID」。当我们将描述文件设置为信任之后就可以打开 Home Depot 了。
此时,我们可以看到如下界面。由于我已经越狱了,所以显示的是 Enable Jailbreak ,第一次启动显示的是 Prepare For Jailbreak 。点击 Prepare For Jailbreak 后会进入一个”协议?“的界面,此时点击 Accept 又会进入另一个界面,这里没有截图。当时我是选择了 Proceed With Jailbreak 后便进入了 Cydia 的安装界面,点击 Begin Installation 之后不要动手机,知道其自动重启。
重启进入系统之后,如果桌面上有 Cydia 的图标则说明越狱成功。(PS:没有的话可以试着重启一次,若依然没有的话就是越狱失败了。。。)
至此,我们完成了设备的越狱。越狱的过程其实很简单,会出问题的地方主要是我们提供的 Apple ID ,所以重新注册一个是最方便的方式。另外,还有一些需要注意的地方。
注意点
1、每次重启手机之后需要在 Home Depot 中重新激活越狱。即步骤 4 中图片所示,点击 Enable Jailbreak 进行激活。
2、应该大部分人都跟我一样提供的不会提供开发者账号,所以这里就跟我们在开发过程中使用免费账号 Run App 一样只有七天的使用时间。因此,每隔七天我们就需要通过电脑重新安装 Home Depot。
3、如果手机不需要关机的话,以上两个注意点可以忽略。
今天越狱完顺便玩了玩庆哥的“砸壳工具”,确实非常方便。改天再写篇文章记录一下吧!!!
]]>网上有很多关于使用 Charles 对 http 和 https 进行抓包的教程。其中唐巧大佬写的这篇Charles 从入门到精通是本人看过的较为详细的关于 http 抓包的教程,同时也介绍了很多关于 Charles 的使用,而不仅仅是简单地说明如何进行配置。
而关于 https 抓包的教程,目前本人看到的大多数教程都只适用于 iOS 9 及以下版本,在 iOS 10 及 iOS 11 系统上拦截到的请求只能看到乱码。因此,写下这篇文章做个记录。
Charles 对 https 进行抓包的配置其实很简单,只需要在原来配置 http 抓包的基础上再增加两个步骤即可。
通过选择菜单栏的 “Proxy” -> “SSL Proxying Settings”,如下图:
打开 SSL 代理设置弹窗,如下图:
勾选 “Enable SSL Proxying” -> “Add” 添加拦截的规则,如下图:
SSL 代理设置完成之后需要进行证书的安装。mac 上必须要安装证书,视情况在模拟器或手机上安装证书。
如图所示,通过选择菜单栏的 “Help” -> “SSL Proxying” -> “Install Charles Root Certificate” 在 mac 上安装证书。
注意:此处安装证书之后还需要在钥匙串中将该证书的信任状态由系统默认设置为始终信任,如下图:
模拟器安装证书非常简单,通过选择菜单栏的 “Help” -> “SSL Proxying” -> “Install Charles Root Certificate in iOS Simulators” 即可。如下图:
在手机上安装证书通过选择菜单栏的 “Help” -> “SSL Proxying” -> “Install Charles Root Certificate on a Mobile Device or Remote Browser”,如下图:
此时,Charles 会弹出提示框。提示我们需要设置代理,然后访问 chls.pro/ssl 下载证书并进行安装。
手机在连接 Wi-Fi 的情况下,通过点击 Wi-Fi 名最后的详情按钮进入详情界面,将 HTTP 代理设置为手动,并根据 Charles 的弹窗将 ip 和 端口填入。
注意:
代理配置完成之后,Charles 会弹出一个窗口提示是否信任手机 ip 的请求,此时应选择 “Allow”,如下图:
代理设置完成之后,通过 Safari 访问 chls.pro/ssl 即可下载证书,证书下载完成时会弹出安装证书的窗口,点击安装即可。如下图:
注意:
以上模拟器和手机安装证书的步骤适用于 iOS 9 及以下的系统,也是网上很多教程包含的内容。
在 iOS 10 和 iOS 11 系统上我们还需要进行证书信任设置,这个选项比较隐蔽,通过以下步骤进入:
设置 -> 通用 -> 关于本机 -> 证书信任设置
找到 Charles 的证书,打开信任开关即可。如下图:
总而言之,在配置的过程中特别注意 iOS 10 和 iOS 11 系统上还需要在关于本机中进行证书信任设置。
到此为止我们就可以进行 https 抓包了。