<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>IOS on 山行小记</title>
    <link>https://ruijingan.pages.dev/tags/ios/</link>
    <description>Recent content in IOS on 山行小记</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <copyright>@2025</copyright>
    <lastBuildDate>Tue, 21 May 2019 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://ruijingan.pages.dev/tags/ios/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>iOS 组件化改造：从私有 pod 源开始</title>
      <link>https://ruijingan.pages.dev/posts/2019/ios-component-architecture/</link>
      <pubDate>Tue, 21 May 2019 00:00:00 +0000</pubDate>
      <guid>https://ruijingan.pages.dev/posts/2019/ios-component-architecture/</guid>
      <description>&lt;p&gt;App 三岁了，单工程 40 万行代码，全量编译要 15 分钟，改一行代码喝杯水回来才能跑真机。终于说服老板让我们做组件化。这篇记录前期的方案取舍，给后来人省点力气。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;先说结论：不要一步到位上&amp;quot;总线&amp;quot;架构。&lt;/strong&gt; 网上流传的组件化方案大多是 CTMediator 那一派，运行时解注册表调用。演示很漂亮，但真落地会发现调用关系全靠字符串，IDE 跳转变瞎，重构基本靠全局搜索。我们最后的方案保守得多：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;底层工具库（网络、缓存、埋点）拆成独立的私有 pod，用 &lt;code&gt;cocoapods-packager&lt;/code&gt; 发到自建的私有源；&lt;/li&gt;
&lt;li&gt;业务模块先只在物理上拆目录，通过 protocol 文件互相依赖，暂时不做运行时解耦；&lt;/li&gt;
&lt;li&gt;主工程退化为一个壳，只负责组装 tab 和路由。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个方案跑了半年，编译时间从 15 分钟降到 4 分钟（业务模块可以用 &lt;code&gt;pod install&lt;/code&gt; 之后按需引入调试），虽然没到网上吹的&amp;quot;秒级编译&amp;quot;，但对日常开发体验的提升已经非常明显。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;私有源的坑。&lt;/strong&gt; 自建源用的是 nexus，权限管理一塌糊涂，最后是靠 git tag + CI 校验版本号一致性来保证不出乱子。后来听说公司内部有 Artifactory 的 license，就迁过去了，省心很多。建议准备做组件化的团队先解决制品库的问题，工具链不顺手，组件化推行不下去——这不是技术问题，是工程习惯问题。&lt;/p&gt;
&lt;p&gt;下一阶段的计划是把业务模块间的 protocol 依赖收敛到一个独立的接口层仓库里，谁改接口谁发版。半年后 hopefully 能再写一篇续集，写写中间件方案到底要不要上。&lt;/p&gt;</description>
    </item>
    <item>
      <title>从 Objective-C 到 Swift：一次不太顺利的迁移</title>
      <link>https://ruijingan.pages.dev/posts/2018/objc-to-swift-migration/</link>
      <pubDate>Thu, 12 Apr 2018 00:00:00 +0000</pubDate>
      <guid>https://ruijingan.pages.dev/posts/2018/objc-to-swift-migration/</guid>
      <description>&lt;p&gt;公司的主 App 跑了三年多 Objective-C，今年年初终于下定决心往 Swift 迁。原计划三个月迁完，实际用了五个多月，中间踩的坑值得记一笔。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要想着一次性迁完。&lt;/strong&gt; 我们最初的方案是新开一个 Swift 分支，集中人力把旧代码全部翻译一遍。干了两个星期就发现这条路走不通：业务需求不会停，分支落后主干越来越多，合并冲突解到怀疑人生。后来改成混合编译，新的模块用 Swift 写，旧的 OC 代码按模块逐步迁，才把节奏理顺。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;bridging header 是个大坑。&lt;/strong&gt; 项目里如果既有 OC 引用 Swift，又有 Swift 引用 OC，Xcode 的报错信息基本不可读。我们最后的经验是：所有 OC 头文件里用到的第三方类型，尽量在 pch 里收口，别让 Swift 端直接碰到太深的头文件链。&lt;/p&gt;
&lt;p&gt;还有一个血泪教训：Swift 4.2 之前 API 变动太剧烈了，我们迁移中途 Swift 4.1 发布，&lt;code&gt;#selector&lt;/code&gt; 和 KVO 相关的写法改了不少，又返工了半个月。现在回头看，选对版本窗口期很重要，大版本发布前千万别开迁。&lt;/p&gt;
&lt;p&gt;代码示例没什么好贴的，唯一想留的是这条规律：&lt;strong&gt;迁移期间新代码的 code review 强度要加倍&lt;/strong&gt;。Swift 写起来太舒服，新人很容易在 optional 处理上放飞自我，&lt;code&gt;!&lt;/code&gt; 满天飞。我们在 CI 里加了 SwiftLint 的 &lt;code&gt;implicitly_unwrapped_optional&lt;/code&gt; 规则之后，线上 crash 率才慢慢降下来。&lt;/p&gt;
&lt;p&gt;总结：迁移本身不难，难的是在业务不停的情况下迁。如果重来一次，我会在开始前先把模块依赖关系理清楚，从依赖最少的叶子模块开始迁，而不是按页面从上往下迁。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
