从不同的目标获取 Bundle ID

25
在我的Xcode项目中,我有四个不同的方案(prod、dev、staging、staging2),这些方案会更改安装到手机上的应用程序的包标识符。这样我就可以同时安装所有四个版本,类似于这种技术
现在我正在为iOS 8构建一个Today Extension。它是一个新的目标,需要自己的包标识符。
扩展的包标识符必须以父应用程序的包标识符为前缀,否则会出现警告:
error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.

    Embedded Binary Bundle Identifier:  com.company.app.TodayExtension
    Parent App Bundle Identifier:       com.company.app.staging

在这种情况下,嵌入式二进制包标识符必须为com.company.app.staging.TodayExtension
我能否通过自定义的Run Script Build Phase来配置我的Today Extension目标,以便首先查看父目标的bundle identifier并设置其自己的bundle identifier呢?

1
你能详细解释一下你是如何解决这个问题的吗?在Jafar下面的答案中,你是否通过切换方案来设置了PARENT_APP_BUNDLE_IDENTIFIER,如果是,你是怎么做到的?或者在每个目标(包括扩展目标)中,你指定了什么样的bundle ids和PARENT_APP_BUNDLE_IDENTIFIER?谢谢! - qix
5
在项目设置 | 构建设置 | 用户定义 中,创建一个名为PARENT_APP_BUNDLE_ID的新条目。如果有4个配置,则为每个添加一个值(com.company.app.staging、com.company.app.development等)。在您的主应用程序目标的Info.plist中,将Bundle Identifier设置为$(PARENT_APP_BUNDLE_ID)。在您的扩展目标的Info.plist中,将其Bundle Identifier设置为$(PARENT_APP_BUNDLE_ID).NameOfYourExtension。 - djibouti33
2
啊哈,完全没有意识到你是通过额外的自定义构建配置(项目|信息|配置)来完成这个操作,并在项目级别为每个配置设置不同的PARENT_APP_BUNDLE_ID值,而不是认为你以某种方式通过覆盖单个目标设置来完成它。因此,您仍然可以切换方案以使用不同的捆绑标识进行构建,因为每个方案使用不同的构建配置集。很酷,对我有用,并帮助我清理重复的目标和plist文件! - qix
我快成功了!但是如何在项目级别为每个配置设置“不同的PARENT_APP_BUNDLE_ID值”? - Doug Mead
1
当您在项目级别的构建设置中添加PARENT_APP_BUNDLE_ID时,通过单击左侧的三角形,您应该可以看到所有配置。在我的应用程序中,我有4个配置(dev,prod,staging,staging2)。创建了该用户定义的构建设置后,我可以看到所有4个配置,并为每个配置分配不同的值。 - djibouti33
3
如果我的扩展嵌入到多个目标中怎么办? - Neil Galiaskarov
3个回答

33

目标的构建设置对其他目标不可用。但是项目的构建设置是可用的。

因此,您可以在项目中添加一个用户定义的构建设置,将其命名为PARENT_APP_BUNDLE_IDENTIFIER,并为所有方案设置正确的包标识符。

然后,在应用程序扩展目标的信息选项卡中将包标识符设置为

$(PARENT_APP_BUNDLE_IDENTIFIER).$(PRODUCT_NAME:rfc1034identifier)

对我来说完美无缺。


太棒了!这节省了我很多的挫败感! - djibouti33
1
我正在遇到相同的问题...我尝试了上述的解决方案,但没有成功。我已经升级到iOS 8.0.2和Xcode 6.0.1(官方版本)。之前我使用的是8.0,在那个版本中它可以正常工作。 - Sri
3
请澄清这部分内容:“为所有的方案设置正确的bundle id” - Mirko
@djibouti33,这真的解决了你的问题吗?在我看来,PARENT_APP_BUNDLE_IDENTIFIER将独立存在于你的扩展信息属性列表中,并从项目信息属性列表中获取默认值,这在使用不同方案时可能很有用,但如果你使用不同的应用程序目标,它仍然无法解决问题,对吧? - Kushal Ashok
2
对我没用。$(PRODUCT_BUNDLE_IDENTIFIER)由项目定义,每个目标可以设置和读取其值。在您的应用程序扩展中,您读取变量,获取并设置自身。这没有意义。 - DawnSong
1
Alexis,针对@Mirko和其他人提出的问题进行跟进,这是否解决了当您有不同目标时的问题?我肯定可以为每个配置设置不同的bundleID,但如果我有3个目标,那我怎么知道哪个目标被选中了呢?您能否在您的回答中澄清这一点或者可能添加屏幕截图? - mfaani

6

我有Siri扩展和多个目标,为了避免为每个目标重复扩展,我在每个方案中添加了Pre-action,在构建之前更改扩展的plist文件的BundleId:

  1. 选择“编辑方案”
  2. 点击“Build”旁边的三角形
  3. 选择“Pre-actions”
  4. 点击“+”,选择“New Run Script Action”
  5. 选择要提供构建设置的目标
  6. 在脚本字段中粘贴以下内容,并更换您的BundleId和扩展文件夹
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier 
YourDesiredBundleId" "$PROJECT_DIR/YourExtensionFolder/Info.plist"

它像魔法一样工作!你需要为每个方案进行配置。


对于我而言,$PROJECT_DIR 不是正确的目录。我必须使用 BUILT_PRODUCTS_DIR 或者 BUILD_DIR - mfaani
非常感谢,现在有成千上万的扩展程序,非常有帮助。 - Perjan Duro
我们需要将上述脚本添加到应用程序目标方案或扩展方案中吗?我有5个应用程序目标,想要使用一个服务扩展。那么,我应该在哪里添加这些运行脚本呢? - Kirti Nikam
@KirtiNikam 应用程序目标方案 - Mike Makhovyk

3

在我的项目中,我需要构建不同版本的应用程序(在细节上有所不同,例如每个应用程序都带有不同的徽标)。

假设有大约10个“应用”目标,我无法想象为每个主目标添加通知内容和通知服务扩展(在这种情况下,我总共将维护30个目标 - 疯狂)。

我在“嵌入应用程序扩展”阶段之后运行一个脚本(https://gist.github.com/damian-rzeszot/0b23ad87e5ab5d52aa15c095cbf43c59),它覆盖应用程序扩展清单中的捆绑标识并重新签名捆绑包。


2
你是否将所有这些脚本复制并放入新的“Build Phases”中的“Run Script”中? - Dmitriy Greh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接