iOS從靜態庫加載Storyboard并創建ViewController教程

最近在研究將iOS工程打包成靜態庫并從中創建ViewController的方法。其中遇到了很多坑,經過兩天的折騰,終于理清了其中的邏輯。鑒于這兩天的折騰并沒有搜索到很實用的教程,因此本文就一步一步向各位演示如何實現將工程打包為靜態庫,并從中創建storyboard。

1.打包靜態庫并拖入項目

首先將打包了storyboard和代碼文件的靜態庫TempFramework.framework拖入項目,并從framework文件中讀取storyboard文件(我這里的storyboard名為BasicMain)。


01 - framework文件結構.png
02-靜態庫拖入項目并讀取storyboard文件創建storyboard.png

創建代碼如下

  NSString *path = [[NSBundle mainBundle] pathForResource:@"TempFramework" ofType:@"framework"];
  NSLog(@"path = %@", path);
    
  NSBundle *myBundle = [NSBundle bundleWithPath:path];
  NSLog(@"myBunlde = %@", myBundle);
    
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"BasicMain" bundle:myBundle];
  NSLog(@"%@", storyboard);

此時運行會報錯

03-第一次運行報錯.png

打印結果與錯誤原因如下:

01-測試用靜態庫創建ViewController[3103:145256] path = (null)
01-測試用靜態庫創建ViewController[3103:145256] myBunlde = (null)
01-測試用靜態庫創建ViewController[3103:145256] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'Could not find a storyboard named 'BasicMain' in bundle NSBundle 
</Users/yzzy/Library/Developer/CoreSimulator/Devices/
0F87417C-9FF4-4F09-B1F7-
10C4E7BB4301/data/Containers/Bundle/Application/E9ADFEBA-
86F0-46E1-B386-61202991AF7A/01-測試用靜態庫創建ViewController.app> (loaded)'

從上述打印結果可以看出,這是因為系統沒有找到framework文件路徑。這里需要補充iOS中關于bundle的介紹:

Bundle簡單地講,就是一個內部結構按照標準規則組織的特殊目錄

iOS的應用都是通過bundle進行封裝的,對應的bundle類型是Application類型,平時我們通過XCode編譯出來的Target(即我們開發的應用),其實就是一個Application類型bundle,即一個文件夾!但是Finder會把這個bundle當做一個文件顯示給我們,其實是因為這個bundle自身也是一個package,而Mac系統會把所有的package當做一個文件來對待,顯示給用戶,從而防止用戶誤操作導致程序文件損壞或丟失。至于bundle和package有什么區別,就不在這里展開說明了,本文后面所說的bundle都會被Mac系統視為package。

bundle的種類:
1. Application
2. Frameworks
3. Plug-Ins

本質上bundle文件就是一個文件夾,因此framework也是一個文件夾,iOS開發中,如果需要從bundle文件中讀取數據,需要在builder phase中將bundle文件加入Copy Bundle Resources。在這里沒有讀取到framework的原因正是因為我們雖然把framework文件拖入了項目,但是沒有將它加入到Copy Bundle Resources中。

04-bundle加入Copy Bundle Resources中.png

此時再運行項目,則可成功讀取framework路徑,并創建storyboard

05-打印路徑成功.png

2.storyboard創建ViewController并跳轉

讀取到storyboard路徑后,接下來就要根據storyboard創建ViewController并跳轉到創建的ViewController。代碼如下:

  NSString *path = [[NSBundle mainBundle] pathForResource:@"TempFramework" ofType:@"framework"];
  NSLog(@"path = %@", path);
    
  NSBundle *myBundle = [NSBundle bundleWithPath:path];
  NSLog(@"myBunlde = %@", myBundle);
   
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"BasicMain" bundle:myBundle];
  NSLog(@"%@", storyboard);
    
  StoryboardOneViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"StoryboardOneViewController"];
  [self presentViewController:vc animated:YES completion:nil];

此時運行進行跳轉時會報錯

06-第二次運行報錯.png

錯誤原因:

01-測試用靜態庫創建ViewController[3560:181383] path = 
/Users/yzzy/Library/Developer/CoreSimulator/Devices/0F87417C-
9FF4-4F09-B1F7-
10C4E7BB4301/data/Containers/Bundle/Application/B67631C8-
087A-4BE9-8AC0-E08178A83199/01-測試用靜態庫創建
ViewController.app/TempFramework.framework

01-測試用靜態庫創建
ViewController[3560:181383] myBunlde = NSBundle 
</Users/yzzy/Library/Developer/CoreSimulator/Devices/0F87417C-
9FF4-4F09-B1F7-
10C4E7BB4301/data/Containers/Bundle/Application/B67631C8-
087A-4BE9-8AC0-E08178A83199/01-測試用靜態庫創建
ViewController.app/TempFramework.framework> (not yet loaded)

01-測試用靜態庫創建
ViewController[3560:181383] <UIStoryboard: 0x608000265680>

01-測試用靜態庫創建
ViewController[3560:181383] Unknown class 
StoryboardOneViewController in Interface Builder file.

01-測試用靜態庫創建
ViewController[3560:181383] *** Terminating app due to uncaught 
exception 'NSUnknownKeyException', reason: '[<UIViewController 
0x7fa4bbf0d4b0> setValue:forUndefinedKey:]: this class is not key 
value coding-compliant for the key testBtn.'

解決這里的錯誤,需要在build setting的other linker flags屬性中,添加參數-ObjC(注意大小寫)。

07-添加-ObjC參數.png

這樣就完成了從framework中加載storyboard并創建ViewController的全部工作。運行項目,跳轉成功!

08-加載成功.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容