Managing Large iOS Projects

本文概述了如何在大型iOS项目中保持生产力的一系列步骤与技巧,包括组织项目文件、使用工作区与子项目、遵循OOD原则、处理非代码资产等。文章详细解释了如何解决Xcode项目文件的冲突问题,以及如何有效组织静态库、资源包和代码规范,最终提供了一种快速测试内容的方法,以提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

少见的写管理的,来自http://benedictcohen.co.uk/blog/archives/258 24 January 2012Managing Large iOS Projects

I recently worked on a relatively large iPad app. Although this was a relatively small team, there was still potential for us to stand on each others toes. This post is a collection of rough notes and tips that describes the steps we took to stay productive. If you’d like more details on anything please get in touch.

Background

Let me explain what I mean by ‘large’. The app was ‘large’ due to the size and number of content files. The app was rather modest in terms of lines of code. There was a maximum of 3 people (2 developers and 1 designer) working directly with the main project or sub-projects at any time. Although this is a small team it’s still large enough to cause problems. In fact any project with more than one person has the potential for these work flow problems to occur.

Beware the Xcode project files

I’m going to start with a rant. I get the impression that the Xcode project format was not built with multiple users in mind. An Xcode project is a bundle that contains files for user specific settings (break points, Xcode window layout etc) and 1 monolithic file,project.pbxproj, that references all the files in the project and build settings etc. project.pbxproj is a JSON-like format which and is not meant to be edited by humans and it does not play well with auto-merging algorithms used by source control. The upshot of this is that this file often becomes the victim of painful source control conflicts when there’s more than 1 person working on a project. Such conflicts are hard to resolve because unlike changes to actual source files the changes to project.pbxproj are performed implicitly by Xcode rather than directly by the user. Yes, these problems can be mitigated with meticulous use of source control, but having to do so feels like the user is supporting the tools instead of the tools supporting the user. (A possible solution would be to take advantage of the fact that the project is a bundle and split project.pbxproj into multiple files; a file for the group structure, files for the build settings for individual files, files for target settings etc. This would make also it easier to see what’s changed when using source control.)

Due to the horribleness of the Xcode project it pays to organise your project so that the number of people working on an individual project file is kept to a minimum.

Workspaces and sub-projects

In Xcode 3 it was possible for a project to contain a reference to other projects; this is achieved in the same way as adding an existing file to the project. I refer to these as sub-projects (I think the proper name is ‘external project reference’). Xcode 4 introduced improvements for working with multiple projects. Apple attributes the improvements to a new featured called Workspaces. Workspaces allow multiple top-level projects in the Xcode organizer. However, the improvements attributed to workspaces also apply to sub-projects. The difference between workspaces and sub-projects is that a project can incorporate targets from sub-projects into its build process, but a sub-project cannot incorporate targets from it’s ‘parent’ project while projects in a workspace can all incorporate each others targets.

Breaking a project down into multiple projects reduces the number of people working on any given project. Use the 6 Principles of OOD relating to packages to help decide what each sub-project should contain.

Gotcha: Beware the ‘install phase’

The ‘Skip install’ build setting causes problems when archiving an app. With the exception of the main target all targets must have ‘Skip install’ set YES (even if the product of the target is not included in the main product). The default value is NO.

Code in sub-projects (static libraries)

Static libraries allow code to be moved into sub-projects. I’m not going to describe how to create static libraries because others have done so already. Using Open Source Static Libraries in Xcode 4 tells you (almost) everything you need to know. However, there are a few extra things I’d add:

  • Start with a standard iOS app and add a static library target to it. Having an app to play around with makes it easier to develop.
  • Gotcha: By default categories implemented in static libraries are not linked. To remedy this add the -all_load linker flag to the main project. Technical Q&A QA1490.

Non-code assets for static libraries

There are occasions when static libraries require assets, e.g., images and sound files. Sub-projects and projects in the same workspace share a build directory and Xcode manages the build order of each project so that the main target is always built last. Because of this we can add build phases to our main project and sub-project which copy static library assets into the main bundle:

  1. In the sub-project target add a ‘Copy Files’ build phase. Set the Destination to ‘Products Directory’ and the subpath toMainBundleAssets. Add the assets to this build phase.
  2. In the main target add a ‘Run Script’ build phase:
    cp -rf "${BUILT_PRODUCTS_DIR}/MainBundleAssets/"* "$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH/"
    This will copy the files from MainBundleAssets into the main bundle.

Resource Bundle sub-projects

Bundles allow arbitrary resources to grouped together and treated as one entity. They’re used for many purposes in Mac OS X and iOS. Many OS X apps store documents as bundles; the document bundle is effectively a bunch of assets and the app the tool for working with those assets. It’s useful to make this same distinction for an iOS app. Design the app so that it loads a resource bundle. It’s an example of designing to an abstraction rather than the specifics.

Some general tips for how to organise and handle a large quantity of assets:

  • Use a naming convention so that each asset can be identified at runtime.
  • When in development ensure that there are no missing assets by crashing early and often.
  • Maintain a sane directory structure and don’t rely on Xcode groups (moving a file from a group doesn’t move it on the disk – this can result in things getting messy).
  • It’s worth remembering that nib files can be used to instantiate arbitrary objects.
  • Gotchas: Beware duplicate file names. It’s possible to have 2 files with identical names but in different directories. But when the bundle is built all files are copied into one folder. This results in 1 of the files being copied over.

Improve performance by moving run time operations to compile time

To improve performance move expensive operations from run time to build time and cache the result. This can be achieved by creating an OS X ‘Command Line Tool’ target that runs as part of the bundles build process. Core Data can be used to store the data created at build time (Core Data is cross platform so a Core Data store that is created on OS X can be read by iOS).

Build tools that allow content to be tested quickly

The best way to test content is to see it in place within the app. However, compiling an app takes time which means that viewing the content in place can be slow. What’s needed is a quick way to test the content without compiling the whole app. One solution is to create a testing app based on the main app. Add features to the testing app that aren’t required in the final app (e.g. re-loading the resource bundle at run time and provided onscreen info that’s useful to the designer). Tips for creating a testing app:

  • Create the testing app by duplicating the app target and give it a distinct name (e.g. ‘ContentTester’).
  • Add categories and method swizzling to key classes (app delegate, view controllers etc) to augment functionality. Add these in separate source files so that the main app stays free of any changes.
  • Add a mechanism for loading content at runtime (e.g. responding to the shake gesture, which is easy to trigger in the simulator).
  • Add macros to ensure that this code never gets compiled into the final build.
  • Restrict the test app to the iOS simulator.
  • Load the content from a place on the local system (e.g. /tmp) so that the content can be reloaded without rebuilding the app.
  • Use symlinks to avoid having to copy files

代码规范的知识
http://blog.youkuaiyun.com/shlei2002/article/details/6576779
GNU Make 是一个广泛使用的项目管理工具,它可以帮助我们自动化构建和管理项目。它的核心思想是基于规则来定义项目的构建过程。 首先,我们需要在项目的根目录中创建一个名为“Makefile”的文件,用于定义项目的规则和依赖关系。Makefile 是用来告诉 GNU Make 如何构建和更新项目的文件,它由一系列规则组成。 每个规则由一个目标(target)和相应的依赖列表组成。目标是指我们希望生成的文件或执行的操作,而依赖列表则表示生成目标所需要的文件或操作。当某个目标的依赖发生变化时,GNU Make 将会自动检测并更新相应的目标。 在 Makefile 中,我们可以使用一些预定义的变量来简化配置,如 CC 表示编译器,CFLAGS 表示编译选项等。我们还可以定义自己的变量,以便在规则中使用。 通过定义规则和依赖关系,我们可以利用 GNU Make 来自动构建项目。当我们运行 make 命令时,GNU Make 将会读取 Makefile,并根据规则和依赖关系来判断哪些目标需要重新构建,然后执行相应的命令。 GNU Make 还支持一些高级特性,如条件判断、循环、递归等,这使得我们可以根据不同的情况来定义不同的规则和行为。 总之,GNU Make 是一个强大而灵活的项目管理工具,它允许我们根据项目的需求来定义规则和依赖关系,并自动化构建过程,提高项目的开发效率和可维护性。无论是小型项目还是大型项目,GNU Make 都是一个极为有用的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值