プロジェクトで使用する一般的なコードを保持するフレームワークを作成しようとしています。オンラインチュートリアルを見つけてフレームワークを作成できましたが、リソース(xibs、画像など)に関連する問題が1つあります。
MainViewController.xib
を使用してUIImageView
を持つtest.png
があるとします。これらはすべて私のフレームワークパッケージに含まれています。
別のプロジェクトでフレームワークを使用する場合は、「バンドルリソースのコピー」ビルドフェーズに追加します。問題は、xibはdummy.framework/Resources/MainViewController.xib
のようなパスを使用してのみアクセス可能であり、内部のUIImageView
はtest.png
をロードできないことです。
UIImageViewは、xibも保存されている相対フォルダーからではなく、バンドルのルートからpngを読み込もうとしているようです。
コードとリソースを使用してフレームワークを作成し、それを別のプロジェクトで使用することに成功した人はいますか?
簡単な答え:できません。
アプリをコンパイルすると、リンクされたフレームワークのリソースを無視して、「メイン」プロジェクトのリソースを使用してバンドルが生成されます。これには、画像、xib、plistなど(ソースファイル以外のもの)が含まれます。
あなたがする必要があるのは、それらのリソースをメインプロジェクトに追加して、アプリケーション内で使用できるようにすることです。これは、最も幸せな方法ではありませんが、機能します。
私はこれが古いスレッドであることを知っていますが、新しい人々がここで同じ間違いをしないようにするために、注意があります:
Xcode 6およびiOS8の時点で、Appleには完全にサポートされているファーストパーティのDynamicFrameworkソリューションが組み込まれています。詳細については、こちらをご覧ください: https://developer.Apple.com/library /ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//Apple_ref/doc/uid/TP40014509-SW14
しかし、それが不足しているのは、新しいプロジェクトを作成し、Cocoa TouchFrameworkテンプレートを選択することです。
フレームワークターゲットを作成し、そのアセットカタログ内の画像にアクセスするために、次のことを行いました。
UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
フレームワークを手動で管理することはもうありませんが、代わりにand recommendCocoaPods を使用します。
元の回答:
このスクリプト に触発され、これをターゲットに追加して、リソースをアプリにコピーします。
SOURCE_PATH="${TARGET_BUILD_DIR}/MYFramework.framework/Resources/"
TARGET_PATH="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MYFrameworkResources.bundle"
mkdir -p $TARGET_PATH
cp -R $SOURCE_PATH $TARGET_PATH
フレームワークをリソースのコピーステップにドラッグすることもできますが、その場合、不要なヘッダーとコンパイルされたコードも追加されます。
編集
IBのこれらのリソース(たとえばpngファイル)を使用するには、次を置き換えます。
MyImage
沿って:
MYFrameworkResources.bundle/MyImage.png
壊れた画像アイコンをプレビューしますが、実行中は機能します。
コードからペン先をロードします。
[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...
最後に、これらのメソッドをNSBundleカテゴリに追加して、メインバンドルまたはMYFrameworkResources.bundleにあるNibリソースへのアクセスを容易にすることができます。
@implementation NSBundle (MyCategory)
+ (NSString *)pathForResource:(NSString *)name
ofType:(NSString *)extension
{
// First try with the main bundle
NSBundle * mainBundle = [NSBundle mainBundle];
NSString * path = [mainBundle pathForResource:name
ofType:extension];
if (path)
{
return path;
}
// Otherwise try with other bundles
NSBundle * bundle;
for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
inDirectory:nil])
{
bundle = [NSBundle bundleWithPath:bundlePath];
path = [bundle pathForResource:name
ofType:extension];
if (path)
{
return path;
}
}
NSLog(@"No path found for: %@ (.%@)", name, extension);
return nil;
}
+ (NSArray *)loadNibNamed:(NSString *)name
owner:(id)owner
options:(NSDictionary *)options
{
// First try with the main bundle
NSBundle * mainBundle = [NSBundle mainBundle];
if ([mainBundle pathForResource:name
ofType:@"nib"])
{
NSLog(@"Loaded Nib named: '%@' from mainBundle", name);
return [mainBundle loadNibNamed:name
owner:owner
options:options];
}
// Otherwise try with other bundles
NSBundle * bundle;
for (NSString * bundlePath in [mainBundle pathsForResourcesOfType:@"bundle"
inDirectory:nil])
{
bundle = [NSBundle bundleWithPath:bundlePath];
if ([bundle pathForResource:name
ofType:@"nib"])
{
NSLog(@"Loaded Nib named: '%@' from bundle: '%@' ", name, bundle.bundleIdentifier);
return [bundle loadNibNamed:name
owner:owner
options:options];
}
}
NSLog(@"Couldn't load Nib named: %@", name);
return nil;
}
@end
最初にアプリケーションバンドルを調べ、次にMYFrameworkResources.bundleなどを調べます。
基本的なフレームワークには、ほとんどの種類のリソースが含まれていません。リソースの使用を含めるために この「偽の」フレームワークライブラリ
最終的には、実際のフレームワークを含む.embeddedframeworkフォルダーが作成されますが、バンドルリソースのコピービルドフェーズに追加するリソースも含まれます。私はそれを使用して、xib、コアデータモデル、画像、およびplistを含めました
Swiftの動的フレームワークから画像をロードするには:
UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)