2010-01-24 12 views
29

Ho un client < => app server che sto creando per Mac OS X, utilizzando Objective-c/Cocoa e xCode. Ho creato un progetto diverso per entrambe le app che ho, e mi chiedo il modo migliore per condividere le classi tra loro. Ci sono diverse classi che ho fatto che potrebbero essere utili a entrambi. Finora li ho copiati, ma ritengo che questa non sia la soluzione migliore.Condivisione di classi tra progetti in xcode/objective-c

Come si condividono le classi in modo efficace? Devo rifarlo come 1 progetto e ho solo due obiettivi di compilazione? Come faccio a fare questo?

Altre informazioni?

Grazie.

risposta

12

Se si dispone di due o più prodotti che condividono una buona quantità di codice comune, come una suite di prodotti, è consigliabile prendere in considerazione la creazione di un solo progetto xcode e quindi aggiungere un target diverso per ciascun prodotto che sarà costruito sia dal codice condiviso che dal codice specifico del prodotto. Con un sacco di codice condiviso, una coppia client/server di prodotti potrebbe essere un ottimo candidato per andare in questo modo.

Boiled-down, l'accordo di base è che per ciascun target nel progetto xcode che si desidera creare, si specificano i file da utilizzare per crearlo: file di origine, arte, xibs e così via. In questo modo, ad esempio, è possibile impostare il prodotto client da compilare utilizzando i file A, B, C, D, E, F e il prodotto server da creare utilizzando i file A, F, X, Y, Z.

Mi piace molto avere ogni prodotto correlato che vive sotto un unico progetto xcode "tetto", perché non si deve saltare intorno ai progetti xcode e semplifica davvero la gestione SCM per i file condivisi.

Ecco un link alla documentazione di Apple su questo: https://developer.apple.com/library/mac/#featuredarticles/XcodeConcepts/Concept-Targets.html

Update: c'è un po 'di fastidio in più coinvolto quando si tratta di configurare i file di intestazione specifica bersaglio in Xcode (è sempre qualcosa ... giusto ?!); per esempio, usa "myHeaderA.h" per questo target e "myHeaderB.h" per quel target. Ecco un ottimo post che spiega come farlo: controlling which project header file Xcode will include. Attenzione: dopo aver impostato le cose in questo modo, xcode non conosce più percorsi per cercare i file di intestazione di destinazione, quindi è necessario impostarli manualmente. Per fare ciò, fare clic con il tasto destro del mouse su Ottieni informazioni sul target, selezionare Crea categoria, quindi aggiungere i percorsi tramite l'impostazione "Percorsi di ricerca intestazione". I percorsi vengono cercati nell'ordine in cui li inserisci.

+0

È possibile farlo ora con il nuovo spazio di lavoro? –

+1

Sì. Ora eseguo Xcode 4.3.2 e non ho bisogno di cambiare nulla. –

4

Il modo migliore è creare un quadro separato contenente le classi condivise. Questo può essere compilato una volta e collegato in entrambi i progetti applicativi.

Vedere Apple's doc on what are Frameworks.

+2

Nella mia esperienza, i framework sono adatti solo per il codice che hai veramente bloccato; dove non ti aspetti cambiamenti. (E, in realtà, questo non succede mai. Le cose cambiano sempre.) Suonano bene sulla carta, ma le strutture tendono a intralciare, soffocano lo sviluppo rapido e l'innovazione (perché non vuoi andare a cambiare il quadro si rompe qualcosa in un'altra app) e in genere sono una scelta sbagliata per la condivisione del codice a meno che non si aggiorni le librerie una volta all'anno (ad esempio Apple). – Womble

+1

@Womble bene, non modificare nulla che possa eventualmente rompere qualcosa in un'altra app ...se ti accorgi di volerlo fare, contrassegna il vecchio metodo come deprecato e scrivine uno nuovo ... –

2

La soluzione più rapida consiste nell'aggiungere solo i riferimenti dei file .h e .m a uno dei progetti. Basta deselezionare la casella "copia" nella casella "aggiungi file esistenti" - dialoghi in xcode. Tieni presente che potresti dover copiare i file di riferimento anche se sposti/condividi il tuo progetto.

+1

Questo dovrebbe funzionare bene con il controllo del codice sorgente? Immagino che la soluzione dei framework funzionerebbe in modo più naturale con CVS e amici. – Spina

1

ho trovato un bel articolo su questo argomento qui: http://www.clintharris.net/2009/iphone-app-shared-libraries/ Questo risponde alla mia domanda, che è specificamente multiple applicazioni iPhone condivisione del codice. Non menziona i framework (sopra) quindi non posso dire se il loro suggerimento (riferimenti al progetto xcode) sia favorevole alla soluzione framework.

+0

La situazione è molto diversa su iPhone con il suo filesystem e le restrizioni della libreria condivisa. –

11

Un ottimo modo per farlo è inserire il codice condiviso nel sistema SCM e includerlo in ogni progetto in cui lo si desidera. In questo modo ogni progetto può condividere il codice, è possibile modificarlo ovunque e controllare semplicemente le modifiche torna nel controllo del codice sorgente quando ti senti bene - e poi tutti gli altri progetti traggono vantaggio dal tuo lavoro.

Questo ha grandi vantaggi rispetto ad altri modi di farlo IMO:

vs. frameworks: Imballo Codice in un quadro è abbastanza fastidioso, e fascio-privato quadri prendere un irragionevolmente molto tempo per caricare - specialmente subito per ottenere alcune classi nella tua app. Wil Shipley di Omni Group (al momento) ha scoperto che i framework che l'azienda includeva in tutte le loro app aggiungevano diversi secondi all'ora di inizio di ogni app. Packaging lezioni private in un quadro può anche incoraggiare un maggior numero di accoppiamento di quanto sia strettamente necessario - è davvero allettante solo per fare un vero e proprio quadro in cui tutte le classi condivise risiedono, in modo da iniziare supponendo che questo codice sarà sempre vivere insieme. e diventa inseparabile. Fondamentalmente, le strutture sono un martello e questo problema è una vite.

vs. solo inclusi i file: Spero che possiate mettere la vostra applicazione in uno SCM ad un certo punto in ogni caso, e semplicemente inclusi i file sul posto crea un problema, perché essi saranno mancanti dal SCM. Copiare i file in ogni progetto introduce il problema opposto: ogni progetto includerà la propria versione dei file e dovrai propagare manualmente qualsiasi modifica utile.

+2

Ciao Chuck, sto prendendo in considerazione questo approccio, ma non sono sicuro di cosa significhi "includerlo in ogni progetto in cui lo vuoi". Stai parlando di fare qualcosa in XCode o forse qualcosa di simile alle proprietà degli esterni di SVN? Cosa intendi esattamente? Grazie. – Cal

+1

Grazie per la risposta Chuck, questo suona come la strada da percorrere per me. Tuttavia, sono praticamente un debuttante su questo argomento. Avete qualche fonte con una spiegazione/esempio più dettagliata? – Tom

+0

@chuck Qualche possibilità hai trovato in un tutorial o scrivi su ciò che proponi? –

2

Ho avuto un problema simile, e la risposta sopra accettata potrebbe causare problemi per un principiante.

Va bene se i due progetti comunicano con un protocollo, ad es. TCP/IP o se non comunicano. Se tuttavia un progetto è un pacchetto (ad esempio un plug-in) che deve accedere alle stesse classi di un'applicazione (mentre viene eseguito nello stesso processo) si avranno problemi con avvisi di collegamento o di runtime/errori relativi all'utilizzo di classi con lo stesso nome. Il modo più semplice per risolvere questo problema è usare un framework. Con un framework è possibile configurarlo in modo che tutti e tre i target si trovino nello stesso progetto, oppure è possibile includere anche il framework in progetti separati.

ho avuto un progetto con un app e un plug-in bundle, qui sono i passi che ho seguito in Xcode 6:

  1. creare un quadro, copiare tutto il codice condiviso sopra.
  2. Nell'intestazione principale del framework, includere le intestazioni di tutto il codice condiviso.
  3. Costruisci il framework per testarlo (ad esempio seleziona lo schema del framework e fai clic su play)
  4. Vai alla sezione Fasi di creazione del pacchetto di applicazioni e plugin e aggiungi il nuovo framework a "dipendenze di destinazione" e 'binario di collegamento con le librerie'
  5. Per includere la roba quadri nel codice nella app e bundle, basta usare l'intestazione principale, e utilizzare <> piuttosto che “" ad esempio, se il vostro quadro è stato chiamato Foo utilizzare #import

Le modifiche al framework verranno compilate automaticamente quando si esegue l'app principale, quindi è possibile ignorare il fac sono obiettivi diversi.

Problemi correlati