I have a question regarding Xcode and bundle resource copy.
I'm currently working on a project with a large asset library. So, a clean install, or a change in a bundle resource warrants a copy of the "new" bundle resource(s).
However, the problem that I'm currently facing is that Xcode is copying a part of my entire asset library every single time that the application is built. This behavior is super weird, since on all the projects that I've worked, Xcode only copied resources if they had changed, or if it were a clean install, or if there was something new that had not been copied before.
In this case however, it copied all the resources on a clean install (expected). However, on every consecutive build, it is still copying some of the files over. Now this is super strange, since none of the files have changed, and it is not copying all the files, only a small portion of them. One more thing - if I run the same app, with the same configuration on the simulator, the copy DOES NOT happen (moar strangeness).
Is there some setting that I can change, or maybe a flag that I can include that might prevent this from happening?
Thanks in advance for the help!
Cheers!
It's been a month since this question's been asked, and I've managed to find a "sort of workaround" solution.
Now, the reason I'm putting this in as the accepted answer is primarily because no other answer/solution has been posted as of writing this. If anything better is posted (or if I have an update), I'll be sure to mark a better answer as the accepted one.
Either ways, this "workaround" will work if you have a super large set of assets that don't change over consecutive builds.
The project I'm working on has a lot of audio and video files that have already been prepared, and aren't going to change (other than the occasional re-recording or something along those lines).
So, as my question states, Xcode was copying a subset of the resources. Ideally, once a resource has been copied (and there are no changes to it), it is not re-copied (at least not supposed to be re-copied) over consecutive builds. In my case, it was getting copied during every consecutive run, causing my total build to start time to be around 15 ~ 20 mins. I'd also like to point out that regardless of whether we used "run script" in the build phases or whether we had the media in our Xcode project, we were facing the same issue.
Solution:
What I did was I cleaned my project, deleted the app, and did a fresh install. So, the first time, it copies ALL the files over with the app. Also, the assets directory is NOT in my Xcode project. We've added a "run-script" phase, wherein we run rsync to copy the media from the media folder, over to the app, during every build.
Now, once the App has finished doing a fresh build; it would have copied over all the required media files.
Then, REMOVE/DISABLE the script, perform a Clean in Xcode (command + shift + K) and run the project again. This time, since there is no script being run, and since Xcode has performed a clean, wherein now it thinks that all it needs to do is re-compile the binaries, it builds super fast. Since I've NOT deleted the App, the media folder is still in my app, and my build to start times are now around 30 seconds ~ 1 minute (this includes sandboxing and code-signing). Code-sign and "sandboxing" the application still takes time, but this is waaaay better than having to wait 15 ~ 20 minutes every time I hit run. :)
Hope this helps!
I've got very similar situation. Also, I have 6 000 resources in my app, and even listing some of them (not copying) was a bit slow. I've found another workaround (very similar to yours, but a bit easy to perform). It was inspired by your one, so thank you very much!
I copied the target of the project, set its bundle id as the original one (it was automatically set with ${PRODUCT_NAME} from build settings) and removed all the resources from Copy Bundle Resources section. First time (after removed from device app) I need to launch the original target with its resources, but then I can build the copied target while resources are still on device.
Some advantages:
it's very easy to switch between both targets
no need two write any scripts (that was purpose I did not use your solution)
Fun with numbers:
58 seconds from "Cmd+R" to loading screen appearing with bundle resource.
20 seconds for the same interval with empty "Copy Bundle Resources" section. Not so good as yours improvement, but still makes difference.
Hope this helps too :)
Related
I have been working in iOS project. Regarding Xcode Derived Data folder whose contents are generated by build system, there are many Stackoverflow posts, i.e. how to remove derived data folder or is it safe to remove derived data folder, etc. but there is none which I am looking for. My question is to know when should I delete the derived data folder and when should I not? In other word, in which conditions this derived data becomes non reusable and why? Are those derived data become stale after resource or configuration change of the project or anything else? I often see many issues are resolved after deleting derived data but we often do not try to know the root cause of the issues.
Can I simply say, until the .xcodeproj file change, the derived data can be reused safely?
Background of the question: In my project, I have a proof build system so that every CLs need to pass the proof build before getting merged to remote branch. So I need to know the risks to architect when I should (or should not) reuse the derived data folder to make the proof build system performant.
Sadly, deleting DerivedData has become the catch all to try and remedy build issues. As you already know, you can delete the DerivedData at any point in time with no issues (unless of course you were building). The nuances as to when it is safe is a little more complicated. In practice I have generally found that significant changes in the code between builds can have issues. Likewise, changing Xcode versions can also have issues. The key words here being can, which does not mean it will.
I do not believe there is any definitive means of knowing when to purge, which is why I think you find most people generally asking "did you remove DerivedData" as one of the first questions when someone has a build problem.
IMHO, I think there is some subtle caching that Xcode does within DerivedData, as I've had build failures in weird situations I could not trace. I would not be surprised if Xcode has some subtle bug related to this caching. In general, I only trusted a command line delete of the project's DerivedData. And if I was extra careful, I'd also purge any associated libraries/frameworks as well as the ModuleCache (in DerivedData). There is also some voodoo in the /var/folders. Not sure if this is still the case, but I have found myself surgically nuking stuff there. Yeah, bad. But I'm also the kind of person that has been known to edit the project.pbxproj file to fix it, so I guess I throw caution to the wind.
Let me ask you this question. What is more important? "bullet-proof" or build times? I've been roped into maintaining or upgrading the build systems for a few apps. I've always done everything as a clean build. This always was fresh pull from source control and then having a defined DerivedData within the workspace (these were Jenkins builds and was configured to use a clean workspace). This pretty much avoided build issues related to needing to remove DerivedData. I've seen way too many strange issues occur due to some Xcode voodoo. It is far better to not add red herrings if you have a build error.
If you do find that the builds as well as any tests needed are taking too long, you can start to devise other strategies to help make it more manageable. This becomes very project dependent. For example on a project I was working on, I moved all libs to pre-built versions. For some reason, they had it setup where they had to build all the 3rd party libs (like openssl) during the build process. This also means that the devs incurred this build penalty the first time they built or any time the cleaned.
You might want to clean derived data when -
When you pull code from remote repository because it might contain new/deleted file which you might be using in other module/project.
Consider there are two project (say ProjectA and ProjectB) in your workspace.
1) You already build your app and their derived data is available.
3) Now consider there is reference to some `Class` of Project A in Project B. You have used static function form ProjectA classes.
2) Now you pull code from remote repo and it contains changes for Project A only.
3) In this pull, the used static function form ProjectA gets deleted.
3) When you build app again, only Project A gets complied again but not Project B because it has no code change. Inshort, when there is change in code XCode complies that module again not complete app.
4) Now you will you get build issue as dependencies are not correct now. Project B has no idea what happened.
5) So in this case, you should clean derived data.
Correct code coverage report.
Code coverage reports into the default derived data directory located at ~/Library/Developer/Xcode/DerivedData.
You can clean code coverge report form DerivedData and regerate it again.
Please correct me if i am wrong. This is as per my understanding.
Will update this answer if i found more reasons.
Derived data can take up significant space too. Derived data is generated during each app build process. Derived data contains intermediate build results, generated indexes, that help speed up build time.
You can think of derived data as cached data/image in web browser, most of the time web browser will auto-save the data/image into your hard disk when you first browse a web page, and the next time you visit the same web page, the page load speed is faster as web browser will use the cached data /image in hard disk.
Few cases I would like to mention when you should delete derived data:
I faced this issue many times that Xcode’s debugger stop working
suddenly so resolve this issue I delete derived data and it start
working fine.
Whenever you are facing issues in building project then it is better to delete derived data and build again.
Deleting derived data causes minor delay in building project for the
first time but it deletes all old settings for the project.
Deleting derived data boost up your system’s performance as it holds lots of memory space which may not needed since very long.
And last but not least for error that are not logical sometimes,
all you have to do is just delete Derived data & error is gone.
Happy to help!
When can i delete the derived data ?
If you happen to have multiple build agents running on multiple machines (either physical or virtual), then each of those agents should do it’s own cleanup.Cleaning derived data might increase the time of first build for each project next day, but it’s a minor drawback. You will also claim free space back by killing DerivedData’s huge appetite. A practical advice to take home - clean Xcode Derived Data on regular basis on your CI box(es),You could create a cron job to do that, make it run some time after midnight and execute this simple shell command.
rm -rf /Users/username/Library/Developer/Xcode/DerivedData/*
For daily use on your development machine create a type alias in your bash profile.
typealias xcode-clean-derived="rm -rf /Users/i4niac/Library/Developer/Xcode/DerivedData/*"
Source :
https://mgrebenets.github.io/mobile%20ci/2015/02/01/xcode-derived-data
I'm at a complete loss as to what I did to cause this:
For the second time since I started using XCode about a month ago (my first time seriously using it after taking one class several years ago) I try to run my project and the next thing I know I have errors because I have duplicate references. I looked at the project and it appeared that most of the files in my project had duplicated themselves, however I discovered that they are not duplicate files just duplicate references. This happened to me today when I tried to build on an actual iphone for the first time but it also happened to me a few weeks ago while using the simulator. Neither time do I recall doing anything unusual. I have built and tested the project probably 100+ times and normally all goes ok. I was able to fix it the first time but I think I have made it worse this time and am probably going to add the files back into a new project. My co-worker also mentioned this happening to him (he has about as much experience with xcode as I do). He told me he ended up with files nested in folders (groups?) nested in other folders about 20 deep.
My question is this: Does anyone know what I may have done to cause this. I would really like to avoid this problem in the future since it is proving to be quite a headache. Any advice would be greatly appreciated.
E.T.A. xcode version 4.6.2 (possibly an earlier version the first time it happened)
Try this instead:
Highlight all the duplicate files
Right click on one of the files and press "Delete"
When prompted for which delete option, click "Remove Reference"
Also you asked for "any advice".
If you aren't already using git source control in your Xcode projects, start now.
You can spot many mistakes like this earlier and fix them more easily using git.
When you add files as a copy, the Xcode project navigator shows added files with an A and modified files with an M.
If the file is inside a closed group folder, the folder shows an A.
If you add a reference without a copy the project navigator won't show an A but MyApp.xcodeproj will show M.
In Xcode you can discard a change before committing it.
In the case below, you would discard changes to all added or modified files.
Typically you review and commit changes frequently.
Using a gui tool such as SourceTree, you have a good chance of spotting an accidental change before you commit. For example, you can see changes to the project file.
If you accidentally commit an unintended change, you can go back later and reverse a commit.
By committing frequently, you have more control over which changes you undo and which ones you keep.
References:
http://www.raywenderlich.com/13771/how-to-use-git-source-control-with-xcode-in-ios-6
http://git-scm.com/doc (scroll down to see videos)
http://www.sourcetreeapp.com
http://gitimmersion.com
I had the same 20 deep nesting of my main folder of images. If its not a bug its very strange behaviour. I just backed it all up !! Then I opened the folder in finder, found the point at which it was starting to nest and deleted it.
I did a rebuild, but I don't think Xcode even noticed. It made no difference to the size of my app so Xcode was not putting unnecessary files in the binary.
This happened to me when I imported a file. Suddenly I had two nested directories containing what looked like copies of all my files. The compiler complained about duplicate classes.
I found a solution, but it's a ball-ache and a time sink.
1: Click on your project in the navigator to open up the project settings in the main view.
2: Open the 'Compile Sources' accordion entry.
(This allows you to see which files are being used in the compilation process.)
3: Find any duplicates in here and delete them.
(At this stage your project should compile again.)
4: In your navigator view, slow-double-click one of the files that's duplicated there. This should allow you to rename it. Change the name (not the extension) slightly.
5: You should notice that the copy becomes red. Select it and hit delete.
(This avoids the delete operation removing the file from the 'Compile Sources')
6: Rename the original file back to its original name again.
7: Repeat from 4 until done, or until bored.
8: Explain to your boss why a simple copy change took half a day.
This process can be optimised up by first renaming all duplicated files, then deleting the duplicates all at once. However this means that you can't test for successful compilation between steps, which allows you to narrow the culprit down to a single file. And takes even more time.
If compilation fails, ensure all the files you need are still in the 'Compile Sources' section, as this process can cause them to be lost from there. The compiler will normally give some reasonable errors about missing classes and variables, but a missing AppDelegate will produce a more confusing error.
I have a strange issue that I haven't seen or read about anywhere else. My Xcode no longer parses all of my files to find issues/errors. It will display any issues or errors in a file I am currently viewing, and these will persist thereafter, but with 400+ files I can't reasonably visit each one to make it compile. Xcode can build successfully if the code is valid, however I can never know when that is, since I see no errors. Indexing occurs, but no compiling takes place.
Also, when building, the status bar states that Xcode is compiling x out of however many total compile sources but the total number is usually not even close to the actual total number. For example it may say compiling x out of 40 files when there are actually 400 compile sources.
I wasn't doing anything out of the ordinary from my usual tasks when this issue began. New projects will compile, then randomly stop compiling after a period of time.
Things I have tried:
nuking derived data
quitting Xcode/restarting computer
Recloning the project from a known working repository. It will build but won't find errors/issues when they do exist. There should be at least a handful of minor issues but none appear.
Reinstalling Xcode (4.5.2)
tried both GCC 4.2 and LLVM 4.1 compilers
Has anyone experienced this issue before and found a solution? This problem has made my job extremely difficult and any help would be much appreciated.
It does sound like corruption of DerivedData. Try this:
Clean your target: cmd+shift+K or Product->Clean
Quit xcode
Delete the contents of /Users/your_user/Library/Developer/Xcode/DerivedData
Restart xcode
(It's safe to delete this folder's contents. But if you're nervous about that, back it up first).
You should be good to go.
I'm working with a rather large, asset-heavy project for iOS and I can't help but notice Xcode copying hundreds of resources (textures, spritesheets, sound files, etc..) that haven't changed at all since the last time I built to the device. It makes coding really, really slow when each build takes 2-4 minutes to pop up on the device.
Is there a way to get Xcode to recognize that it's doing redundant things or write a script that allows it to be more intelligent about how it transfers resources over to the device?
PS I realize that there may not be any built in 'appending' functionality for an app. I hope that isn't the case.
You can try add another target to the project and name it "without resources". Exclude all heavy resources from this target. First time you need start app with all resources target, next time use "without resources" target. If you added something to the project you should use first target.
iOS only supports deploying full application packages that are signed to the device. The process for deploying a debug build to the device is this.
Compile altered source code and sign binary
Alpha pre-multiply PNG images
Create a folder with application resources and binary inside
Sign the contents of the folder and create a ZIP file with the folder and signature
Copy the ZIP file (.ipa) to the device
Unfortunately, I'd imagine the time is being spent in #3 and #4 which gets created each build. I haven't seen any way to speed this up. If you have many, many PNG images, you could try telling Xcode to skip Step 2.
NeverBe's approach sounds like a great idea if your application can allow you to not include many of the resources for most of the time you're developing. You could alternatively have a second set of much smaller/dummy resources that you could switch in and out.
Sometimes, XCode really put unchanged resources to package.
Usually, when you change files by Finder, not XCode.
Make Project -> Clean to make complete rebuild
I've been stuck with a huge problem for a few days now and it is very frustrating. Everything was working perfectly until I messed around with target settings/provisioning a few days ago. Essentially no images are being copied from the project to be included in the app bundle.
I have:
Double checked their case consistency
Made sure they are all included in copy resource bundle section of
build phases
Performed multiple cleans and manual clean outs of the derived
data folder
And the images appear fine in the simulator.
I really don't know where else to turn or what else to try. Any help in solving this would be HUGELY appreciate as I am trying to release an update for an app but am unable to do so before getting this fixed.
ALso it is worth mentioning ever since this problem started occuring it happens in all of my xcode projects.
Check the build log. It's in the "Log Navigator" tab (press command-7). The build log graphically shows the results of the build steps.
Check the path of the individual "CopyPNGFile" steps. You can also open the textual log by clicking the far right button in each build step.