CocoaPods和Localization
一直没有很好地理清 CocoaPods 对图片、NIB等资源的管理方式,趁着跟进 “智齿” 国际化失效问题,摘录下浏览的相关资料。另外吐槽下 “智齿”, 这家的 iOS SDK 是我目前集成的所有 SDK 中,对开发者最不友好的了。
问题来了:在使用 CocoaPods 集成“智齿”后,“智齿”的国际化信息就一直显示英文版本,即使系统语言设置成中文。但是如果不通过 CocoaPods,直接把 SDK 拉进工程中,国际化信息就又生效了。在咨询其开发人员无果后,只能自己慢慢排雷了。由于问题只在 “通过 CocoaPods 引入 SDK” 这种情况下出现,所以要想彻底解决这个问题,就需要明确 CocoaPods 是如何对国际化资源进行管理的。
给 APP 添加悬浮助手
自组内力推业务组件化以来,项目组的业务组件数量也渐具规模。虽然在版本依赖和个别组件独立性等细节上略有欠缺,但是在一定程度上还是提升了开发效率。
既然是业务组件,在某些场景下就需要登录获取相关权限后才能进一步操作。由于项目中登录模块并没有重构过,代码风格和书写逻辑极差,加上针对 B 端的 APP 登录逻辑较为复杂,包括切店等一系列操作,导致给客户使用的登录逻辑界面,在开发阶段难以接入业务组件,即使接入了,使用体验(没错,开发时也讲究一个体验)和开发效率也是会打一定折扣。
那么问题来了,在开发阶段,怎样做才能让业务模块更加简便、优雅、无侵入地接入登录功能呢?进一步讲,如果不局限于登录功能,如何给业务模块提供通用工具入口?
使用usbmuxd连接越狱设备
最近通过 wifi ssh 到越狱设备上时,出了个奇怪的问题:
ssh 一直不结束,没提示成功,也没有提示失败。
下面是自己对越狱设备进行“自测”的过程:
操作 | 结果 |
---|---|
iOS ssh mac ip | 成功 |
iOS ssh localhost | 成功 (sshd 是跑起来的) |
iOS ssh 自身 ip | 失败 |
mac ssh iOS ip | 失败 |
上面的失败是指没有返回 ssh 的结果,一直卡在连接阶段。
如何愉快地使用命令行
古人云:
工欲善其事,必先利其器
从进入软件开发这一行业开始算起,我也算是陆陆续续地接触了三大主流操作系统。虽说不是很深入地使用过每个系统,但从自己的个人喜好及以往的使用经历来看, Mac 无疑是对开发者最友好的一个系统。
不过即便如此,作为一个 Vim 爱好者,我还是非常怀念当初在 Ubuntu 字符终端下编写代码的那种畅(zhuang)爽(bi)感,那种双手不需要离开键盘的紧凑感。
好的工具配置,既能极大地促进开发效率的提升,又能让开发者保持一个心情愉悦的状态。下面纪录下自己常用的一些工具软件,这些软件能减少让开发者对触控板 / 鼠标的依赖。
NSJSONSerialization和NSNumber的事故现场
最近同事在和后台联调时,出现了一个诡异的问题:后台传输的价格为 0.07 ,但是到了 iOS 这边,就变成了 0.07000000000000001 。奇怪的是安卓端并没有此问题,并且从 charles 抓包内容来看,后台传输的价格确实是0.07。
在排除了业务层转化因素后,我们进入了 AFNetworking 框架内部,看能不能找到一点线索,然后就定位到了以下方法:
1 | - (void)URLSession:(__unused NSURLSession *)session |
在拿到原始的 data 后,我尝试在调试终端使用 NSJSONSerialization 对其进行反序列化,结果发现价格在这里已经变成了 0.07000000000000001 。
众所周知,由于计算机无法精确存储浮点数,实际上存储的浮点型变量实际数值就是取范围允许内最接近的值,也就是上面接收到的那样。(注:Float who stole your accuracy)
难道是 NSJSONSerialization 在反序列化的时候出了问题?
利用runtime兼容老代码小记
通常来说,在项目的初期,因为各种原因,要么人力不够,要么项目周期过紧,会产生难以维护、阅读性较差的代码。而这种代码,我习惯称之为“老代码”。就比如现在手上的项目,初期是由一个被迫转到 iOS
的后端 java
哥们写的,所以工程里面到处都可以看见 java
的一些编码风格,比如模型以 Vo
结尾、接口以 I
开头等,甚至转场动画都是简单粗暴地通过 view
叠加再辅以动画实现的。“老代码”是项目特定时间段的产物,因此,也不能把锅全部推给写这些代码的人。不过前人埋坑,后人总得填啊。
好了,吐槽完毕,开始正题。
Objective-C使用范型实现map提示
在当前项目的一些内容加工逻辑较多的界面,我会使用ViewModel
来对Model
进行一层包装,这样可以保持Model
的纯净,也可以减少Controller
中弱逻辑代码的堆叠。当然,部分公用内容也是可以通过给Model
添加分类来实现的,ViewModel
更多是提供特定页面的定制化内容。
由于项目并没有采用MVVM
模式,也就没有引入ReactiveCocoa
,所以项目里面比较多这样的代码:
1 | NSArray <TBVEmployee *> *employees = @[[TBVEmployee new]]; |
这段代码主要是为了将Model
转化成ViewModel
。
一次短暂的mac开发之旅
回杭近一周,发现公司后台写的接口文档还是比较清晰的。特别是自己组负责的业务线,接口文档上的字段和实际返回的字段几乎没有差别。
询问了周围小伙伴如何写模型文件之后,发现无非三种方式:
- 手写啦==
Xcode8
以前的用ESJsonFormat
插件,Xcode8
以后手写- 用
JSONExport
生成
针对以上三种方式,我做了一个简短的分析:
- 这个不用说了,耗时费力不讨好。量少好说,量大就比较蛋疼了。
xcode8
之后,第三方插件被禁止了。虽说有方法能让xcode8
重新用上这个插件,但是即使用上了这个插件,还是需要自己写注释,并且生成模型需要后台返回的json
。- 和上一个方式一样,只是从插件编程了
mac
软件
在打听完后,我随即产生了自己写一个转换工具的想法。
原因如下:
- 后台文档已经写的比较清晰,可以从网页上把这些数据都爬下来,然后生成含有注释的模型
- 可以自动将
Vo
结尾的模型和属性,转成Model
结尾的模型和属性,并且生成YYModel
需要的映射关系 - 因为接口文档都处于一个统一的
baseURL
下,加上模型名称就是完整路径,所以可以很方便地进行批量处理 - 不需要测试后台发布的接口后,再通过获取接口返回的
json
生成模型;只要接口文档一发布就可以生成模型