如何在OS X静态库中包含笔尖?

问题描述 投票:7回答:5

我已经看到了几篇有关iOS的主题的文章,但是提到OS X的一两个内容只是说要构建框架而不是静态库。 (我找不到具有不错的框架说明的帖子。)

我已经将我的项目创建为静态库,并对整个内容进行了相应的编码。现在,我只想将我的框架放在演示应用程序中,并且抱怨缺少笔尖。作为权宜之计,我已将笔尖复制到父项目中,但是我想适当地划分整个内容。

最佳方法是什么?

编辑:

对于上下文:我创建了一个笔尖来初始化Mac应用中的NSWindowController

xcode macos frameworks libraries
5个回答
8
投票

不,这不可能,因为静态库与“捆绑包”不同。

静态库是一个单个文件,其中包含由库创建者链接在一起的类,代码和变量。它不“包含”其他文件,它实质上是一个已编译代码的数据库。尽管可以将xib的数据放在其中,但是Xcode无法知道它是否在其中,因为Xcode会将它们作为文件系统中的单个文件进行查找。

选项1 :(不好)

只需将xib保留在带有说明的README文件的静态库中。有点愚蠢的方法,但是它很快而且并不可怕,因为您已经拥有了一切。

选项2 :(相当不错)

您可以创建一个“框架”,实质上是一堆代码,资源,设置等,可以被多个项目重用

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

OS X Framework的随机指南:(与旧版本的Xcode相同,但概念相同)http://www.intridea.com/blog/2010/12/28/a-visual-guide-to-creating-an-embeddable-framework-for-mac-osx

[UPDATE 1]请注意,它不适用于iOS,因为App Store规则不允许应用捆绑包中的框架。 (不是动态加载的代码)。 [感谢@nielsbot,他在评论中让我想起了这一点。]

[UPDATE 2]阅读有关iOS 8的更多信息,他们在这方面进行了很多更改。 (由于苹果的NDA不能谈论它)


3
投票

好吧,我花了一些时间来整理如何执行此操作的示例。它基于@TomSwift的答案,并且是这样的:http://www.cocoanetics.com/2012/02/xcode-build-rules/

我在此处上传了一个示例项目:https://github.com/nielsbot/StaticLibraryXIB

您将XIB文件的自定义规则添加到静态库目标。它在NSNib上插入一个类方法,该方法在调用XIB时实例化。该方法是您的XIB的名称。因此,如果您有“ TestNib.xib”,则将调用+[NSNib TestNib]

更详细:

  1. 为XIB文件添加自定义编译器(这实际上只是我们要为项目中的每个XIB文件运行的Shell脚本的一部分)

    a)在您的静态库构建规则中,在搜索框中输入“ XIB”,然后单击“复制到目标”按钮以在您的项目中创建XIB文件规则。

    b)将Process保留为“ 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:


1
投票

简单地将您的笔尖转换为目标C类:http://kosmaczewski.net/projects/nib2objc/

然后像添加其他来源一样添加它*

*从未这样做,但从理论上讲应该起作用,对吧?


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
投票

使用Xcode 11,您只需创建一个包目标,并从库代码中引用该包即可引用该笔尖。使用分发包分发库。

iOS上的类似过程:https://www.youtube.com/watch?v=WQI02KR9kQw

© www.soinside.com 2019 - 2024. All rights reserved.