How to add large number of static files to MonoTouch bundle? - ios

I have (quite a bit of) static files that I need to deploy with my application that is built on top of a legacy .NET library. These include several XML and config files, and a read-only database in the 10's of Megabytes.
Most forums I have seen indicate that the best way to accomplish this is to reference the needed files in a project, and set them to Content and "Copy to Output Directory".
I have two issues/questions dealing with this:
Adding these files, and setting them to "Content" seems to not only copy the files over, but embed them into the .dll as well. In other words, I have 40 MB worth of files, and a 40MB dll (this project's only goal is to import these files, there is no substantial code).
How can I prevent this extremely large dll from being made?
Is there an alternative way to get files into the App bundle? I would love to use a custom build command, and although I can copy files into the target directory ${AppDirectory}, but this does not result in these files ending up in the app bundle. Is this approach possible?
Any help is appreciated in advance.

You need to include your files from the main .exe project. You do this by using MonoDevelop's Build Action to Content on each file. They should be copied to the .app without being included inside an .dll (or the .exe).
An alternative (for development) is to use iTunes sharing to copy once your files to your device. This allows you much faster deployment times while developing.
Of course you can't submit such build to the app store (unless the files are not required to make the application work, unlikely). What I do (for my nearly 80MB read-only database) is to use this hack (loading from /Documents) inside #if DEBUG. The release build load the files from the normal location.
I have not automated the process (still debugging the app ;-) but it should be possible to script this so modifying the project options (for each file) is not required when switching from Debug and Release builds.

Related

Are these files needed inside the .app file? (swift)

I'm very new to xCode (or compiled code in general) and I was wondering when I was looking through the .app file if all these were needed.
For every of my classes there is a .o; .d; .swiftdeps; ~partial.swiftdoc; ~partial.swiftmodule file.
Some of these files also contain my working directories...
In the Build Phases of my app I added all my classes to Copy Bunde Resources (otherwise I would get a compile error), maybe that is the reason or are all these files just necessary?
Because when I was looking through over apps I did not find any of these kind of files.
Thank you for your help. :)

How can I arrange my project files according to their folder structure in Xcode

I am working on a MASSIVE project with about 10 thousand files in it. The files are nicely arranged in Xcode's directory system but not so on the disk. Is there a tool that I could use that would make the folder structure on my disk represent the folder structure in Xcode?
Personally, I know two ways to do it:
Do it manually (rearrange your folder first, and then drag and drop your directories in xcode). That will do the job.
Use an external library, I suggest you synx. It does the job well
I don't know why you want to do that, but I don't think it's really important if your folder isn't ordering with your xcodeproj since you will always open it with xcode. Just separate assets is enough, isn't it?

Can I access an xcassets directory on the filesystem?

I would like to dynamically load all images in an xcassets directory. The files are named StockPhoto# where # is the number in the list. If I can access my StockPhotos.xcassets at runtime to count all the files in the directory, I won't have to manually load the files each time I add new stock photos.
If there are other solutions to this problem, I'm open to that but I'm also just very curious how xcassets are handled by the file system- whether they're just reference to a set of files, or actually their own directory. Information on this is sparse.
If there are other solutions to this problem, I'm open to that
The problem is that there is no introspection at runtime into an asset catalog: it isn't a "thing" you can "see" as far as Objective-C and Cocoa Touch are concerned.
The usual solution to this kind of problem is to drag a folder full of images into your project at the outset, and when you do, choose "Create folder references for any added folders" in the dialog - not "Create groups for any added folders". The result is that the folder is copied into your app bundle, and now you can use ordinary file system methods to say "every file in this folder".
Upon compilation of your iOS project, xcassets are compiled to produce either image files, or a proprietary .car file. In that latter case images won't be stored in a directory you can browse.
If your "Deployment Target" is less that iOS7 (meaning that your app would still be able to run on iOS6)
It will produces the same set of image files that you would have had to produce without using Assets Catalog, namely <YourImageName>.png, <YourImageName>#2x.png, <YourImageName>~ipad.png, <YourImageName>~ipad#2x.png and so on, for each image set of your xcassets.
If your "Deployment Target" is iOS7 or greater (meaning that your app would only be able to run on iOS7+)
It will produce a single big .car file in the final bundle (I don't really looked up if this file was actually an sqlite3 datatbase or some proprietary format or whatnot, but who cares, you are not supposed to manipulate it anyway). This big .car file contains all the images, with all their provided variants, and even with slicing info (if you did slice some of them for tiling or to use them as 9-patch images using the tool provided for that in the Assets Catalog editor)
Whatever the produced result you shouldn't / are not supposed to dig into internal details of your bundle like that. The format of the .car file may even change from one iOS version to another (who knows? that's internal details after all which we shouldn't have to deal with) so don't base your logic on it.
[EDIT]: If you need to be sure to have a directory with your set of images at the end of the compilation, you could instead use a folder reference (referencing a real folder in the Finder, as opposed to an Xcode "group" as only group files in Xcode's Project Navigator) then use code to browse it. But then you will have to deal with other details, like only browse files that match the current device (iPhone vs. iPad, non-retina vs. retina…), so this would only shift the problem further in your case; you really should use a constant somewhere to declare the number of images (or put this in some PLIST file for example) and iterate thru them.
As the files you provide at compile time will be in your Bundle — which cannot be altered once compiled as it is digitally signed — the number of images will never changed once the app is compiled anyway. (That's not like if you used the Documents directory and enabled iTunes File Sharing or whatever, letting the user add images himself ;-))
If you're targeting iOS 7+ then no. Xcode will package the files into a proprietary format (.car) that you can't access directly.
Either use imageNamed: methods, or don't use Image Catalogs for the files you need to access directly.
as #AliSoftware suggests you can store all assets images to plist and access them later for more details see here

What's the best way to swap Xcode contents for projects intended for many clients?

I've got a relatively large Xcode project that produces a single app. However, I have many clients/customers who require deep customization and branding of said app. These configurations include different graphics, a few different interfaces and implementations, and, perhaps most importantly, .xcconfig files.
My Xcode project has a dedicated group that points to a particular client's customization folder on disk, so by opening the Xcode project and building, you get a build of the single app with the current client's customizations. To switch to another client, I change where that group points to on disk. (I also change and switch-back the xcconfig "Based On" settings in the project's Info pane to reload the full xcconfig inheritance; Simply changing the group containing one or more xcconfig files doesn't reload this!) This has worked great for 100+ clients. It's a little tedious to switch this folder every time you need to build the app for a different client and ensure the xcconfig is correct, but it works.
Now I'm in the process of automating builds via the command line, and running into troubles. The quick and dirty solution to pointing the aforementioned Xcode group at a different customization folder was to copy the ProjectName.xcodeproj/project.pbxproj file to ProjectName.xcodeproj/project-template.pbxproj and put placeholders inside this file that can be grepped and replaced with the name and path of the desired customization folder. Then, temporarily overwrite project.pbxproj with the modified project-template.pbxproj, and build to get the correct app.
As you've probably observed, the project.pbxproj was duplicated and modified, and will therefore get out of sync as developers modify the original and forget to also update the template. And besides, I shouldn't really be messing with pbxproj files in this fashion anyway -- that's Xcode's private stuff.
So, is there a better way to tell Xcode about a folder full of resources, code, and config files perhaps during the Build Phase with a script or environment variable, rather than at the project group level? The most complicated bit seems to be the xcconfig chain, since each client has their own xcconfig file that inherits from the single app's Debug, Development, and Distribution xcconfig files.
Sorry for the long-windedness of this question, but it's a little complicated! Any suggestions would be greatly appreciated!
I think you would way better off using the targets feature in Xcode. Have one project and the resources of every clients in that project.
You can then duplicate the target you already have (right-click on your target, by selecting the project file in Xcode's Project Navigator).
All your targets will be compiled with the same code. You just need to change the resources in Build Phases > Copy Bundle Resources to have different app created for each target. No need to look at Xcode's internal files.
You can even change the code in your source files by adding a preprocessor macro in your build options (something like FIRST_CLIENT=1) and then look for these definition in your file with #if FIRST_CLIENT.
I have a project set-up like this and it works pretty well :

What is the best way for packing 6000+ sound files in a iOS Application

I'm working on a iOS application that will contain around ~6000 mp3 of sounds files.
Each one is around 1 second (2 max) long and rather low quality (24K bitrate) weighting in at around 2-3KB each. (Please do not comment on the quality, it's as it should be)
Since this is a large amount of files I was wondering what we be the best approach for packing these into the bundle? Should I just throw them together in a group? Is there someway of storing them in a single "package" file then reading them out separately as needed?
Also, what would be the best place to place them: Library/ ? Documents/?
As I'm rather new to iOS development and kick in the right direction will be greatly appreciated.
Thanks in advance,
Ken.
You can create a bundle which will contain all your mp3 files. Your files will be in the ressources of your application, no need to store them in the Documents or Library path of your application sandbox.
The way to create and access a bundle is illustrated here.
Hope this helps
There is no package type that were meant for resource files. There are ones for static and dynamic libraries, custom frameworks and so on, but purely for resources I know of none.
Instead of adding them in bulk into a Group in Xcode's project hierarchy, you should add the containing folder as a folder reference to the project. (Appears in the file navigator in blue.) This way any external modifications you make to the contents of the folder, like adding/removing files will automatically be picked up when you next compile your project.
You can do this by dragging the folder from within Finder to the project browser in Xcode and when asked choose "Create folder references for any added folders".

Resources