How to include an item in the OS X static library?

I saw several posts dedicated to this issue regarding iOS, but one or two mentions of OS X just talk about creating a framework instead of a static library. (I cannot find a message that has decent instructions for the framework.)

I created my project as a static library and encoded everything accordingly. Now I just want to place my framework in a demo application, and it complains about the missing icon. As a stopwatch, I copied the tip to the parent project, but I want to correctly split it all up.

What is the best approach?

Edit:

In context: I created a thread to initialize NSWindowController in a Mac application.

+8
frameworks libraries xcode macos
source share
4 answers

No, this is not possible because the static library does not match the "bundle".

A static library is a single file containing the classes, code, and variables that were linked by the creator of the library. It does not β€œcontain” other files, it is, in fact, a database of compiled code. Although it would be possible to place data for xibs there, Xcode might not know that it is there, since it searches for them as separate files in the file system.

Option 1: (not good)

Just save xib with a static library with a README file, including instructions. It's stupid, but it's quick and not terrible, because you already have everything.

Option 2: (pretty good)

You can create a β€œFramework,” which is essentially a collection of code, resources, settings, etc. that can be reused by several projects.

Apple Doc for Framework: 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

Random guide for OS X Framework: (this is with the old version of Xcode, but it's the same concept) http://www.intridea.com/blog/2010/12/28/a-visual-guide-to-creating-an- embeddable-framework-for-mac-osx

[UPDATE 1] Please note that it will not work with iOS, since application store frameworks are not allowed in application packages. (Dynamically loaded code is not anyway). [Subscribe to @nielsbot, which remind me of this in the comments.]

[UPDATE 2] More about iOS 8, they have changed a lot in this regard. (Can't talk about it because of Apple NDA)

+7
source share

Well, I took the time to put together a sample of how you can do this. It is built on @TomSwift answer, and it is: http://www.cocoanetics.com/2012/02/xcode-build-rules/

I downloaded a sample project here: https://github.com/nielsbot/StaticLibraryXIB

You add a custom rule for XIB files to the target of the static library. It inserts a class method into NSNib , which runs your XIB whenever it calls. Method is the name of your XIB. Therefore, if you have "TestNib.xib", you would call +[NSNib TestNib] .

More details:

  • Add a custom compiler for XIB files (this is just a bit of the shell script that we want to run for each XIB file in the project)

    a) In your static lib build rules, enter "XIB" in the search field and click the "Copy to Target" button to create a draft XIB rule in the file.

    b) leave the "Interface Files" process, set "Use" to "User script:" Here's the user script:

     /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" 

    This will convert your XIB files to .m files, which will be automatically compiled into your project. CompiledNibTemplate.m template that looks like this:

     #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 
  • According to the above example, if your XIB was called "StaticLibraryWindowController.xib", NSNib will now have a new method of the StaticLibraryWindowController class. ) Calling [ NSNib StaticLibraryWindowController ] returns an NSNib object. You can call -instantiateWithOwner:topLevelObjects: on this, like any other nib descriptor)

+4
source share

Just put you in the C object class: http://kosmaczewski.net/projects/nib2objc/

Then turn it on, like your other source *

* Never did this, but theoretically it should work, right?

+1
source share

As others have pointed out, combining a nib file with a static library in the same way that you can link a thread to a framework is simply not possible. The static library contains only compiled code. This is not a container for collecting code and other resources.

However, if you are serious about this, you have an option that will have the same effect. Basically you will be base64 encoding your nib into a string and restoring it at runtime. Here is my recipe:

1) compile your .xib to binary .nib form. Use Xcode or ibtool .

2) use a tool to encode your .nib as base64 text. On OSX, you can use openssl for this from the terminal:

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

3) copy / paste the base64 string into one of your source files. Create an NSString from it:

 NSString* base64 = @"\ TklCQXJjaGl2ZQEAAAAJAAAAHgAAADIAAAA2AAAAjAAAAG4AAADuAwAAEQAAAPwG\ AACHgIaChoGPh4eCjoGJj46CnYGCnoGCn4GBoIKEooaKqIGOqYGCqoGQq4iMs4WC\ uIGEuYePwIaBxoWMy4SCz4GG0IGI0YWM1oGE14aL3YeO5IGE5YeC7IGF7YGKVUlG\ ... ZVN0cmluZwCHgQ0AAABVSUZvbnQAiIBOU0FycmF5AIeATlNGb250AI6AVUlQcm94\ eU9iamVjdACIgQMAAABVSUNvbG9yAIeAVUlWaWV3AA=="; 

4) write code to decode the base64 string in NSData:

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

5) Create a UINib from NSData:

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

6) Use your own:

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

Now you may need to change a few things in your code. If you create view controllers from nibs using init or initWithNibName:bundle: then this will not just work. What for? Because these mechanisms look in the kit (usually in the app bundle) for the tip, and yours will not be there. But you can fix any view controllers in your code to load from your UINib that we just created. Here is a link that describes the process for this: http://www.indelible.org/ink/nib-loading/

You can quickly find that you need other resources available to your code, in addition to your .nib. For example. images. You can use the same approach to embed images or any other resource in your static library.

In my opinion, the cost of developing a workflow to maintain this built-in latter is pretty high. If it were me, I would just create a framework and distribute it.

+1
source share

All Articles