美文网首页Swift
[iOS Resource] 包/Bundle

[iOS Resource] 包/Bundle

作者: ThomasRobot | 来源:发表于2016-11-03 22:36 被阅读2124次

    Apple uses bundles to represent apps, frameworks, plug-ins, and many other specific types of content. ——from developer.apple.com
    苹果用“包”来表示应用、框架、插件以及其它一些特定类型的内容集合。

    关键字:/iOSSwift/Bundle/Framework/Resource FileInfo.plist


    先看代码

    开发过程中我们会调用这样的代码:

    // Swift 2.2
    // Get the app's main bundle
    let mainBundle = NSBundle.mainBundle().path(forResource: FILE_NAME, ofType: FILE_TYPE)
    
    // Swift 3.0
    // Get the file path of the resource file
    let filePath = Bundle.main.path(forResource: FILE_NAME, ofType: FILE_TYPE)
    

    「Bundle」是「Foundation」中定义的类,是用于开发者获取资源文件的一个接口。

    了解概念

    除了Bundle表示「包」以外,还有个单词Package也是「包」,这两者在Apple的定义中拥有不同的含义。

    • Bundle:是一个具有标准层级结构的目录,该目录包含可执行二进制代码,以及相关的资源文件。
    • Package:是一个以单一文件呈现的目录。

    相对与「Package」而言,「Bundle」更像是一个有组织有预谋的东西。

    设计总是伴有目的性的,「Package」存在的目的是用来提升用户体验的,而「Bundle」的目的则是用来提升开发者体验的。

    围绕提升开发者体验来看,苹果为不同平台不同的内容提供了不同的「Bundle标准」,开发者无需手动去构建一个项目的「Bundle」,通过Xcode创建项目即自动会生成相对应的「Bundle」(通过Makefile打包项目例外)。当然,每个「Bundle」有其必要的组成文件,开发者仅需在项目中添加和修改资源文件,而无需手动管理这些文件,同时在代码中引用这些资源文件也是通过Foundation框架中的Bundle类作为接口获取这些资源文件。

    从物理文件的角度来看,一个项目的所有文件包括可执行代码都被按照既定的「Bundle标准」打包好,all in one,简洁明了,便于使用。从操作系统的角度来看,系统(OS X/iOS)自然知道「Bundle」是按怎样的标准打包的,因此可以解析其中的资源文件以及调用包中的可执行程序,这也是为何你双击一个「Bundle」程序就启动的原因,虽然它们从本质上来看都只是文件夹而已。从程序代码的角度来看,所有的资源文件都是按既定标准乖乖呆在某个地方,而开发者并不用关心具体的文件在哪以及如何调用,因为这样的设计必然包含了程序上的接口,也就是Foundation框架中定义的「Bundle」类(在此之前是NSBundle,在Swift3后改成了Bundle),使用Bundle类定义的接口就可以更友好地引用资源文件了。

    包结构/Bundle Structure

    iOS的包结构如下所示:

    MyApp.app
       MyApp
       MyAppIcon.png
       MySearchIcon.png
       Info.plist
       Default.png
       MainWindow.nib
       Settings.bundle
       MySettingsIcon.png
       iTunesArtwork
       en.lproj
          MyImage.png
       fr.lproj
          MyImage.png
    

    从以上包结构可以看出,这样设计的目的之一是解决本地化资源文件的引用问题。把本地化资源引用交给系统自动化处理即可,开发者无需关心其细节。

    除此之外,每个iOS的「Bundle」都包含了Info.plist文件,这也是「Bundle标准」中定义必须要有的,该文件其实是个配置文件,供操作系统和开发者使用。因为有了这个「Bundle标准」,也才使得可以在Runtime通过「Bundle类」来获取程序相关配置项。

    Tip:获取配置项

    了解「Bundle」是为了更好地使用「Bundle」,在此之后写「Bundle」相关代码的时候应该能少不少疑惑。

    程序的很多配置项都是在Info.plist中定义的,那如何获取相关配置项呢?

    let nameSpace = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable")
    let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
    
    // 很多代码中会使用 Bundle.main.infoDictionary[CONFIG_NAME]的方法获取配置项,这也是可行的
    // 只不过苹果开发文档中更推荐上面代码中的接口
    

    PS:通常在Xcode中查看Info.plist文件显示的并非真实的配置项字符串,查看真实配置项字符串可以通过Ctrl+配置项,然后在弹出菜单中选择Show Raw Keys/Values,如下图所示:

    Show Raw Keys/Values

    关于「Bundle」相关API详细使用,可查看官方文档:Bundle Class Reference

    总结

    说了这么多,总结下就是苹果设计了「Bundle」这个东西来解决来一堆本来开发者需要自行解决的问题,但前提是开发者必须先知道啥是「Bundle」。

    「Bundle」其实是iOS开发中比较重要的一个概念,刚开始iOS开发时可能并不会接触到这个概念,或许在copy代码的过程中接触到了,但也没深入理解过。但作为一个程序员而不仅仅是代码的搬运工,理解它并利用好它是我们的职责。所以我抽空上开发者官网简单看了眼这个「Bundle」的概念,然后做了这个记录。

    参考:Bundle Programming Guide

    相关文章

      网友评论

        本文标题:[iOS Resource] 包/Bundle

        本文链接:https://www.haomeiwen.com/subject/yveiuttx.html