iOS
9.2k 词
iOS编译优化方案探索与实践-组件篇序言目前主流的项目构建方案中几乎都使用cocoapods进行组件库管理,不论是第三方开源库还是自研的私有库,都会生成.podspec文件使用cocoapods工具进行维护。 为了便于进行调试,第三方开源库或私有代码库 我们都以源码的方式进行引入。 每次在本机进行全量编译或者ci机器进行打包的时候都会先编译pod仓库中的源代码,然后链接到主项目中。 这个流程没有问题,但是随着项目的的大量迭代和长时间维护,引入的仓库会越来越多。以我们的项目为例,项目迭代了3年左右,引入的第三方仓库达到了30+个。在我的mac上进行一次全量编译时间达到了500s,性能稍差的设备编译消耗的时间更长。 针对组件库的编译时长的优化方案很简单,把cocoapods仓库中引入的需要编译的源码改成不需要编译的二进制库即可。 当然一刀切的引入方式切换是不可取的,根据自身的实际情况,对一些基本不会进入调试的代码和一些稳定版本的常用的仓库进行二进制化较为合适。 针对以上想法有了一些cocoapods插件可以使用。 Cocoapods-Binarycocoapods 1.6.x版本的时...
iOS
1.3k 词
最近Xcode编译完成后在命令行框里第一行总会报一个错误: error: module importing failed: invalid pathname 不论是clean还是删除support文件还是重启Xcode都无法解决这个问题。 于是去google了一番: 把target的scheme中的debug executable的选项取消掉就不报这个错了 试了一下,有效!但是这个选项不能去掉啊,去掉了这个选项就不能打断点进行调试了。😂 Realm删除残留导致的问题?](https://stackoverflow.com/questions/59090655/removed-realm-but-still-getting-this-error-module-importing-failed-invalid-to/59094519#59094519?newreg=5c6ce4372354468b9449dfc34406e472) 看到朋友们删除Realm之后会出现这个问题,但是我又没有安装过Realm,为何也有这个问题呢。 回答中提到解决这个问题需要去编辑~/.lldbi...
iOS
4.7k 词
需求背景近期老板提出了某些需求可能需要借助OCR能力来进行图片到文本的转换。 以下几种方案是对当前可用的免费的OCR的调研。 Vision Vision 是 Apple 在 WWDC 2017 推出的图像识别框架,它基于 Core ML,所以可以理解成 Apple 的工程师设计了一种算法模型,然后利用 Core ML 训练,最后整合成一个新的框架,相比开源模型然后让开发者自己整合起来,这种方式更安全也更方便我们使用。 Overview The Vision framework performs face and face landmark detection, text detection, barcode recognition, image registration, and general feature tracking. Vision also allows the use of custom Core ML models for tasks like classification or object detection. 从官方文档中可以得到Vision框架能做的...
iOS
675 词
Bug:音频列表顺序播放过程中偶尔出现设置的1.5倍速重置为1 原因:音频流卡顿暂停并缓冲到了足够可以继续播放的buffer长度后响应playbackLikelyToKeepUp 事件中 手动调用了 player.play() 方法播放音频 12345678if keyPath == "currentItem.playbackLikelyToKeepUp" { if let item = currentItem, item.isPlaybackLikelyToKeepUp, playStatus == .loading, isPlayerActive { playStatus = .playing player.play() // 播放之后需增加设置rate的步骤 rate = CGFloat(UserDefaultManager.manager.getAudioRateValue()) }} 查看文档可以看到play方法等同于 player.rate = 1,故而导致音频的速率变成了1 ...
iOS
1.7k 词
今天整理了最近半年内使用频率高的一些代码,做了一些代码块 codesnippet使用,并在github上创建了一个私有仓库用来云端维护和同步,写了一个脚本进行代码块下载和合并。 创建方式: 选中要创建的代码块,右键选择Create Code Snippte 右上角 +框快速查看系统和自定义代码块 填写代码块描述,以及快捷方式,修改代码块 xcode中用户自定义的 代码块保存在~/Library/Developer/Xcode/UserData/CodeSnippets路径下,每个代码块都是一个.codesnippet格式的配置文件。 1234567891011~/Library/Developer/Xcode/UserData/CodeSnippets$: ls -ltotal 72-rw-r--r-- 1 zcx staff 1008 Aug 25 19:36 1BF011CF-9292-4B72-9D44-F7C3BC89AFE0.codesnippet-rw-r--r-- 1 zcx staff ...
iOS
9.7k 词
一个小问题引起的思考最近做一个输入框粘贴插入文字的需求时遇到了一个问题: 输入框中输入了文字和表情符😃😃😃(emoji)计算出的光标location和实际感官上的字符个数不一致,最后导致文字插入的位置不对。 这是为什么呢? 查阅资料发现是Unicode编码和UTF-16编码的设计特点导致的此现象。 字符和字素簇定义说明 Characters and Grapheme Clusters It’s common to think of a string as a sequence of characters, but when working with NSString objects, or with Unicode strings in general, in most cases it is better to deal with substrings rather than with individual characters. The reason for this is that what the user perceives as a character in...
iOS
3k 词
NSCacheIntroduction A mutable collection you use to temporarily store transient key-value pairs that are subject to eviction when resources are low. 一种用于临时存储临时键值对的可变集合,在资源不足时容易被回收。 Cache objects differ from other mutable collections in a few ways:The NSCache class incorporates various auto-eviction policies, which ensure that a cache doesn’t use too much of the system’s memory. If memory is needed by other applications, these policies remove some items from the cache, minimizing its memory ...
iOS
10k 词
自iOS8之后,苹果支持了扩展(Extension)的开发,开发者可以通过系统提供给我们的扩展接入点 (Extension point) 来为系统特定的服务提供某些附加的功能。但iOS14后,苹果更新了扩展组件,引入了新的UI组件:WidgetKit 而舍弃了iOS14以下版本的Today Extension组件 Widget介绍这里有一份官方的小组件使用指南 简单来说:小组件相当于一个动态程序入口,在有限的空间内展示你想看到的重要的信息 苹果自带的日历使用起来非常不适,下载第三方日历又不想被捆绑的无用功能打扰。有了小组件之后这个问题就很好的解决了,比如上面的日历小组件,清晰的展示了今天的日期和农历以及周几,打开手机锁屏就能看见。 此外系统自带的电量小组件,方便的展示了需要下滑去状态栏才能看到的耳机电量: 之前发布的时候觉得这都是安卓系统玩剩下的东西,没什么卵用,不过现在是真香! Widget设计指南这里有一份官方的设计指南 简而言之,设计一个简单漂亮吸引人并且快速显示内容的小组件。 Widget: HelloWorld这里有一份官方的开发文档可以参考 一个小组件...
iOS
2.1k 词
APP内部代理 wifi的代理配置不会自动保存?使用iPhone的大概都遇见过这种事情: 每次需要给APP抓包的时候都需要到设置-WIFI-下手动配置代理,然而当我们连着代理的时候无法访问App Store或其他禁止代理的服务,这个时候我们会把WIFI的代理给关闭。 弄完杂七杂八的东西之后回到抓包调试,打开WIFI设置页,手动配置代理… ??? 我刚才填的本机IP和端口呢?我还得再输一次?WTF! 解决方案一弄两个wifi信号,一个挂笔记本的代理不关,另一个正常联网,需要切换代理的时候切换wifi。 说实话操作起来挺麻烦的,并且公司只有一个公用的wifi信号,想弄一个新的信号还需要运维小伙伴来搞,难顶。 解决方案二安装VPN软件,配置本地代理规则,需要抓包的时候打开网络代理。 小火箭之类好用的软件需要美区账号安装,每个测试机都可能会有这个需求,不可能每个测试机都这么操作一遍。 解决方案三APP内部通过代码设置代理,只在APP内部生效,开发环境使用,可持久化配置文件。 去goole了一圈,发现URLSessionConfiguration 中有个字典专门保存代理信息conn...
iOS
1.2k 词
从一个问题开始Runloop 和线程有什么关系? Runloop 和 线程是密不可分的,可以说Runloop是为线程而生的。线程和runloop是一一对应的,我们只可以在当前线程内操控当前线程对应的Runloop。 Runloop是懒加载的在线程第一次获取他的时候创建,在线程结束的时候销毁。 主线程的runloop是默认启动的,因为主线程需要一直监听事件。子线程的Runloop默认是不启动的,需要手动开启循环。 Runloop 的作用?保持程序的运行,主线程的runloop使得APP不会退出 响应并处理APP中的事件,用户交互、定时任务等 节省cpu资源,按需运行,提升程序性能 Runloop的运行过程Run Loop本质是一个处理事件源的循环。我们对Run Loop的运行时具有控制权,如果当前没有时间发生,Run Loop会让当前线程进入睡眠模式,来减轻CPU压力。如果有事件发生,Run Loop就处理事件并通知相关的Observer。具体的顺序如下: Run Loop进入的时候,会通知Observer Timer即将被触发时,会通知Observer 有其它非Port-B...