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
Related
I am trying to copy over my Xcode project from one computer to another but it seems to lose frameworks and the locations for the images although i copied those too.
PS I am using xcode and coding an app with a friend. Is there a useful source that can help us both code at once/ transfer code files.
Thanks for the help.
Try transferring everything from plists to the storyboard. I did this with a friend of mine and it only took about 20 minutes for the code to build and run successfully on his own laptop. the biggest issue is going to be transferring the files that Xcode is going to have to search for, and making sure that the search paths match with where you save the new files.
SDK's and images are difficult because of this path issue - make sure you find where the pictures are supposed to be searched for then add the images there.
Just take your time - even write down where each file should go or where you have put it and you should get it working. Best of luck!
You have to select relative paths in your project for your resources/frameworks (e.g. Relative to group). If you have absolute paths, it won't work on a different computer. Also check in the Build Settings of your target the Framework, Library and Header search paths.
I am developing an app which itself is small (~20m) and builds fast on the simulator, but comes with a large database (~800m) and takes a long time to build on a device. It seems the majority of time is spent on copying(verifying) files in the database which never change. Is there a way to reduce/skip this step and accelerate the build?
Maybe while testing you could put the database in the Documents folder and copy it through iTunes or drop the files in the right folder on the simulator.
I think that way Xcode won't need to copy the file to the device, but of course it makes for a slightly more complex setup on the first run.
For testing purposes, I need to periodically deploy new builds of my iOS app to the device which has old data in its document folder. I'd like to be able to selectively update part of the data and control keep-new or keep-old behaviour for any files in the document folder.
Basically, the tooling support I want is to update only the data that changed when deploying to device. For example whatever in the dev-machine's Xcode project resource folder that are newer or different from their counterparts (files of the same names) on the device (by date, size, etc.) get transferred and their counterparts on the device get overwritten by those. Everything else is ignored.
An ideal scenario would be: When I hit BuildAndRun in Xcode, Xcode will figure out what data to transfer-and-overwrite-device-files and what not to based on some custom rules.
Is is possible to achieve this with Xcode?
UPDATE
I edited the above text to make it clear that I don't want to add app logic for data versioning. I want this to happen in my build-and-test pipeline (Xcode).
Normally, this is pretty simple. Everything that XCode sends goes in the resource bundle. If you update it on the device, you have to move it to the documents directory, as the resource bundle is write only.
Any resources that you might be updating on the device already need 'does document version exist' kind of logic, the only change you have is to maybe add some modification date stuff.
You do have the option in the run scheme to upload application data to the sandbox directory.
Here is a good starting point:-
http://developer.apple.com/library/mac/#recipes/xcode_help-devices_organizer/articles/copy_app_data_to_sandbox.html
In essence, you can download data from a device in the device manager and create an xcdata package. Edit this to contain just the stuff you want to upload.
You can then either upload this manually or specify it in the Edit Scheme dialog ( under options), so it gets uploaded every time you run the scheme.
Easiest way I see to do it is to encode a version number in the files, and the ones you need to update, you increase the version number on them in your code, so when it runs and encounters a file that has a lesser version number, it deletes or ignores it
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 :)
We are developing an iPhone game and I would like to know if is possible to copy new or updated assets (images, animations, sounds or whatever) on the device and test them without rebuilding the application in XCode.
We would like to simplify the production pipeline process and we are trying to avoid our artists to rebuild the application every time they modify the assets.
Any advice is much appreciated.
Fede
Yes, I did it in one of my projects.
My strategy was easy, at the start, I stored the new assets in the app documents folder using a wifi tool specially created for that. Then, when the game needed a resource it checked if it was at the documents folder, if there was, it loaded, if not, it loaded the one from the bundle.
No, because any files that are updated in the XCode side will need to be rebundled and rebuilt. I'm surprised that this is an issue because the build process is remarkably faster between cleans. You're probably not rebuilding the entire application from scratch (ie after a Clean) each time, are you? XCode should detect any resource changes and update them on the device.