2011年4月30日 星期六

Build Static Library in Xcode 4

這篇文章是要來教大家用 Xcode 4 產生 .a 檔,所謂的 Static Library。
用途就是把自己寫好的程式不想要給對方看到 source code 包成 .a 再加上 .h 這樣一樣對方可以正常使用自己寫好的程式,而且看不到自己寫的 .m 檔。
在這個文章要建立兩個專案,一個是用來產生 .a ,另一個用來測試 .a 是不是成功產生。
LibTest - 這個專案用來產生 .a ( Xcode 自動會產生一個名為 libLibTest.a 的檔案)
UsageTest - 這個專案用來測試 LibTest 產生的 .a
讓我們一步一步來進行
首先開啟一個 Static Library 的專案,如下
然後命名為 LibTest 會在導覽列看到如下

LibTest 這個 Group 裡什麼都沒有
接著我們就要新增一個 Class 打算把這個 Class 的 .m 包成 .a
如下方式新增一個 File
然後新增一個 NSObject 的子類別命名為 LibTest,之後會在導覽列看到。
LibTest.h 和 LibTest.m。之後呢,新增一個 method 在 .h 和其實作在 .m
#import <Foundation/Foundation.h> 
@interface LibTest : NSObject { 
-(void) greeting:(NSString *) message; 
@end
上面是 LibTest.h,下方是 LibTest.m


#import "LibTest.h" 
@implementation LibTest 

-(void) greeting:(NSString *) message{ 
    NSLog(@"Hello %@", message); 
@end
打完之後存檔,接下來要產生 .a 檔了。在產生之前先確定一下 configuration
目的就是要確定這個 scheme 跑的是 release 而不是 debug。確定之後。在 Product -> Build 按下之後就會 Build 這個 Target 然後會產生 .a 如下圖來 Build
重點來了,.a 檔會放在那?Xcode 4 會放在 ~/Library/Developer/Xocde/DerivedData/ 的再接下圖
也就是  ~/Library/Developer/Xocde/DerivedData/<Product Name>/Build/Products/Release-iphonesimulator/ 底下會有一個 .a 如上圖,要記得哦,是 Release 如果是 Debug 開頭,我測過是不能被用的。好記得就好。然後要把這個檔案和 .h 一起放到等一下要開啟的 UsageTest 專案裡。
簡單開始一個 Window-based Application ,Product Name 命名為 UsageTest 就可以了。如下圖
接者把上一個專案產生的 libLibTest.a 和 LibTest.h 一起 copy 到這個專案。如下圖。
然後在 UsageTestAppDelegate.m 的 application:didFinishLaunchingWithOptions: 填上如下的程式碼。


#import "UsageTestAppDelegate.h" 
#import "LibTest.h" 
@implementation UsageTestAppDelegate 
@synthesize window=_window; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    LibTest * libObj = [LibTest new]; 
    [libObj greeting:@"Michael"]; 
[self.window makeKeyAndVisible]; 
return YES; 
// 省略 

}
沒意外的話,Run 就會看到如下成功的畫面。只有 .a 和 .h 就可以成功執行了。




7 則留言:

  1. 我想做個.a檔讓我的專案使用,當我編譯好,把.a和.h放到我的專案後,先用模擬器來執行,此時我的.a檔也是在Destination為模擬器下編譯完成的,所以在我的專案裡Link會過,但是,如果我的專案的Destination為iOS Device的時候,link就不會過了,除非我再去編譯.a檔,且.a檔的Destination為iOS Device,這樣才能過。

    這樣會造成我的專案裡要有兩個.a檔,一個for iOS Device,一個for 模擬器,有辦法一個.a檔兩個都滿足嗎?

    謝謝~

    回覆刪除
  2. 多谢你的文章。受益匪浅

    回覆刪除
  3. 比較好的方法應該是app project把static library的project加進來,再去build phase中加上target dependency

    回覆刪除
  4. 在"objective-c與ios開發入門"這本書上所使用的是xcode 4.2 & ios5嗎?

    回覆刪除
  5. Hi, 胖拔,這本書是 Xcode 4.1 和 iOS 4,請期待下一個版本 :)

    回覆刪除
  6. 分享一下,如果在自製library使用category擴充,而導致引用library的專案中發生問題的,可以參考此解法。
    http://stackoverflow.com/questions/10384170/error-while-encrypting-string-in-staticlibrary

    回覆刪除