關於 Bundle

這裏是筆記章節,內容是沒有邏輯的,詳細內容請訪問 《Bundle Programming Guide》 《Code Loading Programming》 《Resource Programming Guide》

Guidelines for Using Bundles

Bundles are the preferred organization mechanism for software in OS X and iOS. The bundle structure lets you group executable code and the resources to support that code in one place and in an organized way. The following guidelines offer some additional advice on how to use bundles:

  • Always include an information-property list (Info.plist) file in your bundle. Make sure you include the keys recommended for your bundle type. For a list of all keys you can include in this file, see Runtime Configuration Guidelines.
  • If an application cannot run without a specific resource file, include that file inside the application bundle. Applications should always include all of the images, strings files, localizable resources, and plug-ins that they need to operate. Noncritical resources should similarly be stored inside the application bundle whenever possible but may be placed outside the bundle if needed. For more information about the bundle structure of applications, see Application Bundles.
  • If you plan to load C++ code from a bundle, you might want to mark the symbols you plan to load as extern “C”. Neither NSBundle nor the Core Foundation CFBundleRef functions know about C++ name mangling conventions, so marking your symbols this way can make it much easier to identify them later.
  • You cannot use the NSBundle class to load Code Fragment Manager (CFM) code.* If you need to load CFM-based code, you must use the functions for the CFBundleRef or CFPlugInRef opaque types.* You may load CFM-based plugins from a Mach-O executable using this technique.
  • You should always use the NSBundle class (as opposed to the functions associated with the CFBundleRef opaque type) to load any bundle containing Java code.
  • When loading bundles containing Objective-C code, you may use either the NSBundle class or the functions associated with the CFBundleRef opaque type in OS X v10.5 and later, but there are differences in behavior for each. If you use the Core Foundation functions to load a plug-in or other loadable bundle (as opposed to a framework or dynamic shared library), the functions load the bundle privately and bind its symbols immediately; if you use NSBundle, the bundle is loaded globally and its symbols are bound lazily. In addition, bundles loaded using the NSBundle class cause the generation of NSBundleDidLoadNotification notifications, whereas those loaded using the Core Foundation functions do not.

Framework

  • Frameworks provide a way to factor out commonly used code into a central location that can be shared by multiple applications. Only one copy of a framework’s code and resources reside in-memory at any given time, regardless of how many processes are using those resources. Applications that link against the framework then share the memory containing the framework. This behavior reduces the memory footprint of the system and helps improve performance.
  • Only the code and read-only resources of a framework are shared. If a framework defines writable variables, each application gets its own copy of those variables to prevent it from affecting other applications.

framework 結構
這裏寫圖片描述

Localized Resources in Bundles

本地化文件夾命名方式如下:

language_region.lproj

The language portion of the directory name is a two-letter code that conforms to the ISO 639 conventions. The region portion is also a two-letter code but it conforms to the ISO 3166 conventions for designating specific regions. Although the region portion of the directory name is entirely optional, it can be a useful way to tune your localizations for specific parts of the world. For example, you could use a single en.lproj directory to support all English speaking nations. However, providing separate localizations for Great Britain (en_GB.lproj), Australia (en_AU.lproj), and the United States (en_US.lproj) lets you tailor your content for each of those countries.

Do not store code in your lproj folders, because the system does not load or execute code stored in lproj folders

加載本地化字符串

// 參數說明
// key 需要本地化的字符串對應的鍵值
// value 這裏是默認值。如果本地化資源文件中沒有找到對應的 key 則返回這個值
// tableName 指定在哪個語言文件中尋找。如果傳入 null,則在  Localizable.strings 中尋找。如下面圖片所示,如果傳入 “game” 則在 game.strings 中加載
- (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName;
NSString *path = [[NSBundle mainBundle] pathForResource:@"game" ofType:@"lproj"];

NSString *resu = [[NSBundle bundleWithPath:path] localizedStringForKey:@"game" value:nil table:@"game"];

這裏寫圖片描述

資源加載順序

The bundle programming interfaces follow a specific search algorithm to locate resources within the bundle. Global resources have the highest priority, followed by region- and language-specific resources. When considering region- and language-specific resources, the algorithm takes into account both the settings for the current user and development region information in the bundle’s Info.plist file.

Because global resources take precedence over language-specific resources, there should never be both a global and localized version of a given resource. If a global version of a resource exists, language-specific versions of the same resource are never returned. The reason for this precedence is performance. If localized resources were searched first, the bundle routines might search needlessly in several localized resource directories before discovering the global resource.

Device-Specific Resources in iOS

In iOS 4.0 and later, it is possible to mark individual resource files as usable only on a specific type of device. This capability simplifies the code you have to write for Universal applications. Rather than creating separate code paths to load one version of a resource file for iPhone and a different version of the file for iPad, you can let the bundle-loading routines choose the correct file. All you have to do is name your resource files appropriately.

To associate a resource file with a particular device, you add a custom modifier string to its filename. The inclusion of this modifier string yields filenames with the following format:

<basename><device>.<filename_extension>

The <basename> string represents the original name of the resource file. It also represents the name you use when accessing the file from your code. Similarly, the <filename_extension> string is the standard filename extension used to identify the type of the file. The <device> string is a case-sensitive string that can be one of the following values:

~ipad - The resource should be loaded on iPad devices only.
~iphone - The resource should be loaded on iPhone or iPod touch devices only.

You can apply device modifiers to any type of resource file. For example, suppose you have an image named MyImage.png. To specify different versions of the image for iPad and iPhone, you would create resource files with the names MyImage~ipad.png and MyImage~iphone.png and include them both in your bundle. To load the image, you would continue to refer to the resource as MyImage.png in your code and let the system choose the appropriate version, as shown here:

UIImage* anImage = [UIImage imageNamed:@”MyImage.png”];
On an iPhone or iPod touch device, the system loads the MyImage~iphone.png resource file, while on iPad, it loads the MyImage~ipad.png resource file. If a device-specific version of a resource is not found, the system falls back to looking for a resource with the original filename, which in the preceding example would be an image named MyImage.png.

Getting the Bundle’s Info.plist Data

The NSBundle class provides the objectForInfoDictionaryKey: and infoDictionary methods for retrieving information from the Info.plist file. The objectForInfoDictionaryKey: method returns the localized value for a key and is the preferred method to call. The infoDictionary method returns an NSDictionary with all of the keys from the property list; however, it does not return any localized values for these keys.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章