我使用以下教程构建了一个框架.
我也有这个框架.
我正在尝试在我的内部实现第二个框架,从我在Apple文档中读到的结果框架被称为"伞框架".
我在框架中使用拖放添加了第二个框架,并验证它是否在"Link Binary With Libraries"中.
在我尝试在我的框架的一个类中进行下一次导入之后:
#import <CrashReporter/CrashReporter.h>
Run Code Online (Sandbox Code Playgroud)
我收到错误,因为导入的框架不可见.
另外我看过stackoverflow帖子: 如何在iOS SDK中创建一个伞形框架?
有没有人试图为iOS提取PLCrashReporter类并将其集成到一个项目中?
你可以在这里找到我的尝试.
Vel*_*nov 53
分发另一个框架的诱惑是可以理解的,但是非常气馁.我将尝试解释为什么(带参数),并提供一些有用的替代方案.
伞框架仅供您使用,只有当您是两个框架的分发者时,您才能完全控制它们,并且它们将一起分发.
苹果公司有一个关于这个话题的热门话题,他们说他们不鼓励伞形框架.
不要创建伞框架
虽然可以使用Xcode创建伞形框架,但对大多数开发人员来说这样做是不必要的,不建议这样做.Apple使用伞形框架来掩盖操作系统中库之间的一些相互依赖关系.几乎在所有情况下,您都应该能够将代码包含在单个标准框架包中.或者,如果您的代码足够模块化,您可以创建多个框架,但在这种情况下,模块之间的依赖关系将是最小的或不存在的,并且不应该保证为它们创建保护伞.
首先,这是大多数开发人员在这种情况下所做的事情,因为有许多框架依赖于其他框架.
告知用户您的框架需要使用其他第三方框架.这是完全标准的,在大多数情况下是预期的.然后在系统级别链接到它.就这么简单.您的框架会发现第三方和函数似乎很有用,就像使用本机框架一样.以UIKit为例.要链接到第三方,请按照下一部分中的步骤操作.它当然可以通过标准方式完成,但使用像CocoaPods这样的工具将使您的项目更容易维护.
要完全回答您的问题,而不是以通常的方式添加第三方框架,因为您可能会遇到问题和复杂问题,请使用 CocoaPods为您添加它.通过这种方式,您可以消除可能的问题,并获得CocoaPods的额外好处,从而获得您需要的第三方的确切版本.
这是一个名为"CrashTest"的应用程序的CocoaPods Podfile
target 'CrashTest' do
pod 'PLCrashReporter', '~> 1.2.0'
end
Run Code Online (Sandbox Code Playgroud)
只是为了澄清一下,当您开发框架时,它仍将被添加到您的项目中并且可见.这里的最大区别在于它将与您的框架分开分发,最终用户必须将两者都添加到他们的项目中才能使工作正常.
以下是为什么这样做的原因.
例如,您希望包含PLCrashReporter在您的框架中.假设另一个框架供应商也希望将其包含在他们的网站中.使用这两个框架的应用程序将PLCrashReporter包含两次(作为每个伞框架的一部分).可能甚至不同版本的它.这可能会导致用户应用程序内部出现严重问题.如果两个伞形框架都链接到PLCrashReporter,如上一节所述,则可以完全避免此问题.
我在上面提到的另一点是版本控制.在分发伞形框架时,您需要能够控制所涉及的所有框架的版本,并且您无法控制第三方框架.这将再次导致与上述问题类似的问题.
我知道这种方法并没有提供问题的直接答案,但它试图阻止一种不良的做法,同时指出行业标准的做事方式.
Seg*_*gev 27
Apple不鼓励你创建一个伞形框架但是,仍然说它有可能对它的结构有一些描述等,所以我将专注于如何实际做到这一点.
我必须提一下,如果你控制一个或多个框架,将它们捆绑成一个并不是一个坏主意,可以帮助最终开发人员.
在最近的Xcodes(7及更高版本)上创建一个伞形框架现在非常简单
这是怎么做的.
首先创建一个框架:
拖到CrashReporter.frameworkUmbrella框架项目:
用于确保两个框架都正常运行的示例代码:
Umbrella.h:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface Umbrella : NSObject
+(void)sayHelloFromUmbrella;
@end
Run Code Online (Sandbox Code Playgroud)
Umbrella.m:
#import "Umbrella.h"
#import <CrashReporter/CrashReporter.h>
@implementation Umbrella
+(void)sayHelloFromUmbrella
{
NSLog(@"Hey from Umbrella");
PLCrashReporter *crashObject = [[PLCrashReporter alloc]initWithConfiguration:nil];
NSLog(@"crashObject: %@",crashObject);
}
@end
Run Code Online (Sandbox Code Playgroud)
构建,您将获得构建文件夹中的Umbrella.framework(包含CrashReporter.framework).
将Umbrella.framework其拖放到要使用它的项目中的"嵌入式二进制文件"中:
然后只需导入完成的框架.
我们刚刚将Umbrella.framework拖到的项目中的ViewController.m:
#import "ViewController.h"
#import <Umbrella/Umbrella.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[Umbrella sayHelloFromUmbrella];
}
Run Code Online (Sandbox Code Playgroud)
哪个会输出这个:
Hey from Umbrella
crashObject: <PLCrashReporter: 0x7fb441d5c650>
Run Code Online (Sandbox Code Playgroud)
这告诉我们两个框架都在工作.
Min*_*uma 13
这里是一个演示项目:
这一行下的所有答案都是错误的,因为他们只是手动将子框架复制到"伞框架"中
如何在另一个框架内添加框架(Umbrella Framework)
首先我们应该知道"伞形框架"是Mac OS中的概念而不是iOS,官方文档就在这里
如果你想创建一个不推荐的"UmbrellaFramework",你必须一步一步地完成这些过程,并在编译和链接期间知道细节
!!这是您可以参考的"FakeBundleShellScript"的示例
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
BUNDLE_IN_ROOT="$APP_PATH/${FRAMEWORK_EXECUTABLE_NAME}.bundle"
if [[ -e "$FRAMEWORK_EXECUTABLE_PATH" ]]; then
FRAMEWORK_MACH_O="$(otool -a "$FRAMEWORK_EXECUTABLE_PATH" | head -n 1)"
FRAMEWORK_FAT_ARCH="$(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")"
else
FRAMEWORK_MACH_O="NO EXIST"
FRAMEWORK_FAT_ARCH="NO EXIST"
fi
echo "FRAMEWORK_EXECUTABLE_NAME is $FRAMEWORK_EXECUTABLE_NAME"
echo "FRAMEWORK_EXECUTABLE_PATH is $FRAMEWORK_EXECUTABLE_PATH"
echo "FRAMEWORK_MACH_O is $FRAMEWORK_MACH_O"
echo "FRAMEWORK_FAT_ARCH is $FRAMEWORK_FAT_ARCH"
echo "BUNDLE_IN_ROOT is $BUNDLE_IN_ROOT"
if [[ "$FRAMEWORK_MACH_O" =~ "Archive :" ]]; then
echo "Rmove Static-Mach-O is $FRAMEWORK_EXECUTABLE_PATH"
rm "$FRAMEWORK_EXECUTABLE_PATH"
defaults write "$FRAMEWORK/Info.plist" CFBundlePackageType "BNDL"
defaults delete "$FRAMEWORK/Info.plist" CFBundleExecutable
if [[ -d "$BUNDLE_IN_ROOT" ]]; then
rm -rf "$BUNDLE_IN_ROOT"
fi
mv -f "$FRAMEWORK" "$BUNDLE_IN_ROOT"
elif [[ "$FRAMEWORK_FAT_ARCH" =~ "Architectures in the fat file" ]]; then
#statements
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
fi
done
Run Code Online (Sandbox Code Playgroud)
正如我所说的,制作一个不推荐的"UmbrellaFramework"的关键是!!!! [将子框架编译为静态,通过假捆绑处理资源],记住!! Apple总是说不要创建一个UmbrellaFramework
如果你能理解中文,可以从我的博客中获得更多关于制作"UmbrellaFramework"的细节
我尝试做@Segev建议的操作,但是不断收到错误消息,指出缺少嵌入式框架文件。
但是,做了一些额外的配置,我设法使其正常工作!
这是我所做的:
您将看到伞形框架的“ Headers”文件夹将包含“ EmbeddedFramework.h”文件
您可以在此处查看示例项目:
希望这可以帮助
| 归档时间: |
|
| 查看次数: |
30721 次 |
| 最近记录: |