2010-12-21 6 views
12

Ich habe eine vorhandene Anwendung, die für verschiedene Kundenanpassen iphone app für verschiedene Kunden

Jeder Kunde benötigt ihr eigenes Symbol und Splash-Screen kompiliert werden muss.
Ich möchte auch in der Lage sein, verschiedene Funktionen abhängig davon, ob der jeweilige Client sie benötigt oder nicht, bedingt zu berücksichtigen.

Ich habe versucht, verschiedene Ziele für jeden Kunden einzurichten, aber bisher nicht viel Glück.
Die verschiedenen Ressourcen mit dem gleichen Namen, aber einem anderen Pfad bleiben durcheinander.

Idealerweise möchte ich in der Lage sein, eine App zu erstellen, indem ich einen anderen ähnlichen Client dupliziere und dann die minimale Anzahl von Änderungen an der App für den neuen Client anlege.

Wie kann ich diese App am besten einrichten?

+0

Vielen Dank für eine Prämie für das Aufstellen. Selbes Problem hier. FWIW, siehe meine Frage zu einem ähnlichen Thema: http://stackoverflow.com/questions/4112483/how-does-xcode-handle-import-header-statements-in-with-multiple-targets – makdad

Antwort

9

Separate Ziele für jeden Client sollte der Weg sein. Für die Funktionen würde ich vorschlagen, zuerst ein Makro zu erstellen, das den Client in den Zieleinstellungen identifiziert (unter "Präprozessor-Makros" auf der Registerkarte "Erstellen") und dann über FeatureDefines verfügt.h-Datei, die wie folgt aussieht:

#ifdef macroClientA // assume client A wants features 1 and 3 
# define macroFeature1 
# define macroFeature3 
#endif 

// and similarly for the other clients 

Jetzt können Sie

verwenden
#import featureDefines 
#ifdef macroFeature1 

jeder Ort, den Sie brauchen, um zu testen, ob Merkmal 1 erwünscht ist oder nicht.

Für die separaten Symbole können Ihre Zieleinstellungen für jeden Client eine andere Datei info.plist angeben, und diese Dateien können wiederum einen anderen Dateinamen für das Symbol angeben.

Für die separaten Begrüßungsbildschirme erfordert iOS immer, dass der Begrüßungsbildschirm den Namen Default.png trägt. Sie können jedoch in verschiedene Unterverzeichnisse Ihres Projektverzeichnisses wechseln. Sie können steuern, welche für welches Ziel verwendet wird, indem Sie mit der rechten Maustaste auf Xcode "Gruppen & Dateien" klicken, Zielmitgliedschaft auswählen, das Kontrollkästchen für das gewünschte markieren und sicherstellen, dass die anderen nicht markiert sind.

Für Ressourcen, würde ich vorschlagen, Ihre Ressource-Dateien wie diese Namensgebung: verwendet werden

resourceName.ext // generische Ressource, wenn es keine kundenspezifische eines
resource-clientName.ext ist // client- spezifische Ressource

Als nächstes setzen eine allgemeine Ressource-Finder-Methode auf, die etwa wie folgt aussieht:

-(NSString *) resourcePathForResourceName: (NSString *) resourceName extension: (NSString *) ext { 
    NSString *clientName; 
    #ifdef macroClientA 
    clientName = @"clientA"; 
    #endif // and similarly for the other clients 
    NSString *clientSpecificName = [NSString stringWithFormat: @"%@-%@.%@", resourceName, clientName, ext]; 
    NSString *genericName = [NSString stringWithFormat: @"%@.%@"]; 
    if ([[NSFileManager defaultManager] fileExistsAtPath: clientSpecificName]) 
    return clientSpecificName; 
    else if ([[NSFileManager defaultManager] fileExistsAtPath: genericName]) 
    return genericName; 
    else 
    // handle the error 
} 

alle Datei Ihre Ressource Lauf greift durch diese Methode wird es Ihnen ermöglichen, Fügen Sie Ihrem Projekt mandantenspezifische Ressourcen hinzu, ohne eine einzelne Codezeile zu ändern.

+0

Danke, ich akzeptiere diese Antwort, da es mehr oder weniger die Art ist, wie ich das Problem gelöst habe. –

3

Sie könnten ein separates Ziel für jeden Client erstellen und jedes Client-Assets in einem eigenen Ordner mit demselben Namen ablegen. Ich habe etwas Ähnliches gemacht, wo ich zwei Projekte hatte, die viel gemeinsam hatten und nur die entsprechenden Assets aus jedem Projekt hinzufügten/entfernten.

Bei diesem Szenario können Sie zu diesem Zeitpunkt einfach einen neuen Ordner mit den clientspezifischen Ressourcen für jedes Ziel hinzufügen, ohne Codeänderungen zu benötigen. Wenn die Pfade ein Problem darstellen, könnten Sie die Methode [UIImage imageNamed:] in Betracht ziehen, bei der nicht der vollständige Pfad, sondern nur der Dateiname erforderlich ist.

0

Schreiben Sie Ihren Code, damit eine externe Konfigurationsdatei den Großteil der Installation ausführen kann, und fügen Sie dann die korrekten Assets zu Ihren Zielen hinzu. Wenn Sie ein Projekt mit einem neuen Ziel für jeden Kunden haben, können Sie auswählen, welche Assets in jedes Ziel aufgenommen werden. Wenn Sie Probleme mit den mehreren Zielen haben, können Sie mit git ein Kernprojekt verwalten und dann für jeden Client verzweigen.

6

Ich habe ein ähnliches Szenario und wie ich damit umgehen ist wie folgt:

1) der Kern-Code der App in einem „application_name-base“ -Ordner

2) unterschiedliche Kunden in sind gehalten ihr "application_name-client_name" -Ordner

3) Die Projektdatei befindet sich im Client-Ordner und enthält die Referenzen aus dem Basisordner, ohne die Kopie zu verwenden.

4) Dateien, die für das Projekt des Clients eindeutig sein müssen, befinden sich im Client-Ordner. Normalerweise Bilder mit dem gleichen Namen. oder .h .m-Dateien, die für das einzelne Projekt eindeutig sein müssen. Außerdem können Sie Dateien nicht projektweise einschließen.

Hält den Code zentral, ermöglicht jedoch unterschiedliche Codes pro Client, ohne zu Verwechslungen zu führen.

+0

Dies mit unterschiedlichen Zielen zu Geben Sie an, welcher Quellordner verwendet werden soll. Viel sauberer als Namensmangel. – Nuthatch

0

Ich würde nur eine Einstellungsschnittstelle für einen Client erstellen, um die App an die individuellen Bedürfnisse anzupassen. Zum Beispiel, Bereitstellung des Bildes von ihrer Foto-Bibliothek, etc.

0

Sie können ein Projekt für jeden Kunden erstellen und alle Quellen aus demselben Pfad einschließen, ohne sie in das Projektverzeichnis zu kopieren. So können Sie Symbol/Begrüßungsbildschirm in einem Projekt ersetzen, während Sie die gleiche Codebasis verwenden. Das sieht nach dem bisher einfachsten Weg aus.