Bundle Programming Guide (一)

介紹

捆綁是macOS和iOS中用于封裝代碼和資源的基礎技術。軟件包通過為所需資源提供已知位置來簡化開發人員體驗,同時減少創建復合二進制文件的需要。相反,捆綁包使用目錄和文件來提供更自然的組織類型,也可以在開發和部署過程中輕松修改。

為了支持bundle,Cocoa和Core Foundation都提供了用于訪問bundle的內容的編程接口。由于捆綁包使用有組織的結構,因此所有開發人員都了解捆綁的基本組織原則很重要。本文檔為您提供了解軟件包的工作原理以及開發過程中如何使用它們來訪問資源文件的基礎。

本文檔的組織

本文檔包含以下章節:

關于Bundles介紹了bundle和packages的概念,以及系統如何使用它們。
捆綁結構描述了標準捆綁類型的結構和內容。
訪問Bundle的內容顯示如何使用Cocoa和Core Foundation界面來獲取有關bundle及其內容的信息。
文檔包描述了文檔包(與捆綁松散相關)以及如何使用它們的概念。

雖然本文檔中的信息適用于所有類型的軟件包,但如果您使用更專門的軟件包(如框架和插件),則還應參考以下文檔:

框架編程指南提供了有關創建和使用自定義框架的詳細信息。
代碼加載編程主題提供有關使用Objective-C語言編寫插件的信息。
插件提供了有關使用C語言編寫插件的信息。

關于捆綁

捆綁是在MacOS和iOS中提供軟件的便捷方式。捆綁包為終端用戶提供簡化的界面,同時為開發提供支持。本章介紹捆綁包,并討論他們在macOS和iOS中的作用。

軟件包和軟件包

雖然捆綁包和包裹有時被稱為可互換的,但它們實際上代表著非常不同的概念:

是Finder向用戶呈現的任何目錄,就像它是單個文件一樣。
捆綁包是具有標準化層次結構的目錄,其中包含可執行代碼和該代碼使用的資源。
軟件包提供了使MacOS易于使用的基本抽象之一。如果您查看計算機上的應用程序或插件,您實際查看的是一個目錄。軟件包目錄中是使應用程序或插件運行所需的代碼和資源文件。然而,當您與包目錄進行交互時,Finder將其視為單個文件。此行為可防止臨時用戶進行可能會對軟件包內容產生不利影響的更改。例如,它阻止用戶重新排列或刪除可能阻止應用程序正常運行的資源或代碼模塊。

注意:即使軟件包默認為不透明文件,用戶仍然可以查看和修改其內容。在包目錄的上下文菜單中是“顯示包內容”命令。選擇此命令將顯示一個新的Finder窗口,設置為包目錄的頂層。用戶可以使用此窗口來導航包的目錄結構,并進行更改,就像它是常規目錄層次結構一樣。
而軟件包可以改善用戶體驗,捆綁更適合幫助開發人員打包他們的代碼,并幫助操作系統訪問該代碼。軟件包定義用于組織與您的軟件相關聯的代碼和資源的基本結構。這種結構的存在也有助于促進諸如本地化之類的重要特征。 bundle的確切結構取決于您是創建應用程序,框架還是插件。它還取決于其他因素,如目標平臺和插件的類型。

捆綁包和包有時被認為是可互換的原因是許多類型的包也是包。例如,應用程序和可加載的軟件包是軟件包,因為它們通常被系統視為不透明目錄。但是并不是所有的bundle都是包,反之亦然。

系統如何識別捆綁包和包

如果滿足以下任一條件,則Finder將目錄作為包:

該目錄有一個已知的文件擴展名:.app,.bundle,.framework,.plugin,.kext等。
該目錄具有一些其他應用程序聲明代表包類型的擴展名;請參閱文檔包。
該目錄的包的位設置。
指定包的首選方法是給包目錄一個已知的文件擴展名。在大多數情況下,Xcode通過提供適用正確擴展名的模板來為您提供幫助。所有你需要做的是創建一個適合類型的Xcode項目。

大多數捆綁包也是包。例如,應用程序和插件通常由Finder顯示為單個文件。但是,對于所有捆綁類型都不是這樣。特別地,框架是一種捆綁,它被視為單個單元,用于鏈接和運行時使用,但框架目錄是透明的,以便開發人員可以查看頭文件及其包含的其他資源。

關于Bundle顯示名稱

顯示名稱給用戶一些控制包和包在Finder中的顯示,而不會破壞依賴它們的客戶端。而用戶可以自由重命名文件,重命名應用程序或框架可能導致相關代碼模塊通過名稱引用應用程序或框架中斷。因此,當用戶更改包的名稱時,更改只是表面的。 Finder不是在文件系統中更改包名稱,而是將一個單獨的字符串(稱為顯示名稱)與捆綁包相關聯,并顯示該字符串。

顯示名稱僅供用戶使用。您永遠不會使用顯示名稱來打開或訪問代碼中的目錄,但是在向用戶顯示目錄的名稱時,請使用它們。默認情況下,捆綁包的顯示名稱與捆綁包名稱本身相同。但是,在以下情況下,系統可能會更改默認顯示名稱:

如果捆綁包是應用程序,則Finder在大多數情況下隱藏.app擴展名。
如果軟件包支持本地化顯示名稱(并且用戶尚未明確更改軟件包名稱),則Finder將顯示與用戶當前語言設置相匹配的名稱。
盡管Finder大部分時間都會為應用程序隱藏.app擴展名,但它可能會顯示它以防止混淆。例如,如果用戶更改應用程序的名稱,并且新名稱包含另一個文件擴展名,則Finder將顯示.app。擴展,以清楚該捆綁是一個應用程序。例如,如果要將.mov擴展名添加到Chess應用程序,Finder將顯示Chess.mov.app以防止用戶考慮Chess.mov是QuickTime文件。

有關顯示名稱和指定本地化捆綁包名稱的詳細信息,請參閱文件系統概述。

捆綁的優點

軟件包為開發人員提供以下優勢:

因為bundle是文件系統中的目錄層次結構,所以bundle只包含文件。因此,您可以使用所有相同的基于文件的界面打開包資源,以便打開其他類型的文件。
捆綁包目錄結構可以輕松支持多個本地化。您可以輕松添加新的本地化資源或刪除不需要的資源。

軟件包可以駐留在許多不同格式的卷上,包括諸如HFS,HFS +和AFP之類的多種叉格式,以及UFS,SMB和NFS等單叉格式。
用戶可以通過在Finder中拖動它們來安裝,重新定位和刪除軟件包。
捆綁包也是包,因此被視為不透明文件,不太容易受到意外的用戶修改,例如關鍵資源的刪除,修改或重命名。
捆綁可以支持多種芯片架構(PowerPC,Intel)和不同的地址空間要求(32位/ 64位)。它還可以支持包含專門的可執行文件(例如,針對特定向量指令集優化的庫)。
大多數(但不是全部)可執行代碼可以捆綁。應用程序,框架(共享庫)和插件都支持捆綁包模型。靜態庫,動態庫,shell腳本和UNIX命令行工具不使用bundle結構。
捆綁的應用程序可以直接從服務器運行。不需要在本地系統上安裝特殊的共享庫,擴展和資源。

捆綁類型

雖然所有捆綁包都支持相同的基本功能,但是您可以定義和創建定義其預期用途的捆綁包的方式有所不同:

應用程序 - 應用程序包管理與可啟動進程關聯的代碼和資源。該捆綁的確切結構取決于您定位的平臺(iOS或MacOS)。有關應用程序包的結構的信息,請參閱應用程序包。
框架 - 框架包管理動態共享庫及其相關資源,如頭文件。應用程序可以鏈接一個或多個框架,以利用它們包含的代碼。有關框架包的結構的信息,請參閱框架包的解剖。
插件 - macOS支持許多系統功能的插件。插件是一種應用程序動態加載自定義代碼模塊的方法。以下列表列出了您可能想要開發的插件的一些關鍵類型:
自定義插件是為您自己定義的插件;請參閱可卸載捆綁的解剖。
Image Unit插件為Core Image技術添加了自定義的圖像處理行為;請參閱圖像單元教程。
Interface Builder插件包含要與Interface Builder的庫窗口集成的自定義對象。
首選項窗格插件定義要集成到“系統偏好設置”應用程序中的自定義首選項;請參閱“優先窗格編程指南”。
Quartz Composer插件定義了Quartz Composer應用程序的自定義修補程序;請參閱Quartz Composer自定義修補程序編程指南。
Quick Look插件支持使用Quick Look顯示自定義文檔類型;請參閱快速編程指南。
Spotlight插件支持自定義文檔類型的索引,以便用戶可以搜索這些文檔;請參閱Spotlight導入器編程指南。
WebKit插件擴展了通用Web瀏覽器支持的內容類型。
窗口小部件將新的基于HTML的應用程序添加到儀表板。
雖然文檔格式可以利用捆綁結構來組織其內容,但文檔通常不被認為是最純粹的捆綁包。實現為目錄并被視為不透明類型的文檔被認為是文檔包,而不管其內部格式如何。有關文檔包的詳細信息,請參閱文檔包。

創建捆綁包

在大多數情況下,您不會手動創建軟件包或軟件包。當您創建新的Xcode項目(或向現有項目添加目標)時,Xcode會在需要時自動創建所需的bundle結構。例如,應用程序,框架和可加載bundle目標都具有關聯的bundle結構。當您構建任何這些目標時,Xcode會為您自動創建相應的軟件包。

注意:某些Xcode目標(例如shell工具和靜態庫)不會導致創建捆綁包或包。這是正常的,不需要為這些目標類型專門創建軟件包。為這些目標生成的生成的二進制文件旨在按原樣使用。
如果您使用make文件(而不是Xcode)來構建項目,那么創建bundle并不奇怪。捆綁包只是文件系統中具有明確定義結構的目錄,并將特定文件擴展名添加到捆綁包目錄名稱的末尾。只要您創建頂級捆綁包目錄并適當地構建您的捆綁包的內容,就可以使用編程支持訪問這些內容來訪問捆綁包。有關如何組織捆綁包目錄的更多信息,請參閱捆綁結構。

程序化支持訪問捆綁包

引用捆綁包或本身捆綁的程序可以利用Cocoa和Core Foundation中的接口訪問捆綁包的內容。使用這些接口,您可以找到捆綁資源,獲取有關捆綁包配置的信息,并加載可執行代碼。在Objective-C應用程序中,您可以使用NSBundle類來獲取和管理包信息。對于基于C的應用程序,可以使用與CFBundleRef opaque類型相關聯的函數來管理捆綁包。

注意:與許多其他Core Foundation和Cocoa類型不同,NSBundle和CFBundleRef不是自由的橋接數據類型,不能互換使用。但是,您可以從任一對象中提取捆綁路徑信息,并使用它來創建另一個對象。
有關如何使用Cocoa和Core Foundation中的程序化支持訪問軟件包的信息,請參閱訪問軟件包的內容。

使用捆綁包的指南

軟件包是MacOS和iOS軟件的首選組織機制。捆綁結構允許您將可執行代碼和資源分組在一個地方并以有組織的方式支持該代碼。以下指南提供了有關如何使用軟件包的一些額外建議:

始終在您的包中包含信息屬性列表(Info.plist)文件。確保包含推薦使用的捆綁類型的密鑰。有關可以包含在此文件中的所有密鑰的列表,請參閱運行時配置指南。
如果應用程序無法在沒有特定資源文件的情況下運行,請將該文件包含在應用程序包中。應用程序應始終包含他們需要操作的所有圖像,字符串文件,本地化資源和插件。非關鍵資源應盡可能類似地存儲在應用程序包中,但如果需要,可以將其放在bundle外部。有關應用程序捆綁結構的更多信息,請參閱應用程序包。
如果您計劃從捆綁包中加載C ++代碼,則可能需要將計劃加載的符號標記為extern“C”。 NSBundle和Core Foundation CFBundleRef函數都不知道C ++名稱的修改約定,所以以這種方式標記您的符號可以使以后更容易識別它們。
您不能使用NSBundle類來加載代碼片段管理器(CFM)代碼。如果需要加載基于CFM的代碼,則必須使用CFBundleRef或CFPlugInRef不透明類型的函數。您可以使用這種技術從Mach-O可執行文件加載基于CFM的插件。
您應該始終使用NSBundle類(與CFBundleRef opaque類型相關聯的函數)來加載包含Java代碼的任何包。
在加載包含Objective-C代碼的捆綁包時,您可以在macOS v10.5及更高版本中使用NSBundle類或與CFBundleRef opaque類型相關聯的函數,但每種類型的行為都有差異。如果您使用Core Foundation函數來加載插件或其他可加載的bundle(而不是框架或動態共享庫),那么這些函數將私有加載并立即綁定它的符號;如果您使用NSBundle,則該捆綁包將在全局加載,其符號將被懶惰綁定。另外,使用NSBundle類加載的bundle會導致生成NSBundleDidLoadNotification通知,而使用Core Foundation函數加載的bundle不會生成。

捆綁結構

捆綁結構可以根據捆綁類型和目標平臺而有所不同。以下部分描述了macOS和iOS中最常用的捆綁結構。

注意:雖然捆綁是一種打包可執行代碼的方法,但它們不是唯一支持的方法。 UNIX shell腳本和命令行工具不使用bundle結構,也不使用靜態和動態共享庫。

應用程序包

應用程序包是開發人員創建的最常見的捆綁類型之一。應用程序包存儲應用程序成功運行所需的所有內容。雖然應用程序包的特定結構取決于您正在開發的平臺,但在兩個平臺上使用捆綁包的方式都相同。本章介紹了iOS和MacOS中應用程序包的結構。

什么文件進入應用程序包?

表2-1總結了您可能在應用程序包中找到的文件類型。這些文件的確切位置因平臺而異,一些資源根本不受支持。有關示例和更詳細的信息,請參閱本章中特定于平臺的軟件包部分。

表2-1應用程序包中的文件類型
文件
描述
Info.plist文件
(必需)信息屬性列表文件是包含應用程序配置信息的結構化文件。系統依賴于此文件的存在來識別有關您的應用程序和任何相關文件的相關信息。
可執行文件
(必需)每個應用程序必須具有可執行文件。該文件包含應用程序的主入口點和靜態鏈接到應用程序目標的任何代碼。
資源文件
資源是存在于應用程序的可執行文件之外的數據文件。資源通常由圖像,圖標,聲音,nib文件,字符串文件,配置文件和數據文件(等)組成。大多數資源文件可以針對特定語言或區域進行本地化,也可以由所有本地化共享。
資源文件在捆綁包目錄結構中的放置取決于您是開發iOS或Mac應用程序。

其他支持文件

Mac應用程序可以嵌入其他高級資源,如私有框架,插件,文檔模板以及其他自定義數據資源,這些資源是應用程序的一部分。盡管您可以在iOS應用程序包中包含自定義數據資源,但不能包括自定義框架或插件。
雖然應用程序包中的大部分資源是可選的,但并不總是如此。例如,iOS應用程序通常需要額外的圖像資源來應用程序的圖標和默認屏幕。盡管未明確要求,但大多數Mac應用程序都包含一個自定義圖標,而不是系統提供的默認圖標。

iOS應用程序包的解剖

Xcode提供的項目模板可以為您的iPhone或iPad應用程序設置捆綁包所需的大部分工作。但是,了解捆綁結構可以幫助您確定應該放置自己的自定義文件的位置。 iOS應用程序的捆綁結構更符合移動設備的需求。它使用相對平坦的結構,幾乎沒有外部目錄,以節省磁盤空間并簡化對文件的訪問。

iOS應用程序捆綁結構

典型的iOS應用程序包包含應用程序可執行文件和應用程序使用的任何資源(例如,應用程序圖標,其他映像和本地化內容)在頂級捆綁包目錄中。 清單2-1顯示了一個名為MyApp的簡單iPhone應用程序的結構。 子目錄中唯一需要進行本地化的文件; 但是,您可以在自己的應用程序中創建其他子目錄來組織資源和其他相關文件。

清單2-1 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

表2-2所示的應用程序的內容如表2-2所示。 雖然應用程序本身僅用于演示目的,但其中包含的許多文件代表了iOS在掃描應用程序包時查找的特定文件。 您自己的軟件包將包含部分或全部這些文件,具體取決于您支持的功能。

表2-2典型的iOS應用程序包的內容

文件
描述
MyApp
(必需)包含應用程序代碼的可執行文件。該文件的名稱與您的應用程序名稱相同。減去.app擴展名。
應用程序圖標(MyAppIcon.png,MySearchIcon.png和MySettingsIcon.png)
(必需/推薦)應用程序圖標在特定時間用于表示應用程序。例如,不同大小的應用程序圖標將顯示在主屏幕,搜索結果和設置應用程序中。并不是所有的圖標都是必需的,但大多數都是推薦的。有關應用程序圖標的信息,請參閱應用程序圖標和啟動映像。
Info.plist
(必需)此文件包含應用程序的配置信息,例如其包ID,版本號和顯示名稱。有關詳細信息,請參閱信息屬性列表文件。
啟動圖像(Default.png)
(推薦)一個或多個圖像,以特定方向顯示應用程序的初始界面。系統使用所提供的啟動映像之一作為臨時背景,直到您的應用程序加載其窗口和用戶界面。如果您的應用程序不提供任何啟動映像,則應用程序啟動時將顯示黑色背景。有關應用程序圖標的信息,請參閱應用程序圖標和啟動映像。
MainWindow.nib
(推薦)應用程序的主要nib文件包含在應用程序啟動時加載的默認界面對象。通常,此nib文件包含應用程序的主窗口對象和應用程序委托對象的實例。然后,其他接口對象將從其他nib文件加載或由應用程序以編程方式創建。 (可以通過向Info.plist文件中的NSMainNibFile鍵分配不同的值來更改主nib文件的名稱。有關詳細信息,請參閱信息屬性列表文件。)
Settings.bundle
“設置”包是一種特殊類型的插件,其中包含要添加到“設置”應用程序的任何特定于應用程序的首選項。此軟件包包含屬性列表和其他資源文件,以配置和顯示您的首選項。
自定義資源文件
非本地化資源放置在頂級目錄中,本地化資源放置在應用程序包的特定語言的子目錄中。資源包括nib文件,圖像,聲音文件,配置文件,字符串文件以及您的應用程序所需的任何其他自定義數據文件。有關資源的更多信息,請參閱iOS應用程序中的資源。
注意:iOS應用程序包不能包含名為“資源”的自定義文件夾。
iOS應用程序應該國際化,并為其支持的每種語言提供一個language.lproj文件夾。除了提供應用程序的自定義資源的本地化版本之外,還可以通過在特定于語言的項目目錄中放置具有相同名稱的文件來本地化啟動映像。但是,即使您提供本地化版本,應始終在應用程序包的頂層包含這些文件的默認版本。默認版本用于特定本地化不可用的情況。有關本地化資源的更多信息,請參閱捆綁包中的本地化資源。

信息屬性列表文件

每個iOS應用程序必須具有包含應用程序配置信息的信息屬性列表(Info.plist)文件。當您創建一個新的iOS應用程序項目時,Xcode會自動創建此文件,并為您設置某些關鍵屬性的值。表2-3列出了您應該明確設置的其他一些鍵。 (Xcode在默認情況下遮蓋實際的鍵名稱,所以Xcode顯示的字符串也列在括號中,可以通過在編輯器中單擊信息屬性列表鍵并選擇顯示來查看所有鍵的真實密鑰名稱來自上下文菜單中的原始鍵/值。)

表2-3 Info.plist文件所需的密鑰



CFBundleDisplayName(Bundle顯示名稱)
捆綁顯示名稱是顯示在應用程序圖標下面的名稱。對于所有支持的語言,此值應本地化。
CFBundleIdentifier(Bundle標識符)
捆綁標識符字符串將您的應用程序標識到系統。此字符串必須是僅包含字母數字(A-Z,a-z,0-9),連字符( - )和句點(。)字符的統一類型標識符(UTI)。字符串也應該是反向DNS格式。例如,如果您的公司的域名是Ajax.com,并且您創建一個名為Hello的應用程序,則可以將com.Ajax.Hello字符串分配為應用程序的包標識符。
捆綁標識符用于驗證應用簽名。
CFBundleVersion(Bundle版)
bundle版本字符串指定包的版本號。該值是單調增加的字符串,由一個或多個周期分隔的整數組成。此值無法本地化。
CFBundleIconFiles
包含用于應用程序各種圖標的圖像的文件名的字符串數組。雖然在技術上不需要,但強烈建議您使用它。
iOS 3.2及更高版本支持此鍵。
LSRequiresIPhoneOS(應用程序需要iOS環境)
一個布爾值,指示捆綁只能在iOS上運行。 Xcode自動添加此鍵并將其值設置為true。您不應該更改此鍵的值。
UIRequiredDeviceCapabilities
告訴iTunes和App Store的一個關鍵知道應用程序需要運行哪些設備相關功能。 iTunes和移動App Store使用此列表來阻止客戶在不支持列出的功能的設備上安裝應用程序。
該鍵的值是數組或字典。如果使用陣列,則給定鍵的存在表示需要相應的功能。如果您使用字典,則必須為每個鍵指定布爾值,以指示該功能是否必需。在這兩種情況下,不包括鍵表示不需要該功能。
有關要包含在字典中的鍵的列表,請參閱信息屬性列表鍵參考。 iOS 3.0及更高版本支持此鍵。
除了上表中的鍵之外,表2-4列出了iOS應用程序通常使用的一些鍵。雖然這些鍵不是必需的,但大多數提供了一種在啟動時調整應用程序配置的方法。提供這些密鑰可以幫助確保系統適當地呈現您的應用程序。

表2-4 Info.plist文件中通常包含的鍵

帕拉
帕拉
NSMainNibFile(主要nib文件名)
標識應用程序主nib文件名稱的字符串。如果要使用除為項目創建的默認文件之外的nib文件,請將該nib文件的名稱與此鍵相關聯。 nib文件的名稱不應包含.nib文件擴展名。
UIStatusBarStyle
一個字符串,用于標識應用程序啟動時狀態欄的樣式。該值基于在UIApplication.h頭文件中聲明的UIStatusBarStyle常量。默認樣式為UIStatusBarStyleDefault。應用程序可以在完成啟動時更改此初始狀態欄樣式。
如果不指定此鍵,則iOS會顯示默認狀態欄。
UIStatusBarHidden
一個布爾值,用于確定應用程序啟動時狀態欄是否最初被隱藏。將其設置為true以隱藏狀態欄。默認值為false。
UIInterfaceOrientation
標識應用程序用戶界面初始方向的字符串。該值基于在UIApplication.h頭文件中聲明的UIInterfaceOrientation常量。默認樣式為UIInterfaceOrientationPortrait。
UIPrerenderedIcon
一個布爾值,指示應用程序圖標是否已經包含光澤和斜角效果。默認值為false。如果您不希望系統將這些效果添加到您的作品中,請將其設置為true。
UIRequiresPersistentWiFi
一個布爾值,通知系統應用程序使用Wi-Fi網絡進行通信。在任何時候使用Wi-Fi的應用程序都必須將此鍵設置為true;否則,30分鐘后,設備將關閉Wi-Fi連接以節省電量。設置此標志還允許系統知道當Wi-Fi可用但當前未被使用時,它應顯示網絡選擇對話框。默認值為false。
即使此屬性的值為true,當該設備空閑(即屏幕鎖定)時,此密鑰也不起作用。在此期間,應用程序被視為無效,盡管它可能在某種程度上起作用,但沒有Wi-Fi連接。
UILaunchImageFile
包含應用程序啟動映像使用的基本文件的字符串。如果不指定此鍵,則基本名稱被假定為字符串Default。
應用程序圖標和啟動映像

應用程序圖標和啟動映像是必須存在于每個應用程序中的標準圖形。每個應用程序必須指定要在設備的主屏幕和App Store中顯示的圖標。并且應用程序可以指定用于不同情況的幾個不同的圖標。例如,應用程序可以提供在顯示搜索結果時使用的應用程序圖標的小版本。啟動圖像向用戶提供應用程序啟動的視覺反饋。

用于表示圖標和啟動圖像的圖像文件必須都位于捆綁包的根級別中。如何將這些映像標識到系統可能會有所不同,但是建議的方法來指定應用程序圖標是使用CFBundleIconFiles鍵。有關如何在應用程序中指定圖標和啟動圖像的詳細信息,請參閱iOS應用程序編程指南中的高級應用技巧中的這些項目的討論。

注意:除了捆綁軟件頂層的圖標和啟動映像之外,還可以在應用程序的語言特定項目子目錄中包含啟動映像的本地化版本。有關在應用程序中包含本地化資源的更多信息,請參閱捆綁包中的本地化資源。

iOS應用程序中的資源

在iOS應用程序中,非本地化資源位于捆綁包目錄的頂層,以及應用程序的可執行文件和Info.plist文件。大多數iOS應用程序在此級別至少有幾個文件,包括應用程序的圖標,啟動映像和一個或多個nib文件。盡管您應該將大多數非本地化資源放在此頂級目錄中,但您也可以創建子目錄來組織資源文件。本地化資源必須放置在一個或多個特定于語言的子目錄中,這些子目錄在捆綁軟件的本地化資源中有更詳細的討論。

清單2-2顯示了一個包含本地化和非本地化資源的虛構應用程序。非本地化資源包括Hand.png,MainWindow.nib,MyAppViewController.nib以及WaterSounds目錄的內容。本地化資源包括en.lproj和jp.lproj目錄中的所有內容。

清單2-2具有本地化和非本地化資源的iOS應用程序

MyApp.app/
   Info.plist
   MyApp
   Default.png
   Icon.png
   Hand.png
   MainWindow.nib
   MyAppViewController.nib
   WaterSounds/
      Water1.aiff
      Water2.aiff
   en.lproj/
      CustomView.nib
      bird.png
      Bye.txt
      Localizable.strings
   jp.lproj/
      CustomView.nib
      bird.png
      Bye.txt
      Localizable.strings

有關在應用程序包中查找資源文件的信息,請參閱訪問軟件包的內容。有關如何加載資源文件并在程序中使用它們的信息,請參閱資源編程指南。

macOS應用程序包解剖

Xcode提供的項目模板可以在開發過程中設置Mac應用程序包所需的大部分工作。但是,了解捆綁結構可以幫助您確定應該放置自己的自定義文件的位置。 macOS軟件包使用高度有組織的結構,使捆綁加載代碼更容易查找軟件包中的資源和其他重要文件。層次性還有助于系統將代碼捆綁包(例如應用程序與其他應用程序使用的目錄包)區分開來實現文檔類型。

macOS應用程序包的結構

Mac應用程序包的基本結構非常簡單。在bundle的頂層是一個名為Contents的目錄。此目錄包含應用程序所需的所有資源,包括資源,可執行代碼,私有框架,私有插件和支持文件。雖然Contents目錄可能看起來很多,但它將該捆綁包標識為現代風格的捆綁包,并將其與早期版本的Mac OS中發現的文檔和舊版捆綁類型分離。

清單2-3顯示了典型應用程序包的高級結構,包括您最可能在Contents目錄中找到的立即文件和目錄。這個結構代表每個Mac應用程序的核心。

清單2-3 Mac應用程序的基本結構

MyApp.app/
   Contents/
      Info.plist
      MacOS/
      Resources/

表2-5列出了您可能在Contents目錄中找到的一些目錄,以及每個目錄的目的。該列表并不詳盡,但僅代表常用的目錄。

表2-5目錄目錄的子目錄
目錄
描述
MacOS
(必需)包含應用程序的獨立可執行代碼。通常,此目錄僅包含一個二進制文件,其中包含應用程序的主入口點和靜態鏈接代碼。但是,您也可以將其他獨立的可執行文件(如命令行工具)放在此目錄中。
資源
包含所有應用程序的資源文件。此目錄的內容進一步組織起來以區分本地化和非本地化資源。有關此目錄的結構的更多信息,請參閱資源目錄
構架
包含可執行文件使用的任何私有共享庫和框架。該目錄中的框架是針對應用程序進行修訂鎖定的,不能被操作系統可用的任何其他甚至更新的版本所取代。換句話說,包含在該目錄中的框架優先于在操作系統的其他部分中發現的任何其他類似命名的框架。
有關如何向應用程序包添加私有框架的信息,請參閱框架編程指南。
插件
包含可擴展的應用程序的基本功能的可加載捆綁包。您可以使用此目錄來包含必須加載到應用程序進程空間中以便使用的代碼模塊。您不會使用此目錄來存儲獨立的可執行文件。
SharedSupport
包含不影響應用程序運行能力的其他非關鍵資源。您可以使用此目錄來包括應用程序期望存在的文檔模板,剪貼畫和教程,但不影響應用程序運行的能力。
多年來應用程序包已經發展很大,但總體目標是一樣的。捆綁組織使應用程序更容易找到其資源,同時使用戶更難干擾這些資源。由于Finder將大多數捆綁包視為不透明實體,因此臨時用戶很難移動或刪除應用程序可能需要的資源。

信息屬性列表文件

要使Finder能夠識別應用程序包,您需要包含一個信息屬性列表(Info.plist)文件。該文件包含XML屬性列表數據,用于標識捆綁包的配置。對于最小的包,該文件將包含很少的信息,很可能只是包的名稱和標識符。對于更復雜的軟件包,Info.plist文件包含更多信息。

重要提示:使用區分大小寫的搜索來定位捆綁資源。因此,您的信息屬性列表文件的名稱必須以資本“I”開頭。
表2-6列出了您應該始終包含在Info.plist文件中的鍵。 Xcode在創建新項目時自動提供所有這些鍵。 (Xcode在默認情況下遮蓋了實際的鍵名稱,所以Xcode顯示的字符串也列在括號中,您可以通過在編輯器中單擊信息屬性列表鍵并選擇顯示原始密鑰/值來查看所有密鑰的真實密鑰名稱從出現的上下文菜單。)

表2-6 Info.plist文件中的預期密鑰

描述
CFBundleName(Bundle name)
捆綁的短名稱。該鍵的值通常是應用程序的名稱。創建新項目時,Xcode默認設置此鍵的值。
CFBundleDisplayName(Bundle顯示名稱)
應用程序名稱的本地化版本。您通常在InfoPlist.strings每個語言特定資源目錄中的文件中包含此密鑰的本地化值。
CFBundleIdentifier(Bundle標識符)
將應用程序標識到系統的字符串。此字符串必須是僅包含字母數字(A-Z,a-z,0-9),連字符( - )和句點(。)字符的統一類型標識符(UTI)。字符串也應該是反向DNS格式。例如,如果您的公司的域名是Ajax.com,并且您創建一個名為Hello的應用程序,則可以將com.Ajax.Hello字符串分配為應用程序的包標識符。
捆綁標識符用于驗證應用簽名。
CFBundleVersion(Bundle版)
指定包的版本號的字符串。該值是單調增加的字符串,由一個或多個周期分隔的整數組成。該值可以對應于應用程序的已發布版本或未發行版本。此值無法本地化。
CFBundlePackageType(Bundle OS類型代碼)
這是捆綁的類型。對于應用程序,此鍵的值始終為四個字符的字符串APPL。
CFBundleSignature(Bundle創建者操作系統類型代碼)
捆綁的創建者代碼。這是一個特定于包的四個字符的字符串。例如,TextEdit應用程序的簽名是ttxt。
CFBundleExecutable(可執行文件)
主要可執行文件的名稱。這是用戶啟動應用程序時執行的代碼。 Xcode通常在構建時自動設置此鍵的值。
表2-7列出了您在Info.plist文件中應該考慮的鍵。

表2-7 Info.plist文件的推薦鍵

描述
CFBundleDocumentTypes(文檔類型)
應用程序支持的文檔類型。這種類型由一系列字典組成,每個字典提供有關特定文檔類型的信息。
CFBundleShortVersionString(Bundle version string,short)
發布版本的應用程序。該鍵的值是由三個周期分隔的整數組成的字符串。
LSMinimumSystemVersion(最小系統版本)
運行該應用程序所需的最小版本的macOS。該鍵的值為n.n.n形式的字符串,其中每個n是表示所需的macOS的主版本號或次版本號的數字。例如,值10.1.5將代表macOS v10.1.5。
NSHumanReadableCopyright(版權(可讀))
申請的版權聲明。這是一個可讀的字符串,可以通過將密鑰包含在特定于語言的項目目錄中的InfoPlist.strings文件中進行本地化。
NSMainNibFile(主要nib文件名)
啟動應用程序時加載的nib文件(不帶.nib文件擴展名)。主要的nib文件是一個Interface Builder存檔,包含啟動時所需的對象(主窗口,應用程序委托等)。
NSPrincipalClass(Principal類)
動態加載的Objective-C代碼的入口點。對于應用程序包,這幾乎總是NSApplication類或自定義子類。
您放入Info.plist文件的確切信息取決于您的軟件包的需求,并可根據需要進行本地化。有關此文件的更多信息,請參閱運行時配置指南。

資源目錄

資源目錄是您放置所有圖像,聲音,nib文件,字符串資源,圖標文件,數據文件和配置文件的位置。此目錄的內容進一步細分為您可以存儲本地化和非本地化資源文件的區域。非本地化資源駐留在Resources目錄本身的頂層或您定義的自定義子目錄中。本地化資源駐留在稱為特定于語言的項目目錄的單獨子目錄中,這些目錄被命名為與特定本地化一致。

查看資源目錄的最佳方式是查看一個例子。清單2-4顯示了一個包含本地化和非本地化資源的虛構應用程序。非本地化資源包括Hand.tiff,MyApp.icns和WaterSounds目錄的內容。本地化資源包括en.lproj和jp.lproj目錄或其子目錄中的所有內容。

清單2-4具有本地化和非本地化資源的Mac應用程序

MyApp.app/
   Contents/
      Info.plist
      MacOS/
         MyApp
      Resources/
         Hand.tiff
         MyApp.icns
         WaterSounds/
            Water1.aiff
            Water2.aiff
         en.lproj/
            MyApp.nib
            bird.tiff
            Bye.txt
            InfoPlist.strings
            Localizable.strings
            CitySounds/
               city1.aiff
               city2.aiff
         jp.lproj/
            MyApp.nib
            bird.tiff
            Bye.txt
            InfoPlist.strings
            Localizable.strings
            CitySounds/
               city1.aiff
               city2.aiff

您的每個語言特定的項目目錄都應包含相同資源文件集的副本,并且所有本地化文件的任何單個資源文件的名稱必須相同。換句話說,只有給定文件的內容才能從一個本地化到另一個本地化。當您在代碼中請求資源文件時,只能指定所需文件的名稱。捆綁加載代碼使用用戶的當前語言偏好來確定要搜索所請求的文件的目錄。

有關在應用程序包中查找資源文件的信息,請參閱訪問軟件包的內容。有關如何加載資源文件并在程序中使用它們的信息,請參閱資源編程指南。

應用程序圖標文件

您的頂級Resources目錄中的一個特殊資源是您的應用程序圖標文件。按照慣例,此文件采用包的名稱和.icns的擴展名;圖像格式可以是任何支持的類型,但如果沒有指定擴展名,則系統假定為.icns。

本地化信息屬性列表

因為應用程序的Info.plist文件中的某些鍵包含用戶可見的字符串,所以macOS提供了一種用于指定這些字符串的本地化版本的機制。在每個特定于語言的項目目錄中,您可以包括一個指定適當本地化的InfoPlist.strings文件。該文件是一個字符串文件(不是屬性列表),其條目由要本地化的Info.plist鍵和適當的翻譯組成。例如,在TextEdit應用程序中,該文件的德語本地化包含以下字符串:

CFBundleDisplayName = "TextEdit";
NSHumanReadableCopyright = "Copyright ? 1995-2009 Apple Inc.\nAlle Rechte vorbehalten.";

創建應用程序包

創建應用程序包的最簡單的方法是使用Xcode。所有新的應用程序項目都包括一個適當配置的應用程序目標,它定義了構建應用程序包所需的規則,包括要編譯哪些源文件,哪些資源文件要復制到該包中,等等。新項目還包括預配置的Info.plist文件,通常還有幾個其他文件可以幫助您快速入門。您可以使用項目窗口根據需要添加任何自定義文件,并使用Info或Inspector窗口配置這些文件。例如,您可以使用“信息”窗口為您的包中的資源文件指定自定義位置。

有關如何在Xcode中配置目標的信息,請參閱Xcode Build System Guide。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容

  • 框架捆綁 框架是封裝動態共享庫和支持該庫所需的資源文件的分層目錄。框架比典型的動態共享庫提供了一些優勢,因為它們為...
    nicedayCoco閱讀 1,637評論 0 2
  • 關于首選項和設置 首選項是您持久存儲的信息,并用于配置您的應用程序。應用程序通常會向用戶公開偏好設置,以便他們自定...
    nicedayCoco閱讀 1,017評論 0 0
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,785評論 18 139
  • 關于資源 適用于計算機程序的資源是與程序可執行代碼相關的數據文件。資源可以通過將代碼之外的復雜數據集或圖形內容創建...
    nicedayCoco閱讀 653評論 0 0
  • 關于iOS應用程序架構 應用程序需要與iOS一起工作,以確保他們提供出色的用戶體驗。 除了為您的應用程序的設計和用...
    nicedayCoco閱讀 1,236評論 0 1