Post

iOS 单个项目中开发多个 APP,复用组件和第三方库

iOS 单个项目中开发多个 APP,复用组件和第三方库

在 iOS 开发中,有时需要在 同一个项目 中开发多个 APP(例如主应用 + 轻量版 + 定制版)。这些 APP 可能有 相同的核心代码,但在 UI、功能或配置 上有所不同。下面在项目中 在一个 Xcode 项目中开发 3 个 APP,同时 复用组件和第三方库,提高开发效率并减少冗余代码。

一、使用 Xcode Target 实现多个 APP

在 Xcode 中,每个 APP 都是一个 Target,多个 Target 共享代码,但可以有不同的:

  • App Icon & Launch Screen
  • Bundle Identifier
  • Info.plist 配置
  • 编译宏(Preprocessor Macros)
  • 资源文件(Assets)
  • URL Scheme & 权限(Entitlements)

1. 创建多个 Target

  1. 打开 Xcode,选择项目,在左侧 Project Navigator 里点击 TARGETS 旁边的 + 号,选择 iOS → Application → Single View App

  2. 输入 Target 名称(例如 AppAAppBAppC)。

  3. 配置 Target 的 Info.plist,每个 Target 需要单独的 Info.plist 文件(可以复制主 APP 的 Info.plist 并重命名)。

  4. 调整 Bundle Identifier

    ,确保每个 APP 的

    1
    
    Bundle ID
    

    唯一,例如:

    • com.example.appA
    • com.example.appB
    • com.example.appC
  5. 设置不同的 App 图标:

    • Assets.xcassets 中为每个 Target 添加不同的 AppIcon 资源。
    • Info.plist 中关联不同的 AppIcon

二、复用代码和 UI 组件

多个 APP 可能有 相同的业务逻辑,但 UI 或部分功能不同,可以通过 共享代码编译条件 复用组件。

1. 代码共享:使用 Shared 文件夹

创建一个 Shared 目录,把 所有公共代码、UI 组件、工具类、网络请求封装 等放入 Shared,然后:

  • 每个 Target 的 Build PhasesCompile Sources 中,确保 Shared 目录下的代码 被所有 Target 共享

  • 例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    Project/
    ├── AppA/
    │   ├── ViewControllers/
    │   ├── Resources/
    ├── AppB/
    │   ├── ViewControllers/
    │   ├── Resources/
    ├── Shared/
    │   ├── Networking/
    │   ├── Models/
    │   ├── Utilities/
    │   ├── UIComponents/
    

2. 使用 #ifdef 进行条件编译

如果不同的 APP 逻辑不同,可以用 宏定义(Preprocessor Macros) 区分:

  1. 在 Xcode 中

    • 进入 Build SettingsPreprocessor Macros
    • 为每个 Target 添加不同的宏定义:
      • APP_A
      • APP_B
      • APP_C
  2. 在代码中使用 #ifdef

    1
    2
    3
    4
    5
    6
    7
    
    #ifdef APP_A
    NSLog(@"App A 的特定代码");
    #elif defined(APP_B)
    NSLog(@"App B 的特定代码");
    #else
    NSLog(@"默认 App 代码");
    #endif
    

三、共享第三方库(CocoaPods)

多个 Target 共享 相同的第三方库(如 AFNetworkingSDWebImage)可以通过 CocoaPods 实现:

1. 编辑 Podfile

Podfile 里为多个 Target 共享 Pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
target 'AppA' do
  pod 'AFNetworking'
  pod 'SDWebImage'
end

target 'AppB' do
  pod 'AFNetworking'
  pod 'SDWebImage'
end

target 'AppC' do
  pod 'AFNetworking'
  pod 'SDWebImage'
end

如果所有 Target 都用相同的库,可以用 abstract_target 共享:

1
2
3
4
5
6
7
8
abstract_target 'CommonPods' do
  pod 'AFNetworking'
  pod 'SDWebImage'

  target 'AppA'
  target 'AppB'
  target 'AppC'
end

然后执行:

1
pod install

四、管理不同的配置(不同环境 / API)

多个 APP 可能使用 不同的服务器地址不同的用户权限,可以使用 配置文件或编译环境变量 来区分。

1. 使用不同的 xcconfig

Configurations 里为 AppAAppBAppC 创建不同的 xcconfig

1
2
CONFIGURATION_BUILD_DIR = $(SRCROOT)/Build/$(CONFIGURATION)/$(PRODUCT_NAME)
API_BASE_URL = "https://api.example.com"

然后在代码中读取:

1
NSString *baseURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"API_BASE_URL"];

2. 运行时读取不同的 plist 配置

创建多个 Config.plist,每个 Target 使用不同的 Config.plist

1
2
3
NSString *configPath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *config = [NSDictionary dictionaryWithContentsOfFile:configPath];
NSString *apiURL = config[@"APIBaseURL"];

五、不同 Target 使用不同资源

1. 在 Xcode 资源管理器中区分资源

Assets.xcassets 里创建 AppA_AssetsAppB_Assets,然后在 Build Phases 里调整资源:

  • AppA 只包含 AppA_Assets
  • AppB 只包含 AppB_Assets

2. 代码动态加载资源

1
UIImage *image = [UIImage imageNamed:@"custom_icon"];

Xcode 会根据 Target 选择正确的资源。

This post is licensed under CC BY 4.0 by the author.