国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > IOS-使用framework实现功能模块动态更新

IOS-使用framework实现功能模块动态更新

来源:程序员人生   发布时间:2015-04-08 08:38:40 阅读次数:3412次

测试Xcode版本为6.1.1

实现进程简述:把想要的作为动态更新的模块,移动到我们创建的Framework工程中,然后得到我们想要的动态库文件,把此文件再通过iTunes放到“主程序”项目的document文件夹下,从而实现从主程序中去加载此动态库,从而实现功能模块的动态更新效果。理想效果为支付宝APP,而支付宝采取的是HTML5(网页)的情势实现的,这是目前最通用的实现方式,但是不适用于复杂界面效果。


第1步:创建IOS Framework工程




第2步:生成的工程中本来的类删掉不用


然后添加新的类文件来实现动态加载效果



图片和测试界面不多说,重点为PacteraFramework这个类文件中的代码部份:

添加入口方法:

/* 主程序和此动态库的关系关键,也就是从“主程序”到“动态库内封装的程序”的入口方法 @param mainCon “主程序”中入口按钮所在的ViewController对象 @param bundle 此动态库在document文件中的路径,用于xib的加载和图片的加载 */ -(void)showView:(id)mainCon withBundle:(NSBundle *)bundle;

实现此方法:

-(void)showView:(id)mainCon withBundle:(NSBundle *)bundle { /* *初始化第1个controller TheFirstViewController继承于RootViewController *这里的重点是xib文件的加载  通常我们在初始化xib的时候其实不是很在乎bundle:这个参数,1般情况下都会赋予nil值  其实我们所用到的图片、xib等资源文件都是在程序内部中获得的,也就是我们经常使用的[NSBundle mainBundle]中获得,所谓的NSBundle本质上就是1个路径,mainBundle指向的是.app下。  而如果我们不指定bundle,则会默许从.app路径下去寻觅资源。  不过很明显,我们的动态库是放到“主程序”的document文件下的,所以资源文件是不可能在[NSbundle mainBundle]中获得到的,所以这里我们需要指定bundle参数,这也是传递framework的路径的意义所在 */ TheFirstViewController *firstCon = [[TheFirstViewController alloc]initWithNibName:@"TheFirstViewController" bundle:bundle]; //保存NSBundle firstCon.root_bundle = bundle; //加上导航栏,并隐藏。 UINavigationController *navCon = [[UINavigationController alloc]initWithRootViewController:firstCon]; [navCon setNavigationBarHidden:YES]; //转换传递过来的mainCon参数,实现界面跳转 UIViewController *viewCon = (UIViewController *)mainCon; [viewCon presentViewController:navCon animated:YES completion:^{ NSLog(@"跳转到动态更新模块成功!"); }]; }

上面描写了xib文件的加载,下面是使用图片的注意事项:(使用RootViewController基类的代码做说明)

/* *注意获得图片的方式,通过路径+图片名称去获得 *如果直接使用[UIImage imageNamed:@"root_top_bg.png"]方式加载是会出现问题,  由于在当前程序的路径下是找不到此图片的,图片也会被封装到framwork中 *如果在xib文件中直接为某个控件添加图片的话,和平常使用1样直接添加图片名称,不会出现路径的问题 */ [navImageView setImage:[UIImage imageWithContentsOfFile:[self.root_bundle pathForResource:@"root_top_bg" ofType:@"png"]]];


以上为1些frameweok工程中的注意事项,现在我们运行得到动态库文件



选择Show in Finder,取出framwork文件



第3步:创建“主程序”的项目工程



第4步:设置此工程可以通过iTunes来实现文件同享




然后通过itunes把framework放到document路径中



第5步:获得framework,并调用上面提到的动态库入口方法和传递参数

(此项目在界面上添加了1个简单的按钮,点击按钮来进入动态库)

-(void)testFramework { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *documentDirectory = nil; if ([paths count] != 0) documentDirectory = [paths objectAtIndex:0]; //拼接我们放到document中的framework路径 NSString *libName = @"PacteraFramework.framework"; NSString *destLibPath = [documentDirectory stringByAppendingPathComponent:libName]; //判断1下有无这个文件的存在 如果没有直接跳出 NSFileManager *manager = [NSFileManager defaultManager]; if (![manager fileExistsAtPath:destLibPath]) { NSLog(@"There isn't have the file"); return; } //复制到程序中 NSError *error = nil; //加载方式1:使用dlopen加载动态库的情势 使用此种方法的时候注意头文件的引入 // void* lib_handle = dlopen([destLibPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_LOCAL); // if (!lib_handle) { // NSLog(@"Unable to open library: %s ", dlerror()); // return; // } //加载方式1 关闭的方法 // Close the library. // if (dlclose(lib_handle) != 0) { // NSLog(@"Unable to close library: %s ",dlerror()); // } //加载方式2:使用NSBundle加载动态库 NSBundle *frameworkBundle = [NSBundle bundleWithPath:destLibPath]; if (frameworkBundle && [frameworkBundle load]) { NSLog(@"bundle load framework success."); }else { NSLog(@"bundle load framework err:%@",error); return; } /* *通过NSClassFromString方式读取类 *PacteraFramework 为动态库中入口类 */ Class pacteraClass = NSClassFromString(@"PacteraFramework"); if (!pacteraClass) { NSLog(@"Unable to get TestDylib class"); return; } /* *初始化方式采取下面的情势  alloc init的情势是行不通的  一样,直接使用PacteraFramework类初始化也是不正确的 *通过- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;  方法调用入口方法(showView:withBundle:),并传递参数(withObject:self withObject:frameworkBundle) */ NSObject *pacteraObject = [pacteraClass new]; [pacteraObject performSelector:@selector(showView:withBundle:) withObject:self withObject:frameworkBundle]; }

第6步:运行“主程序”项目到装备上,然后点击按钮进入动态库模块吧。

注意:有时候我们运行framework工程获得framework文件,内部并没有我们想要的xib文件(这个时候内部展现的为nib格式的),所以在我们每次运行此工程的时候,都需要clean


demo下载地址:点击跳转到下载页面

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生