bundle programing guide

CF 意思是Core Foundation

bundle在ios和ox中是一个基本的技术,用来封装代码和资源文件的。
bundle使用目录和文件来管理,不管是在开发环境还是先上部署修改都非常容易。
Cocoa和Core Foundation都提供了对bundle内容编程的接口。
一个bundle是一个目录,以标准化的分层结构,它包含可执行代码和资源使用的代码。
不是所有的bundle都是以包的形式存在的。

如何知道是一个包文件,一般可以通过看包文件的扩展名来得到,比如.app, .bundle, .framework, .plugin, .kext

bundle的优势:
1:因为bundle在文件系统中是以目录的形式存在的,所以可以用基本的文件读取接口读取bundle
2:因为bundle的目录结构所致,所以可以很容易就支持国际化
3:bundle可以存在不同的文件系统中
4:用户可以容易的安装,移动,删除bundle
5:大部分bundle还是包,所以不容易受到外部用户对关键资源的操作
6:bundle支持intel系列的芯片,以及32位和64位的机器
7:大多数可执行的代码都是使用bundle的,Applications, frameworks (shared libraries), and plug-ins都支持bundle模型,但是动态库,静态库,脚本,命令行等不支持bundle结构

bundle的几种类型:
Application
Frameworks
Plug-Ins:OS X支持,方便应用动态加载不同的模块,有很多种plug-ins

创建bundle:一般当你创建一个xcode工程的时候,在你编译的时候,会自动生成bundle的
如果是objective-c语言开发的应用,可以使用NSBundle类来获取和管理bundle,如果是c开发的应用,可以使用关联CFBundleRef类型的方法来获取和管理bundle。
使用NSBundle来加载java代码,使用CFBundleRef or CFPlugInRef类型来加载Code Fragment Manager (CFM)代码和c、c++代码。

Application bundle包含文件:info.plist(应用的配置文件)、可执行文件、资源文件、支持文件
Info.plist文件属性:
CFBundleDisplayName:应用的显示名称,在icon下面的
CFBundleIdentifier:com.company.application(一般这样)
LSRequiresIPhoneOS:指定app能在那个ios版本上使用
CFBundleVersion:应用版本号
NSMainNibFile:指定应用的主nib文件
UIStatusBarStyle:
UIStatusBarHidden:
UIInterface-Orientation:
UIRequiresPersistent-WiFi:设置为true,app只能在wifi场景下使用

Framework Bundles:
Mac OS X 扩展了 framework 的功能,让我们能够利用它来共享代码和资源。framework 在概念上有点像 Window 下的库,但是比库更加强大,通过 framework 我们可以共享所有形式的资源,如动态共享库,nib 文件,图像字符资源以及文档等。系统会在需要的时候将 framework 载入内存中,多个应用程序可以同时使用同一个 framework,而内存中的拷贝只有一份。一个 framework 同时也是一个 bundle,我们可以在 finder 里浏览其内容,也可以在代码中通过 NSBundle 访问它。
与动态/静态库相比,framework 有如下优势:
第一,framework 能将不同类型的资源打包在一起,使之易于安装,卸载与定位;
第二,framework 能够进行版本管理,这使得 framework 能不断更新并向后兼容;
第三,在同一时间,即使有多个应用程序使用同一 framework,但在内存中只有一份 framework 只读资源的拷贝,这减少了对内存的占用

如何创建一个framework bundle,可以查看Framework Programming Guide
可加载的bundle不能在IOS中使用,可加载的bundle的目录结构和应用bundle的目录结构差不多

指定国际化的格式:language _region .lproj
English speaking:for Great Britain (en_GB.lproj),Australia (en_AU.lproj), and the United States (en_US.lproj)

访问bundle内容:
如果是Cocoa框架的应用,定位和打开bundle
//objective-c语言获取bundle
NSBundle* mainBundle;
// Get the main bundle for the app.
mainBundle = [NSBundle mainBundle];

//c、c++语言获取bundle
CFBundleRef mainBundle;
// Get the main bundle for the app
mainBundle = CFBundleGetMainBundle();


取回的bundle为空有几种情况:
1:应用没有被打包
2:程序启动的时候,可执行文件路径不对,这个路径可以通过PATH或者启动参数指定

通过指定PATH获取:
NSBundle* myBundle;
myBundle = [NSBundle bundleWithPath:@"/Library/MyBundle.bundle"];


如果使用Core Foundation开发的应用:
CFURLRef bundleURL;
CFBundleRef myBundle;
// Make a CFURLRef from the CFString representation of the
// bundle’s path.
bundleURL = CFURLCreateWithFileSystemPath(
kCFAllocatorDefault,
CFSTR("/Library/MyBundle.bundle"),
kCFURLPOSIXPathStyle,
true );
// Make a bundle instance using the URLRef.
myBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
// You can release the URL now.
CFRelease( bundleURL );
// Use the bundle...
// Release the bundle when done.
CFRelease( myBundle );


取回plug-ins在应用中的目录
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef plugInsURL;
CFArrayRef bundleArray;
// Get the URL to the application’s PlugIns directory.
plugInsURL = CFBundleCopyBuiltInPlugInsURL(mainBundle);
// Get the bundle objects for the application’s plug-ins.
bundleArray = CFBundleCreateBundlesFromDirectory( kCFAllocatorDefault,
plugInsURL, NULL );
// Release the CF objects when done with them.
CFRelease( plugInsURL );
CFRelease( bundleArray );


通过bundle id获取bundle:
//cocoa
NSBundle* myBundle = [NSBundle bundleWithIdentifier:@"com.apple.myPlugin"];

//core funduction
CFBundleRef requestedBundle;
// Look for a bundle using its identifier
requestedBundle = CFBundleGetBundleWithIdentifier(
CFSTR("com.apple.Finder.MyGetInfoPlugIn") );


只要你使用一个的NSBundle对象或CFBundleRef类型来定位资源,你不用担心资源是如何寻找的,它会按照一个优先级来。

没有bundle对象,也可以自己获取bundle里面的内容,通过NSFileManager类来操作,不过如果要获取多个资源文件,建议使用bundle对象。

获取单个文件
//cocoa工程
NSBundle* myBundle = [NSBundle mainBundle];
NSString* myImage = [myBundle pathForResource:@"Seagull" ofType:@"jpg"];

//core funduction工程
CFURLRef seagullURL;
// Look for a resource in the main bundle by name and type.
seagullURL = CFBundleCopyResourceURL( mainBundle,
CFSTR("Seagull"),
CFSTR("jpg"),
NULL );


获取多个文件(cocoa工程)
//cocoa工程
NSBundle* myBundle = [NSBundle mainBundle];
NSArray* myImages = [myBundle pathsForResourcesOfType:@"jpg"
inDirectory:nil];
//core funduction工程
CFArrayRef birdURLs;
// Find all of the JPEG images in a given directory.
birdURLs = CFBundleCopyResourceURLsOfType( mainBundle,
CFSTR("jpg"),
CFSTR("BirdImages") );


获取bundle的plist文件中的内容
CFDictionaryRef bundleInfoDict;
CFStringRef myPropertyString;
// Get an instance of the non-localized keys.
bundleInfoDict = CFBundleGetInfoDictionary( myBundle );
// If we succeeded, look for our property.
if ( bundleInfoDict != NULL ) {
myPropertyString = CFDictionaryGetValue( bundleInfoDict,
CFSTR("MyPropertyKey") );
}


获取bundle的版本(using Core Foundation)
// This is the ‘vers’ resource style value for 1.0.0
#define kMyBundleVersion1 0x01008000
UInt32 bundleVersion;
// Look for the bundle’s version number.
bundleVersion = CFBundleGetVersionNumber( mainBundle );
// Check the bundle version for compatibility with the app.
if (bundleVersion < kMyBundleVersion1)
return (kErrorFatalBundleTooOld);


使用bundle加载object-c class
- (void)loadBundle:(NSString*)bundlePath
{
Class exampleClass;
id newInstance;
NSBundle *bundleToLoad = [NSBundle bundleWithPath:bundlePath];
if (exampleClass = [bundleToLoad principalClass])
{
newInstance = [[exampleClass alloc] init];
// [newInstance doSomething];
}
}


使用包来管理文件
当文件格式过于复杂,目录结构很多时候,或者有很多不同格式的文件,那么使用包来封装你的整个文件,使用NSFileWrapper来创建文件包,然后通过NSDocument类去读取你的资源文件。如果你使用的是bundle structure,那么你可以通过NSBundle or CFBundleRef类获取文件

打包步骤:
1:定义文档结构
2:注册文档类型
3:创建包

猜你喜欢

转载自guafei.iteye.com/blog/1837699