余额不足.

iOS提升效率的几个Tips

字数统计: 2.2k阅读时长: 7 min
2020/03/09 Share

工具篇

Crashes


Xcode内置一个强大无比的Crash收集系统,在Windows-Organizer中可以找到他。
这里收集crash的前提是触发crash的手机打开了与App开发者共享功能,这样产生的crash日志才能上传到苹果服务器上。
打开的流程为 设置-隐私-分析与改进,这里需要同时打开共享iphone分析和与App开发者共享。
Organizer下的Crashes能准确的定位到出问题的代码是哪一行,现在我们在bugly上看问题可能只能定位到哪个类的哪个方法除了问题,但是具体哪一行还需要具体分析,有时候看着该方法都觉得:“这TM哪有问题啊”,就像上图的问题,在bugly报的错是:

你只能定位到是enterChatRoom中的某个block出问题了,到底除了啥问题,是哪行代码的问题,就需要具体分析了,而Crashes点击代码后面的箭头就能指哪打哪,清晰的定位到问题所在。最终这个问题炸在了云信内部。

这个urlSession很熟悉吧,bugly上报了他无数次,在bugly中的堆栈是长成这样的:

这问题只能让我们觉得这特么是系统的urlsession有问题吗??哪段网络请求的参数出问题了吗?在没用crashes之前可能会让我们一头雾水,然后再来看看:

原来是kingfiser你小子在从中作梗!

介绍完crashes的优点后在来看看他的缺陷。
如果出问题的手机并没有打开和开发者共享数据时,他们出现的crash是不会被收集到这上面来的。但是如果碰到疑难杂症的话还是建议你到这来看看,指不定就有意外收获呢!

Safari

Web页面开发调试利器
移动端调试 webview
单纯在pc端使用手机视图模式,有时并不能保证其在 移动端浏览器/App 有一致的表现,那么要怎么调试呢?

准备工作
需要对Mac/iOS端Safari进行简单的设置

Mac Safari

iOS Safari

开始调试
调试分两种情况,web页是跑在 Safari 中还是 App 中的,但无论如何都需要先把手机和电脑连接起来(无线连接跟局域网复杂程度有关,有的时候连不上,在家里还行,在公司就别了)。

在 Safari 中打开的 web 页
比如,在手机端Safari打开 https://www.baidu.com,会看到Mac端的Safari-开发-手机-多了如下图的选项

打开后可以看到下图弹出一个常见的web检查器工具,大部分操作点我相信你们比我熟悉,在这里就提几个小技巧吧:

图中红色框的工具,点击后(呈现蓝色状态的瞄准镜),可以直接在手机上点击web元素来触发选中
当鼠标滑过web元素(如绿色框的代码)的时候可以看到手机端也会有对应的元素框标识
选中的web元素/代码/执行后的代码,后面会有 = $ ( = 0、1、2…..),可以直接的控制台使用它

在 App 中打开的 web 页
首先,需要确认你手机的App是通过开发的同学 使用Xcode直接Debug Run出来的(扫码分发下载的不支持),或者模拟器使用拖进去的包也可(但记得给检查一下模拟器的Safari的网页检查器是否打开)

Surge

相信大家都用过Charles,这兄弟在网络方面的调试非常专业,但是作为一个程序猿你怎么可以不会科学上网呢?科学上网需要通过代理来实现,然后Charles抓包同样也需要代理来实现,那这时候问题就来了,我需要同时抓包和科学上网咋整?Charles和科学上网软件同时打开注定会有一方会失败,毕竟一山不容二虎。

完美的解决方案——Surge



看图也知道这个软件有多强大了吧,而且配置简单。科学上网的话只需要在设置中托管一个链接即可,抓包也仅仅需要生成新证书-将证书安装到系统,而且还很贴心的给iOS开发者提供了给模拟器添加证书的功能。
当然他的缺点就是无法将网络断点并修改request和repsonse的内容。

iOS开发调试神器-FLEX

首先附上链接FLEX
看到这个名字你可能会先想到前端布局方式,其实他的全名叫Flipboard Explorer,是用于iOS开发的一组应用程序内调试和探索的工具。

之所以称之为神器因为它能:

  • 检查和修改层次结构中的视图。
  • 查看任何对象的属性和成员变量。
  • 动态修改属性和成员变量。
  • 动态调用实例和类方法。
  • 查看详细的网络请求历史记录,包括时间,标题和完整响应。
  • 添加您自己的模拟器键盘快捷方式。
  • 查看系统日志消息(例如来自NSLog)。
  • 通过扫描堆访问任何活动对象。
  • 查看应用程序沙盒中的文件系统。
  • 浏览文件系统中的SQLite / Realm数据库。
  • 使用控ctrrl,Shift键和Command键在模拟器中触发3D触摸。
  • 探索应用程序和链接的系统框架(公共和私有)中的所有类。
  • 快速访问对象,例如[UIApplication sharedApplication],Appdelegate,key Window上的根视图控制器等等。
  • 动态查看和修改NSUserDefaults值。


FLEX可以在开发阶段动态依附在App内。先看看大致的功能

具体它有多牛逼,实操一把你就知道了!

代码调试篇

导航栏的黑框

如果在键盘弹出的状态下侧滑返回时在导航栏和视图的中间出现了黑框的情况下,如图所示

不用想太多,直接按照以下代码操作执行即可:

1
2
3
4
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
view.endEditing(true)
}

这样侧滑返回就可以干掉出现黑框的问题,而且即使操作了侧滑返回然后又没有执行返回的操作,光标依然会回到上一次执行输入的位置

利用断点实时插入代码

除了直接在控制台通过 LLDB 调试器修改 App 状态,我们还可以通过在断点中添加命令来实现同样的功能。而且通过断点来设置调试命令的方式更加方便实用,几乎是实时插入代码的功能。
如下图,设置一个断点,通过 Edit Breakpoint… 打开编辑框,你可以将多个不同的调试命令按顺序填入 Action 中,就能实现之前同样的功能。另外你可以勾选 Automatically continue after evaluationg actions ,可以自动继续执行后续代码,而不会停在这一行。

利用 watchpoints 监听变量的变化

如果我们想监听一个变量发生变化时可以使用 watchpoints 通过监测内存的变化来监听属性的变化。
操作也很简单,在你需要监听变量初始化的地方打上断点,然后点击下图红框所示的地方即可监听值的改变。

查看视图层级

在日常调试中,使用 LLDB 命令po [self.view recursiveDescription]命令来输出页面视图结构是非常方便的,然而我们在 Swift 调用栈中使用这个命令的时候将打印以下错误:

1
2
3
4
po self.view.recursiveDescription()
error: <EXPR>:3:6: error: value of type 'UIView?' has no member 'recursiveDescription'
self.view.recursiveDescription()
~~~~~^~~~ ~~~~~~~~~~~~~~~~~~~~

因为调用的recursiveDescription为私有方法。

其实我们可以通过“expression -l objc -O – ”命令来使用 Obj-C 代码来输出我们想要的视图结构,记得self.view两边一定要加上 符号。 expression -l objc -O -- [self.view` recursiveDescription]

当然这条指令太长了,可以利用别名command alias <alias name> expression -l objc -O —-
然后使用别名直接调用即可

利用 “expression CATransaction.flush()” 命令刷新页面

你可以在控制台通过 LLDB 调试器中改变 UI 的坐标值,但你并不能立即看到页面有任何改变。事实上你确实修改了它的值,你只是需要使用“expression CATransaction.flush()”来刷新一下你的页面。
配合修改 UI 坐标值的命令一起使用,你能看到你的模拟器正在发生令人振奋的一幕。

1
2
3
4
// 修改坐标点
po unsafeBitCast(0x7fe439d13160, UILabel.self).center.y = 300
// 刷新页面
expression CATransaction.flush()
CATALOG
  1. 1. 工具篇
    1. 1.1. Crashes
    2. 1.2. Safari
    3. 1.3. Surge
    4. 1.4. iOS开发调试神器-FLEX
  2. 2. 代码调试篇
    1. 2.1. 导航栏的黑框
    2. 2.2. 利用断点实时插入代码
    3. 2.3. 利用 watchpoints 监听变量的变化
    4. 2.4. 查看视图层级
    5. 2.5. 利用 “expression CATransaction.flush()” 命令刷新页面