2010-01-24 14 views
29

Tengo un cliente < => aplicación de servidor que estoy construyendo para Mac OS X, usando Objective-c/Cocoa y xCode. Creé un proyecto diferente para ambas aplicaciones, y me pregunto cuál es la mejor manera de compartir clases entre ellas. Hay varias clases que he hecho que serían útiles para ambos. Hasta aquí los he estado copiando, pero siento que esta no es la mejor solución.Compartiendo clases entre proyectos en xcode/objective-c

¿Cómo comparto clases de manera efectiva? ¿Debo rehacerlo como 1 proyecto y solo tengo dos objetivos de compilación? ¿Cómo hago esto?

¿Alguna otra información?

Gracias.

Respuesta

12

Si tiene dos o más productos que van a compartir una buena cantidad de código común, como un conjunto de productos, es posible que desee considerar la creación de un solo proyecto xcode y luego agregar un objetivo diferente para cada producto que se compilará a partir de código compartido y específico del producto. Con una gran cantidad de código compartido, un par de productos cliente/servidor posiblemente sería un gran candidato para ir de esta manera.

Disminuido, el trato básico es que para cada objetivo en su proyecto xcode que desee construir, especifique qué archivos se deben usar para compilarlo: archivos fuente, art, xibs, etc. De esta forma, por ejemplo, puede configurar su producto cliente para que se construya utilizando los archivos A, B, C, D, E, F y su producto de servidor que se construirá utilizando los archivos A, F, X, Y, Z.

Me gusta mucho tener todos los productos relacionados que viven bajo un único proyecto xcode "techo", porque no tendrás que saltar alrededor de proyectos xcode, y realmente simplifica la gestión de SCM para los archivos compartidos.

Aquí hay un enlace a la documentación de Apple en esto: https://developer.apple.com/library/mac/#featuredarticles/XcodeConcepts/Concept-Targets.html

Actualización: hay un poco de molestia adicional involucrado cuando se trata de la configuración de archivos de cabecera específicos de la diana en Xcode (que es siempre algo ... ¿no ?!); por ejemplo, use "myHeaderA.h" para este objetivo y "myHeaderB.h" para ese objetivo. Aquí hay una gran publicación que comparte cómo hacerlo: controlling which project header file Xcode will include. Precaución: después de configurar las cosas de esta manera, xcode ya no conoce ninguna ruta para buscar ninguno de sus archivos de encabezado de destino, por lo que debe configurarlos manualmente. Para ello, haga clic con el botón derecho en Obtener información en su destino, seleccione Categoría de compilación y luego agregue sus rutas a través de la configuración "Rutas de búsqueda de encabezado". Las rutas se buscan en el orden en que las ingresas.

+0

¿Se puede hacer esto con el nuevo espacio de trabajo ahora? –

+1

Sí, ahora ejecuto Xcode 4.3.2 y no necesito cambiar nada. –

4

La mejor manera es crear un marco separado que contenga las clases compartidas. Esto se puede compilar una vez y vincular a ambos proyectos de aplicación.

Ver Apple's doc on what are Frameworks.

+2

En mi experiencia, los marcos solo son adecuados para el código que realmente ha bloqueado; donde no esperas cambios (Y, en realidad, eso nunca sucede. Las cosas siempre cambian.) Suenan bien en el papel, pero los marcos tienden a interponerse en mi camino, sofocan el desarrollo rápido y la innovación (porque no quieres ir y cambiar el marco, se rompe algo en otra aplicación) y generalmente son una mala opción para compartir código a menos que actualice sus bibliotecas una vez al año (por ejemplo, Apple). – Womble

+1

@Womble, no cambie nada que pueda romper algo en otra aplicación ...si desea hacer eso, marque el método anterior como obsoleto y escriba uno nuevo ... –

2

La solución más rápida es agregar solo referencias de los archivos .h y .m a uno de los proyectos. Simplemente desmarque la casilla "copiar" en el cuadro de diálogo "agregar archivos existentes" en xcode. Tenga en cuenta que también podría necesitar copiar los archivos a los que se hace referencia si mueve/comparte su proyecto.

+1

¿Funcionaría muy bien con el control de código fuente? Supongo que la solución de marcos funcionaría más naturalmente con CVS y amigos. – Spina

1

Encontré un buen artículo sobre este tema aquí: http://www.clintharris.net/2009/iphone-app-shared-libraries/ Respondió a mi pregunta, que es específicamente sobre múltiples aplicaciones de iPhone que comparten el código. No menciona los marcos (arriba) por lo que no puedo decir si su sugerencia (referencias del proyecto xcode) se compara favorablemente con la solución de marcos.

+0

La situación es muy diferente en el iPhone con su sistema de archivos y restricciones de biblioteca compartida. –

11

Una forma muy buena de hacerlo es colocar el código compartido en el sistema SCM e incluirlo en cada proyecto que desee. De esta forma, cada proyecto puede compartir el código, puede editarlo en cualquier lugar y simplemente verificar los cambios vuelva al control de la fuente cuando se sienta bien al respecto, y luego todos los otros proyectos se beneficiarán de su trabajo.

Esto tiene grandes ventajas sobre otras formas de hacer que la OMI:

vs marcos: Código de embalaje en un marco es bastante molesto, y el bundle-privada marcos tomar un tiempo excesivamente largo para cargar - especialmente justo para obtener algunas clases en tu aplicación. Wil Shipley de Omni Group (en ese momento) una vez descubrió que los marcos que la compañía incluía en todas sus aplicaciones estaban agregando varios segundos a la hora de inicio de cada aplicación. El empaquetado de clases privadas en un marco también puede alentar más acoplamiento de lo que es estrictamente necesario; es realmente tentador hacer One True Framework donde residen todas las clases compartidas, por lo que se puede asumir que este código siempre vivirá en conjunto. y se vuelve inseparable. Básicamente, los marcos son un martillo y este problema es un tornillo.

frente a solo incluir archivos: con suerte, usted pondrá su aplicación en un SCM en algún momento de todos modos, y simplemente incluir los archivos in situ crea un problema porque faltarán en SCM. Copiar los archivos en cada proyecto presenta el problema opuesto: cada proyecto incluirá su propia versión de los archivos y usted tendrá que propagar manualmente cualquier cambio útil.

+2

Hola Chuck, estoy considerando este enfoque, pero no estoy seguro de qué implica "incluirlo en cada proyecto que deseas". ¿Estás hablando de hacer algo en XCode o tal vez algo así como propiedades SVN externas? Qué quieres decir exactamente? Gracias. – Cal

+1

Gracias por la respuesta Chuck, este parece ser el camino a seguir. Sin embargo, soy casi un novato en este tema. ¿Tiene alguna fuente con una explicación/ejemplo más detallado? – Tom

+0

@chuck ¿Alguna posibilidad de encontrar un tutorial o escribir sobre lo que propone? –

2

Tuve un problema similar, y la respuesta aceptada anteriormente puede causar problemas para un novato.

Estará bien si los dos proyectos se comunican mediante algún protocolo, p. TCP/IP, o si no se comunican. Sin embargo, si un proyecto es un paquete (por ejemplo, un complemento) que necesita acceder a las mismas clases que una aplicación (mientras se ejecuta en el mismo proceso), tendrá problemas con enlaces o advertencias/errores de tiempo de ejecución para tener clases con el mismo nombre. La forma más simple de resolver este problema es usar un marco. Con un marco, puede configurarlo para que los tres objetivos estén en el mismo proyecto, o incluso puede incluir el marco en proyectos separados.

que tenían un proyecto con una aplicación y un plug-in paquete, aquí están los pasos que hemos seguido en Xcode 6:

  1. crear un marco, copiar todo el código compartido a través.
  2. En el encabezado principal del marco, incluya los encabezados de todo el código compartido.
  3. Construya el framework para probarlo (por ejemplo, seleccione el esquema del framework y haga clic en play)
  4. Vaya a la sección Build Fases tanto de la Aplicación como del Paquete de Complementos y agregue el nuevo framework a 'dependencias de destino' y 'binario Enlace con las bibliotecas'
  5. Para incluir la materia marcos de código en la aplicación y el paquete, sólo tiene que utilizar la cabecera principal, y utilizar <> en lugar de “" por ejemplo, si su marco se llama Foo utiliza import

Los cambios en el marco se compilarán automáticamente cuando ejecute la aplicación principal, por lo que puede ignorar el fac t son objetivos diferentes

Cuestiones relacionadas