2013-10-25 52 views
8

我已經看過幾篇關於iOS的文章,但是關於OS X的一兩句話只是說要構建一個框架而不是一個靜態庫。 (我找不到有體面的框架指令的帖子。)如何在OS X靜態庫中包含一個筆尖?

我已經創建了我的項目作爲靜態庫,並相應地編寫了整個項目。現在,我只想將我的框架放入一個演示應用程序,它抱怨缺少一個筆尖。作爲一個權宜之計,我已經將筆尖複製到了父項目中,但我希望將整個事情劃分好。

什麼是最好的方法?

編輯:

對於背景:我創建了一個筆尖在Mac應用程序初始化一個NSWindowController

+0

代碼創建VC代替? – Kevin

+0

我可能誤解了這個問題,但似乎在網上有一些關於安靜的文章。 以下是幾個: * http://www.galloway.me.uk/tutorials/ios-library-with-resources/ * http://www.arcanelab.com/post/43939133725/creating-and -using-a-static-library-with-a-resources –

+0

我繼續並創建了一個工作示例。實際上花了幾個小時!檢查我的答案。 – nielsbot

回答

7

不,這是不可能的,因爲靜態庫與「包」不同。

靜態庫是一個單獨的文件,它包含由庫創建者鏈接在一起的類,代碼和變量。它不包含其他文件,它本質上是編譯代碼的數據庫。雖然可以將xib的數據放在那裏,但Xcode無法知道它在那裏,因爲它將它們視爲文件系統上的單個文件。

選項1:(不好)

只要保持廈門國際銀行與README文件包括指令的靜態庫。這種愚蠢的方式,但它快,不可怕,因爲你已經擁有了一切。

選項2:(相當好)

您可以創建一個「框架」,它本質上是一個可通過多個項目

蘋果文檔的架構被重用代碼,資源,設置等捆綁: https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html

https://developer.apple.com/library/mac/documentation/macosx/conceptual/BPFrameworks/Tasks/CreatingFrameworks.html

爲OS X框架隨機指南:(這是與舊版本的Xcode的,但它是相同的概念) http://www.intridea.com/blog/2010/12/28/a-visual-guide-to-creating-an-embeddable-framework-for-mac-osx

[更新1] 注意,它不會與iOS工作,因爲在應用程序束框架不被App Store的規則所允許。 (動態加載的代碼是不是)。 [感謝@nielsbot誰提醒我這評論]

[更新2] 瞭解更多關於iOS 8的他們改變了很多東西在這方面。 (不能上,由於蘋果的保密協議的商談)

+0

框架是要走的路。儘管如此, –

+1

不適用於iOS,因爲App Store規則不允許應用程序包中的框架。 (好吧,動態加載的代碼不是) – nielsbot

+0

我繼續前進並創建了一個工作示例。實際上花了幾個小時!檢查我的答案。 – nielsbot

1

簡單地轉換你筆尖爲目標C級:http://kosmaczewski.net/projects/nib2objc/

然後包括你將你的其他來源*

*從來沒有這樣做,而是理論上它應該工作,對吧?

+1

人們爲了聲譽而做的事情。 :p只是開玩笑,很酷的建議,將調查。 – Moshe

+0

那麼一個靜態庫並不意味着它有任何的UI信息。 – Mojtaba

1

正如其他人指出的那樣,將nib文件與靜態庫捆綁在一起的方式與您可能將nib與框架綁定在一起的方式是不可能的。靜態庫僅包含已編譯的代碼。它不是代碼和其他資源集合的容器。

也就是說,如果你認真對待這個問題,你可以選擇一個具有相同效果的選項。基本上,你將base64編碼成一個字符串,並在運行時重構它。這裏是我的食譜:

1)將你的.xib編譯爲二進制.nib格式。使用XCode或ibtool

2)使用工具將.nib編碼爲base64文本。在OSX你可以使用openssl從終端做到這一點:

openssl base64 -in myNib.nib -out myNib.txt 

3)複製/串的base64粘貼到您的源文件之一。從它構造的NSString:

NSString* base64 = @"\ 
TklCQXJjaGl2ZQEAAAAJAAAAHgAAADIAAAA2AAAAjAAAAG4AAADuAwAAEQAAAPwG\ 
AACHgIaChoGPh4eCjoGJj46CnYGCnoGCn4GBoIKEooaKqIGOqYGCqoGQq4iMs4WC\ 
uIGEuYePwIaBxoWMy4SCz4GG0IGI0YWM1oGE14aL3YeO5IGE5YeC7IGF7YGKVUlG\ 

... 

ZVN0cmluZwCHgQ0AAABVSUZvbnQAiIBOU0FycmF5AIeATlNGb250AI6AVUlQcm94\ 
eU9iamVjdACIgQMAAABVSUNvbG9yAIeAVUlWaWV3AA=="; 

4)編寫代碼來以base64串入一個NSData的解碼:

NSData* d = [[NSData alloc] initWithBase64EncodedString: base64 options: NSDataBase64DecodingIgnoreUnknownCharacters]; 

5)從NSData的構造UINib:

UINib* nib = [UINib nibWithData: d bundle: nil]; 

6 )用你的筆尖:

NSArray* nibItems = [nib instantiateWithOwner: nil options: 0]; 

現在,您可能最終需要在代碼中更改一些內容。如果您使用initinitWithNibName:bundle:從筆尖創建視圖控制器,那麼這不會「正常工作」。爲什麼?因爲這些機制爲筆尖查找捆綁包(通常是應用程序包),並且您的筆尖不在那裏。但是,您可以修復代碼中的任何視圖控制器,以便從我們剛剛重新構建的UINib中加載。下面是描述此過程的鏈接:http://www.indelible.org/ink/nib-loading/

您可能很快就會發現除了.nib以外,您還需要其他資源可用於您的代碼。例如。圖片。您可以使用相同的方法在靜態庫中嵌入圖像或任何其他資源。

在我看來,保持此嵌入式筆尖保持最新狀態所需的工作流程的開發人員成本非常高。如果是我,我只需創建一個框架並分發它。

+0

如果你打算走這條路,不要用base64編碼它;只需創建一個原始字節值的C數組,然後爲其分配'NSData'。這就是說,這會起作用,但它也會膨脹你的二進制文件的大小。 –

+0

@Dave DeLong。好點,我沒有想過使用c數組。你仍然需要一個工具來將二進制代碼編碼爲十六進制符號,是的? – TomSwift

+0

是的,你仍然需要一個工具來生成代碼。 –

4

好吧,我花時間把你如何做到這一點的樣本放在一起。它是建立在@ TomSwift的答案,這一點:http://www.cocoanetics.com/2012/02/xcode-build-rules/

我在這裏上傳了一個樣本項目:https://github.com/nielsbot/StaticLibraryXIB

您添加的廈門國際銀行文件自定義規則,以你的靜態庫的目標。它在NSNib上插入一個類方法,在調用XIB時實例化你的XIB。該方法是您的XIB的名稱。所以如果你有「TestNib.xib」,你可以撥打+[NSNib TestNib]

的詳細信息:

  1. 添加XIB文件自定義編譯器(這僅僅是一個有點shell腳本的,我們要爲項目中的每個XIB文件運行)

    一)在靜態庫構建規則中,在搜索框中輸入「XIB」,然後單擊「複製到目標」按鈕以在項目中創建XIB文件規則。

    B)離開過程爲「Interface Builder中的文件」上,使用「自定義腳本:」這是自定義腳本:

    /usr/bin/ibtool --output-format human-readable-text --compile "$TARGET_TEMP_DIR/$INPUT_FILE_BASE.nib" "$INPUT_FILE_DIR/$INPUT_FILE_NAME" 
    Hexdump=`hexdump -v -e '1 1 "0x%02x, "' "$TARGET_TEMP_DIR/${INPUT_FILE_BASE}.nib"` 
    Datalength=`stat -f "%z" ${TARGET_TEMP_DIR}/${INPUT_FILE_BASE}.nib` 
    sed -e "s/HEX_DUMP/$Hexdump/g" -e "s/NIB_NAME/${INPUT_FILE_BASE}/g" -e "s/HEX_LENGTH/$Datalength/g" "${SRCROOT}/NibTest/CompiledNibTemplate.m" > "$DERIVED_FILE_DIR/$INPUT_FILE_BASE.nib.m" 
    

    這將改變你的XIB文件到將被自動編譯.m文件進入你的項目。模板是CompiledNibTemplate.m,它看起來像這樣:

    #import <Cocoa/Cocoa.h> 
    
    @implementation NSNib (NIB_NAME) 
    
    +(instancetype)NIB_NAME 
    { 
        NSData * data = [ NSData dataWithBytesNoCopy:(void*)(const unsigned char[]){ HEX_DUMP } length:(NSUInteger){ HEX_LENGTH } freeWhenDone:NO ] ; 
        NSNib * result = [ [ NSNib alloc ] initWithNibData:data bundle:nil ] ; 
        return result ; 
    } 
    
    @end 
    
  2. 根據上面的例子,如果你的XIB被稱爲「StaticLibraryWindowController.xib」,NSNib現在有一個新的類方法StaticLibraryWindowController。 )調用[ NSNib StaticLibraryWindowController ]將返回一個NSNib對象。你可以打電話-instantiateWithOwner:topLevelObjects:像那個像其他筆尖手柄)

+0

我正要嚇壞了 - 並且因爲骯髒而閱讀 - (跛腳/不正確)授予回答者的愚蠢的帖子..與您的回購鏈接和故事..然後我看到了您的答案。對你有好處...還有關於這個問題的注意事項是...... [這樣的東西,它允許一個嵌入數據在任何二進制,捆綁,lib等](https://github.com/Daij-Djan/DDMountainNotifier /blob/master/MountainNotifier/DDEmbeddedDataReader.h) –

+0

另外,我聽說動態代碼加載的一些限制已經在iOS 8中解除了...因此,這可能不再適用 – nielsbot

+0

@alexgray這非常酷,謝謝。 – nielsbot

相關問題