IOS-使用framework實現功能模塊動態更新
來源:程序員人生 發布時間:2015-04-08 08:38:40 閱讀次數:3557次
測試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下載地址:點擊跳轉到下載頁面
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈