2012-08-29 19 views
15

Sto provando a creare un framework che mantenga alcuni codici comuni che utilizzo nei miei progetti. Ho trovato tutorial online e sono riuscito a creare un framework ma ho ancora un problema relativo alle risorse (xibs, immagini, ecc.).IOS Static Framework con risorse interne

Diciamo che ho uno MainViewController.xib che ha unutilizzando un test.png. Tutti questi sono nel mio pacchetto quadro.

Quando utilizzo il framework in un altro progetto, lo aggiungo alla fase di compilazione "Copia risorse pacchetto". Il problema è che lo xib è accessibile solo utilizzando un percorso come dummy.framework/Resources/MainViewController.xib e il UIImageView interno non può caricare test.png.

Sembra che UIImageView proverà a caricare il png dalla radice del pacchetto e non dalla relativa cartella in cui è memorizzato anche lo xib.

Qualcuno è riuscito a creare un framework con codice e risorse e usarlo in un altro progetto?

+1

Hi Andrei, puoi dirmi come si aggiunge il file nella directory .bundle quadro ... i non sono in grado di farlo. potrebbe esserci qualche errore nel mio script di shell. – Apple

risposta

0

Risposta breve: non è possibile.

Quando si compila l'applicazione, il pacchetto viene generato con le risorse del progetto "principale", ignorando le risorse nei framework collegati. Ciò include immagini, xib, plist ecc. (Tutto ciò che non è un file sorgente)

Ciò che devi fare è aggiungere quelle risorse al tuo progetto principale in modo che siano disponibili per l'uso all'interno dell'applicazione, non il modo più felice intorno, ma funzionerà.

+0

Bene, le risorse vengono copiate, ma in una sottocartella. –

+2

Questa è la risposta più vicina ai fatti reali. È tuttavia possibile forzare xcode a copiare risorse da un framework, ma saranno collocate in una sottocartella nel bundle principale. Questo rende il loro caricamento un rompicoglioni. –

+0

Ora puoi farlo ora – doozMen

1

quadri di base non comprendono la maggior parte dei tipi di risorse, per includere le risorse utilizzare this "fake" framework library

Si finisce con una cartella .embeddedframework che contiene il quadro attuale, ma comprende anche tutte le risorse che si aggiungono alla copia Bundle Risorse fase di costruzione. L'ho usato per includere xibs, modelli di dati di base, immagini e plists

+0

Sì, ma se hai (nel framework) uno xib che usa una risorsa che è anche nel framework (un'immagine diciamo). Sarai in grado di caricare lo xib nell'applicazione di test? –

+0

Non ho quel progetto di fronte a me ma sono abbastanza sicuro che sarebbe ok, dargli un colpo ... – wattson12

+0

Ho concluso che ciò che voglio ottenere non è realmente possibile. A causa dell'incapacità di Interface Builder di visualizzare immagini che si trovano in sottocartelle (funzionano comunque su runtime), non è davvero fattibile consegnare alcuna risorsa in un modulo bundle. Il modo migliore sarebbe semplicemente aggiungere un zip insieme alla libreria statica e l'utente può usare quella cartella nel suo progetto. –

4

Non gestisco più manualmente i framework ma uso e recommendCocoaPods invece.


risposta originale:

  1. Utilizzare la fake framework @ wattson12 menzionato. Compilerà e salverà anche le risorse.
  2. Ispirato this script, aggiungere questo al vostro obiettivo per copiare le risorse per la vostra applicazione:

    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 
    

Si potrebbe anche solo trascinare il quadro di riferimento per il vostro passo Copia risorse, ma allora sarete aggiungendo intestazioni non necessarie e codice compilato pure.

Modifica

Per utilizzare queste risorse da IB, per esempio un file PNG, sostituire:

MyImage 

da:

MYFrameworkResources.bundle/MyImage.png 

Sarà l'anteprima di un'immagine icona rotto, ma funzionerà durante l'esecuzione.

Caricare un pennino dal codice:

[NSBundle loadNibNamed:@"MYFrameworkResources.bundle/MyNib" ... 

Infine è possibile aggiungere questi metodi in una categoria NSBundle per facilitare l'accesso alle risorse pennino che il mio essere nel vostro pacchetto principale o in 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 

si cercherà prima nella vostra bundle dell'applicazione e poi in MYFrameworkResources.bundle, ecc

+0

Grazie, ma il generatore di interfacce non rileva ancora correttamente le risorse –

+0

Hai problemi con le immagini? (prepending il percorso è sufficiente) o con i pennini? Puoi anche controllare la directory di costruzione per vedere dove vengono copiate le risorse all'interno della tua app. – Rivera

12

so che questo è un vecchio thread, ma per mantenere le nuove peopl e dal fare gli stessi errori qui è una nota:.

Come di Xcode 6 e iOS 8, Apple ha una prima parte completamente supportata soluzione quadro dinamico costruito in Per ulteriori informazioni consultare qui: https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_6_0.html#//apple_ref/doc/uid/TP40014509-SW14

Ma il corto di è, creare un nuovo progetto e scegliere il modello di Cocoa Touch Framework.

+0

Tutto bene e bene, ma sei riuscito a includere le risorse di immagine in un Dynamic Framework creato in Xcode 6. Ho provato tutto da solo, ma non riesco a farlo funzionare! Sembra essere molto poca documentazione da Apple su di esso. – simonthumper

+9

Sì. è stato abbastanza semplice ma forse non ovvio. Semplice includere le tue immagini nel tuo framework come normale, ma per caricarle, devi fare riferimento al fascio del tuo framework. Quindi '[NSBundle bundleWithIdentifier: @" com <#company#>. <#framework#> "];' –

+0

Non hai bisogno di scherzare con la creazione di un fascio o altro. Il framework Xcode gestisce quello per te. Ma devi caricarli da quel bundle predefinito. Trovo utile creare una categoria NSBundle con una scorciatoia per la categoria framework. –

7

ho creato un bersaglio quadro e per accedere alle immagini all'interno del suo catalogo di asset ho il seguente:

UIImage *img = [UIImage imageNamed:@"IMAGE_NAME_HERE" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:[UITraitCollection traitCollectionWithDisplayScale:[UIScreen mainScreen].scale]]; 
+0

Grazie mille, ho perso un sacco di tempo cercando di trovare una soluzione per questo. e questo ha funzionato :) – Ismail

-1

Come di Xcode 7 ora possiamo usare Asset Cataloghi. Nei miei esperimenti ho scoperto che puoi fare riferimento a file nello stesso spazio di lavoro, ma progetti diversi rimuovono la necessità di gestire le risorse in fase di compilazione o di preoccuparsi degli obiettivi.

+0

Questa risposta non è correlata alla domanda – doozMen

0

Al fine di caricare un'immagine da un quadro dinamico in Swift 3:

UIImage(named: "name", in: Bundle(for: type(of: self)), compatibleWith: nil)

Problemi correlati