IOS Static Framework con recursos dentro
frameworks uiimageview (7)
Estoy tratando de crear un marco que mantenga algún código común que uso en mis proyectos. Encontré tutoriales en línea y logré crear un marco, pero todavía tengo un problema relacionado con los recursos (xibs, imágenes, etc.).
Digamos que tengo un MainViewController.xib
que tiene un UIImageView
utilizando un test.png
. Todos estos están en mi paquete de marco.
Cuando uso el marco en otro proyecto, lo agrego a la fase de compilación "Copiar recursos del paquete". El problema es que solo se puede acceder a la xib mediante una ruta como dummy.framework/Resources/MainViewController.xib
y el UIImageView
interior no puede cargar test.png
.
Parece que UIImageView intentará cargar el png desde la raíz del paquete, y no desde la carpeta relativa donde también se almacena el xib.
¿Alguien ha logrado crear un marco con código y recursos y usarlo en otro proyecto?
A partir de Xcode 7 ahora podemos utilizar los catálogos de activos. En mis experimentos, descubrí que puede hacer referencia a archivos en el mismo espacio de trabajo, proyectos diferentes que eliminan la necesidad de administrar los activos de forma micro en las fases de construcción o preocuparse por los objetivos.
Creé un objetivo de marco y para acceder a las imágenes dentro de su catálogo de activos hice lo siguiente:
UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]];
Los marcos básicos no incluyen la mayoría de los tipos de recursos, para incluir recursos use esta biblioteca de marcos "falsos"
Usted termina con una carpeta .embeddedframework que contiene el marco de trabajo real, pero también incluye cualquier recurso que agregue a la fase de compilación de Copiar recursos del paquete. Lo he usado para incluir xibs, modelos de datos centrales, imágenes y plistas
Para cargar una imagen desde un framework dinámico en Swift 3 :
UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)
Respuesta corta: no puedes.
Cuando compila la aplicación, el paquete se genera con los recursos del proyecto "principal", ignorando los recursos en los marcos vinculados. Esto incluye imágenes, xib''s, plist''s, etc. (cualquier cosa que no sea un archivo fuente)
Lo que debe hacer es agregar esos recursos a su proyecto principal para que estén disponibles para su uso dentro de su aplicación, no la forma más feliz de hacerlo, pero funcionará.
Sé que este es un hilo viejo, pero para evitar que nuevas personas cometan los mismos errores, aquí hay una nota:
A partir de Xcode 6 y iOS8, Apple tiene una solución de Dynamic Framework de primera instancia totalmente compatible. Para obtener más información, consulte aquí: https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14
Pero en breve, cree un nuevo proyecto y elija la plantilla de Cocoa Touch Framework.
Ya no administro los marcos manualmente, sino que uso y recommend CocoaPods en su lugar.
Respuesta original:
- Utilice el marco falso @ wattson12 mencionado. Se compilará y guardará los recursos también.
Inspirado por este script , agregue esto a su destino para copiar los recursos a su aplicación:
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
También puede simplemente arrastrar el marco a su paso de Copiar recursos, pero luego también agregará encabezados innecesarios y código compilado.
Editar
Para usar estos recursos de IB, por ejemplo, un archivo png, reemplace:
MyImage
por:
MYFrameworkResources.bundle/MyImage.png
Obtendrá una vista previa de un icono de imagen roto, pero funcionará cuando se ejecute.
Cargue un Nib desde el código:
[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ...
Finalmente, puede agregar estos métodos en una categoría de NSBundle para facilitar el acceso a los recursos de Nib que pueden estar en su paquete principal o en MYFrameworkResources.bundle:
@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
Primero examinará su paquete de aplicaciones y luego en MYFrameworkResources.bundle, etc.