2014-02-18 4 views
10

Auf den Punkt gebracht:Wie kann ich ein Bild von Assets.car (kompilierte Version von xcassets) in einem NSBundle laden?

Wie kann ich innerhalb eines NSBundle Bilder aus einer kompilierten Assets.car laden?

Full Version:

Ich bin im Begriff, eine Suite von Anwendungen zur Umwandlung von CocoaPods zu verwenden. Jede App basiert auf einem freigegebenen Pod namens Core.

Core enthält Codedateien, xib Dateien und mehrere xcasset Dateien.

Hier ist die entsprechende Zeile aus dem Podspec für Core, die das Ressourcenpaket erstellt:

s.resource_bundles = {'CoreResources' => ['Core/Resources/*']} 

Die Podspec geht pod spec lint und Hauptprojekt, das auf sie baut richtig setzt.

jedoch keine der Bilder von allen xcasset Dateien innerhalb Core zeigen.

ich bin (naiv) versucht, die Bilder mit einer Kategorie auf UIImage wie folgt zu laden:

@implementation UIImage (Bundle) 

+ (UIImage *)imageNamed:(NSString *)name bundle:(NSBundle *)bundle 
{ 
    if (!bundle) 
     return [UIImage imageNamed:name]; 

    UIImage *image = [UIImage imageNamed:[self imageName:name forBundle:bundle]]; 
    return image; 
} 

+ (NSString *)imageName:(NSString *)name forBundle:(NSBundle *)bundle 
{ 
    NSString *bundleName = [[bundle bundlePath] lastPathComponent]; 
    name = [bundleName stringByAppendingPathComponent:name]; 
    return name; 
} 
@end 

Zuvor war Core eine submodule, und diese Lösung funktionierte gut. Doch bei der Untersuchung meiner früheren bundle Datei (getrennt von main Bündel), bemerkte ich, dass alle Bilder wurden einfach in die bundle kopiert werden ... das heißt

Image.png, [email protected], etc alle im Bündel waren.

Bei näherer Betrachtung des CocoaPods -Generated Bündel, es enthält ein

Assets.car

, die ich verstehe, eine kombinierte, kompilierte Version von zu sein, alle die xcasset Dateien innerhalb des Core Unterverzeichnis.

Wie kann ich Bilder von diesem kompilierten Assets.car innerhalb dieses Core Ressourcenbündels laden?

Als Hack, ich nehme an, ich könnte ...

Die Podspec syntax reference gibt dies als Beispiel:

spec.resource = "Resources/HockeySDK.bundle" 

Dies scheint darauf hinzudeuten, dass es zu schaffen das Bündel manuell möglich ist innerhalb von Xcode und CocoaPods einfach kopieren.

Dies ist eher eine Hack als eine Lösung.

Ich glaube CocoaPods (v 0.29+) kann dies vollständig ...?

Antwort

4

Ich war in der gleichen Situation wie Sie, und ich endete mit dem "Hack" Sie erwähnt, aber es ist während Pod-Installation automatisiert, so dass es viel wartbarer ist.

In meinem podspec Ich habe

# Pre-build resource bundle so it can be copied later 
    s.pre_install do |pod, target_definition| 
    Dir.chdir(pod.root) do 
     command = "xcodebuild -project MyProject.xcodeproj -target MyProjectBundle CONFIGURATION_BUILD_DIR=Resources 2>&1 > /dev/null" 
     unless system(command) 
     raise ::Pod::Informative, "Failed to generate MyProject resources bundle" 
     end 
    end 
    end 

Dann später im podspec:

s.resource = 'Resources/MyProjectBundle.bundle' 

Der Trick hier ist das Bündel zu bauen, bevor pod so installieren, dass die .bundle verfügbar ist, und kann dann einfach so verknüpft werden, als ob Sie die ganze Zeit in der Quelle hätten. Auf diese Weise kann ich einfach neue Ressourcen/images/xibs in das Bundle-Ziel einfügen und sie werden kompiliert und verlinkt. Klappt wunderbar.

Die Ich habe eine Kategorie auf NSBundle + MyResources, die einen einfachen Zugang zu den Bündel Ressourcen erlaubt:

+ (NSBundle *)myProjectResources 
{ 
    static dispatch_once_t onceToken; 
    static NSBundle *bundle = nil; 
    dispatch_once(&onceToken, ^{ 
     // This bundle name must be the same as the product name for the resources bundle target 
     NSURL *url = [[NSBundle bundleForClass:[SomeClassInMyProject class]] URLForResource:@"MyProject" withExtension:@"bundle"]; 
     if (!url) { 
      url = [[NSBundle mainBundle] URLForResource:@"MyProject" withExtension:@"bundle"]; 
     } 
     bundle = [NSBundle bundleWithURL:url]; 
    }); 
    return bundle; 
} 

Also, wenn Sie zum Beispiel zu ladende ein Datenmodell Kern:

NSURL *modelURL = [[NSBundle myProjectResources] URLForResource:@"MyModel" withExtension:@"momd"]; 

Ich habe einige bequeme Methoden gemacht Bilder zugreifen und:

+ (UIImage *)bundleImageNamed:(NSString *)name 
{ 
    UIImage *imageFromMainBundle = [UIImage imageNamed:name]; 
    if (imageFromMainBundle) { 
     return imageFromMainBundle; 
    } 

    NSString *imageName = [NSString stringWithFormat:@"MyProject.bundle/%@", name]; 
    UIImage *imageFromBundle = [UIImage imageNamed:imageName]; 
    if (!imageFromBundle) { 
     NSLog(@"Image not found: %@", name); 
    } 
    return imageFromBundle; 
} 

hatte noch nicht das auf mich nicht.

+0

+1: Ja, ich habe etwas sehr ähnliches getan. Sie können CocoaPods tatsächlich dazu veranlassen, das Ressourcenbündel vollständig für Sie zu erstellen - ohne die Vorinstallations-Hooks zu benötigen. Ich werde versuchen, dies als eine andere mögliche Lösung für diese bald zu schreiben. –

+0

@ JRG-Entwickler Super, würde es gerne sehen. – Wilmar

+0

Würde mich freuen, moderne Nicht-Hack-Version zu sehen –

Verwandte Themen