Xcode 没有将最新的资源文件复制到 iPhone

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4718677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:39:44  来源:igfitidea点击:

Xcode not copying latest resource file to iPhone

iphonexcode

提问by whatupdave

I'm writing an iPhone app in Objective-C with Xcode and I have some Lua scripts that run on the device.

我正在用 Xcode 用 Objective-C 编写一个 iPhone 应用程序,我有一些在设备上运行的 Lua 脚本。

I'm having an issue where if I edit a Lua script, save, flick over to Xcode and Build and Run (?Y) the latest version of that Lua script is copied into the app bundle but not copied to the device.

我遇到了一个问题,如果我编辑 Lua 脚本,保存,轻弹到 Xcode 和 Build and Run (?Y),该 Lua 脚本的最新版本会被复制到应用程序包中,但不会复制到设备中。

The scripts aren't in the Xcode project, I edit them in Textmate. I have a build step which copies the scripts into the app bundle and touches the files, this is being run fine and the latest script version is in the app bundle when I run the app. The files have all been touched, but for some reason when copying the bundle to the device Xcode decides not to copy the latest.

脚本不在 Xcode 项目中,我在 Textmate 中编辑它们。我有一个构建步骤,它将脚本复制到应用程序包中并接触文件,这运行良好,当我运行应用程序时,最新的脚本版本在应用程序包中。这些文件都已被触及,但出于某种原因,当将捆绑包复制到设备时,Xcode 决定不复制最新的。

If I stop the app and then Build and Run (?Y) again, the latest version is copied across.

如果我停止应用程序,然后再次构建并运行 (?Y),则会复制最新版本。

My workaround is to save the Lua file, then in Xcode do a Build (?B) and then Build and Run (?Y), so build the app twice. This always seems to copy the latest version to the device.

我的解决方法是保存 Lua 文件,然后在 Xcode 中执行 Build (?B) 和 Build and Run (?Y),因此构建应用程序两次。这似乎总是将最新版本复制到设备。

Update:

更新:

As many have noted, one solution is to clean the targets and rebuild. You cando this, you could also build twice as I have noted above. This problem is easily reproducible (in my setup it happens every time, regardless of how recently the targets were cleaned). I'm hoping for a more reliable/permanent solution

正如许多人所指出的,一种解决方案是清理目标并重建。你可以这样做,你也可以像我上面提到的那样构建两次。这个问题很容易重现(在我的设置中,它每次都会发生,无论目标最近多久被清理过)。我希望有一个更可靠/永久的解决方案

采纳答案by Kenny Wyland

You should definitely add those files to your XCode project. You can still edit them in your other editor, but XCode will include them in your bundle automatically if you add it to the project. If they aren't getting copied when you build, this is how I resolve it:

您绝对应该将这些文件添加到您的 XCode 项目中。您仍然可以在其他编辑器中编辑它们,但如果您将其添加到项目中,XCode 会自动将它们包含在您的包中。如果构建时它们没有被复制,我就是这样解决的:

  • Right click on the file in XCode and choose "Touch" which updates the timedate stamp on the file, so it looks "new".

  • On the simulator, choose Reset Content and Settings from the File Menu.

  • In XCode, do a Build Clean

  • 右键单击 XCode 中的文件并选择“Touch”,它会更新文件上的时间戳,因此它看起来是“新的”。

  • 在模拟器上,从文件菜单中选择重置内容和设置。

  • 在 XCode 中,执行 Build Clean

When you build and run after that it should install the file just fine.

当您构建并运行之后,它应该可以很好地安装文件。

EDIT:

编辑:

To add external folders to your project that will get included in your bundle and preserve the folder structure intact, all you need to do is:

要将外部文件夹添加到您的项目中,这些文件夹将包含在您的包中并保持文件夹结构完整无缺,您需要做的就是:

  • Click on the project icon at the top of the file list on the left.

  • Click the Project menu and Add to Project.

  • Select the folder you want to include and click Add.

  • Unchecked the Copy checkbox and change "Recursively create groups for any added folders" to "Create Folder References for any added folders".

  • When the target is built, open up the bundle and your directory structure will exist inside fully intact.

  • 单击左侧文件列表顶部的项目图标。

  • 单击项目菜单并添加到项目。

  • 选择要包含的文件夹,然后单击添加。

  • 取消选中复制复选框并将“为任何添加的文件夹递归创建组”更改为“为任何添加的文件夹创建文件夹引用”。

  • 构建目标后,打开包,您的目录结构将完整地存在于其中。

回答by Mark

First of all: I feel your pain. I haven't found any good documentation on rolling up your sleeves and digging into the iOS build pipeline if you want to do some interesting (or even just simple) data pipelining using custom scripts.

首先:我感觉到你的痛苦。如果您想使用自定义脚本进行一些有趣的(甚至只是简单的)数据流水线操作,我还没有找到任何关于卷起袖子并深入研究 iOS 构建流水线的好的文档。

Second of all: I don't agree that you need to, or even shouldput all your assets in your xcode project. That's really a matter of personal preference, and if you've got a complicated enough project, XCode becomes a beast to navigate your code alone as it is, let alone with all your art assets and data files.

其次:我不同意你需要,甚至不应该把你的所有资产放在你的 xcode 项目中。这真的是个人喜好的问题,如果您有一个足够复杂的项目,XCode 会变成一个野兽,可以单独浏览您的代码,更不用说您所有的艺术资产和数据文件了。

Third: Cleaning is a work-around, as is touching an individual source-code file (XCode will pick up on this and do the signing/touching of the master directory for you without the need to do a clean build -- a clean build is extremelytime consuming if you have a large project or significant assets), but these are really just hacks to get the thing to work without fixing the underlying problem: you need to hit the right dependency to get the copy step to kick in.

第三:清理是一种变通方法,就像触摸单个源代码文件一样(XCode 将接受此操作并为您执行主目录的签名/触摸,而无需进行干净的构建——干净的构建如果您有一个大型项目或重要资产,则非常耗时),但这些实际上只是在不解决潜在问题的情况下使事情正常工作的技巧:您需要找到正确的依赖项才能启动复制步骤。

I had the same issues you're describing here with the following differences: I'm using a gnu make script to process art resources (audio, data files, images) by doing some basic manipulations (compression, stripping out un-needed things, building fonts, etc). I'm using gnu make because 1.) I know it 2.) I find it easier to put all my rules into one script 3.) I like to keep my data folder nice and heirarchical and 4.) XCode isn't always the way you want to interface/organize/manage all your data! (though I think it does a great job for code and even small amounts of data in a less complex project)

我遇到了您在此处描述的相同问题,但有以下区别:我正在使用 gnu make 脚本通过执行一些基本操作(压缩、去除不需要的东西)来处理艺术资源(音频、数据文件、图像),构建字体等)。我使用 gnu make 是因为 1.) 我知道它 2.) 我发现将我的所有规则放在一个脚本中更容易 3.) 我喜欢让我的数据文件夹保持良好和层次结构 4.) XCode 并不总是您想要的界面/组织/管理所有数据的方式!(虽然我认为它在代码和不太复杂的项目中甚至少量数据方面做得很好)

Anyhow, what I found is that I really had 2 problems: 1.) Code signing and 2.) Copying. The copying is easy, all you need to do is touch the build products folder. In my case I added the following to my make file: "touch $(DIR_CONTENTS)" where I defined "$(DIR_CONTENTS)" using the existing env parms provided by xcode to the shell when my xcode is executed: "DIR_CONTENTS = $(BUILT_PRODUCTS_DIR)/$(CONTENTS_FOLDER_PATH)" (you can see the full list of env parms if you click on the 3 horizontal lines in the output log). In your case you'd need to do the equivalent in your lua script. Not sure what that entails, I've been purposely dodging lua for years, but I can't imagine it's too crazy.

无论如何,我发现我确实有两个问题:1.) 代码签名和 2.) 复制。复制很容易,您需要做的就是触摸构建产品文件夹。在我的例子中,我在我的 make 文件中添加了以下内容:“touch $(DIR_CONTENTS)”,其中我使用 xcode 提供给 shell 的现有环境参数定义了“$(DIR_CONTENTS)”,当我的 xcode 执行时:“DIR_CONTENTS = $( BUILT_PRODUCTS_DIR)/$(CONTENTS_FOLDER_PATH)"(如果单击输出日志中的 3 条水平线,您可以看到 env 参数的完整列表)。在您的情况下,您需要在 lua 脚本中执行等效操作。不知道这意味着什么,多年来我一直在故意避开 lua,但我无法想象它太疯狂了。

The next bit is trickier, 'cuz what I found was that just because you've updated, doesn't mean that the code signing stuff works nicely. In my case I needed to add a ResourceRules.plist file and add my art directory (art/.*) as a dictionary, with a line to omit and a weight. I couldn't find docs on this anywhere, so I copied the ResourceRules.plist file from the generated folder into my source folder, added it to the project, and then pointed the code signing stuff at it. (This would be in the build rules under Code Signing: it'll be your "Code Signing Resource Rules Path")

下一点更棘手,因为我发现仅仅因为你已经更新,并不意味着代码签名的东西很好用。就我而言,我需要添加一个 ResourceRules.plist 文件并将我的艺术目录 (art/.*) 添加为字典,其中包含要省略的行和权重。我在任何地方都找不到这方面的文档,所以我将 ResourceRules.plist 文件从生成的文件夹复制到我的源文件夹中,将其添加到项目中,然后将代码签名内容指向它。(这将在代码签名下的构建规则中:它将是您的“代码签名资源规则路径”)

This isn't really my ideal solution, btw. I would rather be able to trigger the code-signing step via my script if my data changes, but as I stated earlier I haven't found any useful docs in apple's developer library on how to really dig into the custom builds. You cando the code signing by hand, but I didn't like it.

顺便说一句,这并不是我理想的解决方案。如果我的数据发生变化,我宁愿能够通过我的脚本触发代码签名步骤,但正如我之前所说,我没有在苹果的开发人员库中找到任何关于如何真正挖掘自定义构建的有用文档。您可以手动进行代码签名,但我不喜欢它。

Hope that helps.

希望有帮助。

UPDATE:

更新:

I figured I'd add some example code.... here are some relevent excerpts from my makefile:

我想我会添加一些示例代码......这里是我的makefile中的一些相关摘录:

# Near the beginning, where I do my variables n' such, I define the 
# directory in a variable. Note that BUILD_PRODUCTS_DIR and CONTENTS_FOLDER_PATH
# are environment variables set by XCode and will be filled with the corresponding
# paths
DIR_CONTENTS     = $(BUILT_PRODUCTS_DIR)/$(CONTENTS_FOLDER_PATH)
DIR_DEST_ART     = $(DIR_CONTENTS)/art
DIR_DEST_FONTS   = $(DIR_DEST_ART)/fonts
# ... more folders defined here...
DIR_SRC_FONTS    = $(SRCROOT)/source-art/fonts
# ... more folders defined here...

# ... do some useful build stuff ...

# This is an example of my rule that takes the .png's built by my font script
# and compresses them to .pvrs (note: this isn't final, so YMMV). The thing to
# note here is that if this rule kicks off, the last thing that will happen is
# that I will touch my DIR_CONTENTS folder, which will kick off the copy to the
# device. I find having to touch the folder really annoying, I prefer the way xcopy 
# and similar copy methods recursively travel & update if required.
$(DIR_DEST_FONTS)/%.pvr : $(DIR_SRC_FONTS)/%.png
    @echo == Compress $(subst $(SRCROOT),src,$<) to $(subst $(DIR_DEST_ART),dest,$@) ===
    @mkdir -p $(dir $@)
    @xcrun -sdk iphoneos texturetool -e PVRTC -o $@ -f PVR $<
    @touch $(DIR_CONTENTS)

Then, in order to deal with the code signing problem, I edited my ResourceRules.plist to look like the below. The area to pay attention to is the key that starts with "art/.*"

然后,为了处理代码签名问题,我将 ResourceRules.plist 编辑为如下所示。需要注意的区域是“art/.*”开头的key

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>rules</key>
<dict>
    <key>.*</key>
    <true/>
    <key>art/.*</key>
    <dict>
        <key>omit</key>
        <true/>
        <key>weight</key>
        <integer>0</integer>
    </dict>
    <key>Info.plist</key>
    <dict>
        <key>omit</key>
        <true/>
        <key>weight</key>
        <real>10</real>
    </dict>
    <key>ResourceRules.plist</key>
    <dict>
        <key>omit</key>
        <true/>
        <key>weight</key>
        <real>100</real>
    </dict>
</dict>
</dict>
</plist>

回答by aussiegeek

For reasons I am yet to understand, sometimes the build process seems to get forgetful or simply unreliable.

出于我尚未理解的原因,有时构建过程似乎变得健忘或根本不可靠。

Usual troubleshooting for this type of scenario is to clean all in XCode, and at the same time delete the app from the phone

此类场景的常见故障排除是在 XCode 中清除所有内容,同时从手机中删除应用程序

回答by Nas Banov

Sounds like you have an "one-off" kind of a problem, in which your updated scripts make it "too late" to the bundle. Have you tried changing the order of the build phases, in particular moving the copy phase not to be at the end but before the compile and link phases?

听起来你有一个“一次性”的问题,你更新的脚本使它“为时已晚”。您是否尝试过更改构建阶段的顺序,特别是将复制阶段移到编译和链接阶段之前而不是最后?

回答by ThomasW

Why are the scripts not in the Xcode project? They can still be in the project while you use Textmate to edit them. Perhaps including them in the Xcode project will make it more likely that they get transferred to the device?

为什么脚本不在 Xcode 项目中?当您使用 Textmate 编辑它们时,它们仍然可以在项目中。也许将它们包含在 Xcode 项目中会使它们更有可能被转移到设备上?

回答by jfalexvijay

Just clean all target in xcode. And restart the xcode.
Then try to install in the device. It will work.

只需清理 xcode 中的所有目标。并重新启动xcode。
然后尝试安装在设备中。它会起作用。

回答by sum

I work on this in device build when resource updated:

当资源更新时,我在设备构建中处理此问题:

  1. In XCode, Right Click your .app file in Products Group
  2. Choose 'Show in Finder'
  3. Clean the files that where .app file located
  4. Run again
  1. 在 XCode 中,右键单击 Products Group 中的 .app 文件
  2. 选择“在 Finder 中显示”
  3. 清理 .app 文件所在的文件
  4. 再次运行

this works fine for me on device building that won't cost much time.

这对我来说在设备构建上很好用,不会花费太多时间。

回答by Warren Stringer

I had a similar problem auto-copying a script file, when changed. Had set its Type to "C" to allow for auto syntax highlighting. Had added the file to "Build Phases / Copy Bundle Resources". But no luck; changes to the file would not update the bundle.

我在自动复制脚本文件时遇到了类似的问题。已将其类型设置为“C”以允许自动语法突出显示。已将该文件添加到“构建阶段/复制捆绑资源”。但没有运气;对文件的更改不会更新包。

The fix, in this case, was to change the Type from "C" to "JSON". Now, it updates the bundle automatically on the device. Makes sense, since source files are rarely needed for a binary. Originally, Apple didn't allow any scripting.

在这种情况下,修复方法是将类型从“C”更改为“JSON”。现在,它会在设备上自动更新捆绑包。有道理,因为二进制文件很少需要源文件。最初,Apple 不允许任何脚本编写。

enter image description here

在此处输入图片说明

回答by Purj0001

I see this problem once in a while with a sqlite database that I have included in my project. Sometimes it just doesn't get the updated version.

我偶尔会在我的项目中包含的一个 sqlite 数据库中看到这个问题。有时它只是没有得到更新的版本。

Typically my fix for this is to go into the Application Support/iPhone Simulator folder and delete the app inside the Application folder and also delete the Caches folder.
This will force the Simulator to reconstruct all of this and get fresh files.

通常,我对此的解决方法是进入 Application Support/iPhone Simulator 文件夹并删除 Application 文件夹中的应用程序,同时删除 Caches 文件夹。
这将强制模拟器重建所有这些并获取新文件。

回答by Akshay

Use Trouble Shooting

使用故障排除

Clean the XCode Projects

清理 XCode 项目

Build and Run

构建和运行