[关闭]
@wrlqwe 2015-12-21T01:12:47.000000Z 字数 2381 阅读 1327

iOS开发中的统一资源管理工具 R.swift 解析

开发 iOS开发


在iOS开发中,资源管理是一个很让人头疼的问题,我们常用下面的代码来创建资源实例:

  1. let icon = UIImage(named: "settings-icon")
  2. let font = UIFont(name: "San Francisco", size: 42)
  3. let viewController = CustomViewController(nibName: "CustomView", bundle: nil)

这在开发时留下了很大的隐患,一次错误的键入要等到运行时才能发现,在swift中一次失败的转换甚至会导致应用程序崩溃:

  1. let icon = UIImage(named: "settings-icon")!

R.swift就为了应对这个问题而生,下面是它的使用:

  1. let icon = R.image.settingsIcon
  2. let font = R.font.sanFrancisco(size: 42)
  3. let viewController = CustomViewController(nib: R.nib.customView)

所有的实例都由静态的类型实例产生,甚至可以达到自动完成的效果
autocompleteofrswift
这能给我们的开发带来巨大的便利,更高效率同时减少失误。

下面我将尝试解析它的实现思路。

R.swift 扫描了项目中所有的资源,并且生成 R.generated.swift 文件存储资源;
在 xcode 的 build phases 里执行扫描脚本,更新资源,确保资源的准确性。

R.generated.swift文件结构如下
r.generated.swift
R.swift 通过 struct 来组织类型和变量。

在main.swift里定义了 R.generated.swift 的全部结构

  1. let fileContents = [
  2. Header,
  3. Imports,
  4. externalStruct.description,
  5. internalStruct.description,
  6. ReuseIdentifier.description,
  7. StoryboardSegueIdentifier.description,
  8. TypedStoryboardSegueInfo.description,
  9. NibResourceProtocol.description,
  10. ReusableProtocol.description,
  11. ReuseIdentifierUITableViewExtension.description,
  12. ReuseIdentifierUICollectionViewExtension.description,
  13. NibUIViewControllerExtension.description,
  14. SegueUIViewControllerExtension.description,
  15. UIStoryboardSegueExtension.description,
  16. ].joinWithSeparator("\n\n")

其中 externalStruct 生成了使用中的大部分资源文件,它扫描了整个目录,生成了包括 image, font, segue 等 struct 。

  1. structs: [
  2. imageStructFromAssetFolders(resources.assetFolders, andImages: resources.images),
  3. fontStructFromFonts(resources.fonts),
  4. segueStructFromStoryboards(resources.storyboards),
  5. storyboardStructAndFunction.0,
  6. nibStructs.extern,
  7. reuseIdentifierStructFromReusables(resources.reusables),
  8. resourceStructFromResourceFiles(resources.resourceFiles),
  9. ]

除了这些,rswift对storyboard的验证里加入了如下语句:

  1. let validateImagesLines = Array(Set(storyboard.usedImageIdentifiers))
  2. .map { "assert(UIImage(named: \"\($0)\") != nil, \"[R.swift] Image named '\($0)' is used in storyboard '\(storyboard.name)', but couldn't be loaded.\")" }
  3. let validateImagesFunc = Function(isStatic: true, name: "validateImages", generics: nil, parameters: [], returnType: Type._Void, body: validateImagesLines.joinWithSeparator("\n"))

它会生成storyboard的资源验证代码
storyboard validate

也增加了对UITableView和UICollectionView的支持, 生成的代码帮助推导出正确的cell:
tableView

Rswift能带来很大的便利,但是还是有一点局限性
1. 如果新导入了资源,那只有在编译一次后,才会有正确的提示,因为build phases 是在编译阶段执行的
2. 生成的R.generated.swift需要手动添加到build sources里
3. 现在生成的代码是swift的,不能在OC里使用

其中,第一条属于编译器的硬伤,应该没什么改进空间;
第二条编辑配置文件,可以进行改进,好在只是第一次需要手动添加;
第三条应该可以生成class的类型来兼容OC,也是可以改进的,但是有关类型推导的拓展部分,因为OC的语言特性,很难完全兼容。

以上就是我的Rswift的分析,谢谢观看。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注