具有多个目标的iOS扩展

Enz*_*ran 36 duplicates target ios ios8 ios-app-extension

在iOS 8中,当我们创建一个新的扩展时,我们必须决定它附加到哪个目标.扩展名将具有与目标相同的捆绑包ID前缀.

  1. 之后有什么方法可以改变目标吗?
  2. 如果我的项目包含2个(或更多)目标(例如一个用于调试/模拟器,一个用于生产/设备),那么使用扩展的最佳方法是什么?我是否需要创建另一个扩展并复制代码(为两个目标保留相同的代码非常麻烦)?

mal*_*lex 28

要在很多目标中共享一个窗口小部件,应该只Embedded BinariesGeneral配置选项卡中为每个父目标添加widget.appex目标

在此输入图像描述

然后你会自动获得Embed App Extensions区域Build Phases

在此输入图像描述

  • 它显示错误:"嵌入式二进制文件的包标识符不以父应用程序的包标识符为前缀",因为我的两个目标都有不同的bundle-id,所以为了广告扩展,我需要给出扩展名的bundle-id,它将以(或者前缀为)target的bundle-id.因此无法为多个目标添加相同的notificaiton-service-extension.有什么解决方案吗? (11认同)
  • @Ankush,请参见apparition47的答案-很好地解决了“嵌入式二进制文件的包标识符不以父应用程序的包标识符为前缀”的问题。 (3认同)

小智 14

这是我的设置:我有3个目标(生产,登台,本地)和扩展目标,我不想重复3次.

只是为了澄清Neo Chen的答案,编辑你的每个父目标的方案:

构建>预执行>新运行脚本操作>从(父方案)提供构建设置.

粘贴每个扩展名:

#!/bin/bash

buildID=${PRODUCT_BUNDLE_IDENTIFIER}
extId="notification-service"

/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $buildID.$extId" "${SRCROOT}/${extId}/Info.plist"
Run Code Online (Sandbox Code Playgroud)

似乎在第一次构建时工作.

  • 该解决方案完美运行,只需一个通知服务扩展即可使用不同的目标。该脚本需要添加到特定 app-target 中的 pre-actions 中。确保在 pre-actions 选项卡中的下拉“provide build settings for:”中选择您的目标,否则将不会执行。 (4认同)
  • 我有多个目标、不同的帐户和开发团队。该扩展需要代码签名。我如何才能实现代码签名与我的父目标相同。我已经用 xcconfig 文件尝试过。但我无法弄清楚如何为我的扩展正确设置 DEVELOPMENT_TEAM。任何想法? (4认同)
  • 在本地运行效果良好。但是,当我尝试将每个目标的存档版本上传到 App Store 时,我收到[与此类似的错误](/sf/ask/1967475401/ -invalid-code-signing-entitlements) 对于两个目标之一。有人知道如何解决这个问题吗?@Erumaru 这和你遇到的问题是一样的吗?您找到解决方案了吗? (3认同)
  • 我得到:`设置:条目,“:CFBundleIdentifier”,不存在`。有任何想法吗? (3认同)
  • 如果扩展程序的plist的路径与扩展程序的捆绑软件ID不匹配,则可能需要编辑脚本。 (2认同)

leo*_*aka 10

看起来您应该只能使用自己的Info.plist复制Extension目标,但不能复制任何其他内容.

但是,当您创建扩展时,Xcode会将"嵌入应用程序扩展"添加到应用程序目标的构建阶段,如下所示,并且还没有UI可以执行此操作.

在此输入图像描述

仍然,您可以为第二个目标创建扩展,然后删除除.plist之外的所有文件,并修复需要修复的内容.这是一步一步:

  • 为"目标1"创建"扩展1"
  • 为"目标2"创建"扩展2"
  • 删除为"Extension 2"创建的所有文件,但Info.plist除外
  • 使"Extension 2"目标的"Build Phases"与"Extension 1"的构建阶段相同.通常,这会将必要的.m文件添加到"编译源"阶段,并将资源添加到"复制捆绑资源"阶段

  • "嵌入式应用程序扩展"构建阶段只是一个带有自定义名称的标准"复制文件"阶段.您可以轻松地自行添加,并将extension.appex目标放在插件中.如果您愿意,也可以更改构建阶段的名称. (4认同)
  • 成功了,谢谢。但是如果我们有 10 个以上的目标就不好了,所以我们必须为每个目标创建 10 个以上的小部件:( (2认同)

小智 6

我已经创建了一个运行脚本来支持此要求

#!/bin/sh
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${SRCROOT}/ImagePush/Info.plist"

buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $buildVersion" "${SRCROOT}/ImagePush/Info.plist"

buildID=${PRODUCT_BUNDLE_IDENTIFIER}
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $buildID.ImagePush" "${SRCROOT}/ImagePush/Info.plist"
Run Code Online (Sandbox Code Playgroud)

ImagePush是我的扩展

添加到您需要的目标并添加,确保此脚本在构建阶段中的扩展设置之前运行,然后您只需执行两次构建操作(PS:第一次失败,将尝试改进),它将支持多个目标


Dam*_*zot 5

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

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

“嵌入应用程序扩展”阶段运行一个脚本(https://gist.github.com/damian-rzeszot/0b23ad87e5ab5d52aa15c095cbf43c59),它覆盖应用程序扩展 plists 和权利、应用程序版本中的包 ID,更改配置文件并重新签署捆绑。


Aug*_*ard 1

您需要为每个 ID 创建多个扩展,但您可以创建动态框架并将其与每个扩展链接。那么您将不需要重复您的代码。