What does iOS do when an app is "Installing" and is it possible to programmatically control it? - objective-c

I understand it may be unpacking some sort of compressed package into the file system (and due to the mobile nature I suppose it may be quite aggressive compression to reduce download time). But does it run any sort of preflight scripts? I suppose it does stuff like register the info.plist, add a pane in Settings.app if you've specified one, and the app's global URL and file type reception registration.
The reason why I'm interested is twofold: curiosity (would there be a way of seeing precisely what's going on? Has anyone investigated this?) and making an installation script. I'm constructing a dictionary app using Core Data (I've thought about this a lot, trust me, I want to use Core Data) and I'd like to have a way of nicely generating the Core Data store from the original XML without degrading the user experience by having some kind of "initializing app". Furthermore I'd like to deploy the dictionary compressed and then uncompress it on the device, to keep it under the 20 mb over the air download limit.
I suppose I could generate the Core Data store on my simulator or dev phone and then add it to the bundle, though that way still seems less than neat. Hence why it would be nice for iOS to handle it for me
Anyway, thoughts?

Whatever the OS does during install, you can be certain that Apple does not offer developers any hook into the operation. There is no way to run any code of your own (install script etc.) until the user first launches your app manually. So do whatever initialization needs to be done on first launch.
The .ipa packages you submit to Apple are already compressed (they are just ZIP files with another file extension) so it should not be necessary to compress a text file yourself to stay under the 20 MB limit. Compressing it twice probably won't help much in terms of file size.

Related

Is there a way to hide assets from users within my Mac App?

I have developed a simple app for Mac which uses a browser window to display some content. Now the assets (images etc.) are visible to anyone who receives the app and discloses the content in finder using 'show package content'.
Is there a way to prevent this? Can I hide it or encapsulate it somehow using code or some XCode function?
A trivial way would be to change the extension on your files so the system doesn't recognize them as images. You'd then have to load the images as data and convert them to images in code, which would be a bit of a pain.
A more rigorous solution would be to encrypt the images in your app bundle, then write a utility function that loads and decrypts images.
Here's another option.
You can zip all the assets. Use whatever is easiest e.g. pkzip or gzip or even just tar it all. Then you hide a lot of info and, if you want to go the extra step, it is easy to encrypt the zipped file and there are lots of libraries around to include in your project and use to unzip it with.
It should be easy to read assets directly from the zipped file, but if you need them individually you could e.g. put a single file / resource inside a zip or you could unzip it. You could even unzip to temporary space and remove it all when the app quits if you have really sensitive stuff that is too big to fit in memory.
** EDIT **
Java works this way right. A jar file is just a renamed zip and it often contains all of the resources the app needs, and it seems to be working there. So if that is a guide performance should not be too bad.

Objective-C - Finding directory size without iterating contents

I need to find the size of a directory (and its sub-directories). I can do this by iterating through the directory tree and summing up the file sizes etc. There are many examples on the internet but it's a somewhat tedious and slow process, particularly when looking at exceptionally large directory structures.
I notice that Apple's Finder application can instantly display a directory size for any given directory. This implies that the operating system is maintaining this information in real time. However, I've been unable to determine how to access this information. Does anyone know where this information is stored and if it can be retrieved by an Objective-C application?
IIRC Finder iterates too. In the old days, it used to use FSGetCatalogInfo (an old File Manager call) to do this quickly. I think there's a newer POSIX call for that these days that's the fastest, lowest-level API for this, especially if you're not interested in all the other info besides the size and really need blazing speed over easily maintainable code.
That said, if it is cached somewhere in a publicly accessible place, it is probably Spotlight. Have you checked whether the spotlight info for a folder includes its size?
PS - One important thing to remember when determining the size of a file: Mac files can have two "forks", the data fork, and the resource fork (where e.g. Finder keeps the info if you override a particular file to open with another application than the default for its file type, and custom icons assigned to files). So make sure you add up both forks' sizes, or your measurements will be off.

How do I disable PNG file "optimization" when building in MonoTouch?

I am making an application which uses a large amount of PNG file resources. In order to minimize the size of my binary, I have manually optimized all of my files, and was able to reduce the resources folder size to almost 20% of the original non-optimized size.
However, when building my application for device (not simulator) testing, the build process attempts to "optimize" my PNG files by running what seems to be a modified version of pngcrush, which not only makes the build process almost five minutes longer, and makes most of my files larger, but also makes some files unusable by doing alpha premultiplication, which I don't need, since I'm using the alpha values for purposes different than transparency.
I found that it is possible to disable this step in xcode, were I making an objective-c project, by changing "Compress PNG Files" to "No" in the Build Settings as described in this webpage.
However, I have not been able to find how to modify this setting in the MonoDevelop project.
How do I disable this PNG "optimization" step when building from MonoDevelop?
This feature is being worked on (in MonoDevelop). However the iPhone addin (for MonoDevelop) is not open source so hacking it yourself won't work.
Right now you have two options.
Moving the image directly to the device during development so they won't be deployed each time (along with the application). You can see how to implement this hack from this article.
Hack your iphone-optimize script (that's what MonoDevelop calls). The script tis located in your Xcode directory (if you have several version then the one specified in MonoDevelop's SDK locations is being used).
For this you need to:
Backup your existing (original) PNG;
Copy the optimized PNG as your 'new' originals;
Backup the iphoneos-optimize script;
Edit that script to ignore the PNG files (i.e. not execute pngcrush)
Keep in mind that updating Xcode will replace the script - so you'll need to re-edit it after updates.
Half year ago it was not possible.
Yet, since MonoDevelop sources are open, it is possible to patch it and compile from sources.

Lock Embedded Resources in Cocoa

I'm developing on Cocoa using Xcode. I was wondering if there is a way to lock the embedded resources of my app, like logos, images, sounds, ... so nobody can change them?
Probably the easiest way would be to check timestamps on the resources, but this is also easy to circumvent. A better way would be to compute the hash of your application's resources directory on launch, and compare to a known value.
If any of the resources have been modified then the hash will differ and you can show a message and quit. You could use a custom build script step in Xcode to calculate the hash and have it available at compile time so that the process is all automated.

iOS 5: ~/Library/Caches - How to check all required files are present a very smart way?

I guess everybody read about the recent issues with the new iOS 5.
e.g. at http://iPhoneIncubator.com/blog/data-management/local-file-storage-in-ios-5
My Magazine-App holds about 1k html/css/image/video files for every issue and I want to know if anything is missing.
So my question is how to check all required files are present a very smart way?
I would expect iOS to clean caches atomically; i.e. iOS will either clean you app's cache or it will not. It shouldn't partially remove files from your cache. However, I don't believe this is documented behaviour, so it's a bad idea to assume this.
When you download your content, you have to know what to download for each issue, right? So you already have some kind of manifest file that references every file that is needed by each magazine. You should save this manifest locally so that you can refer to it when checking for the existence of files. You can still save this in the caches directory, if it's missing, you know your cache has been at least partially cleaned.
Also, I don't believe there's any guarantee that iOS won't clean caches while your application is running. As well as checking at the point where the user opens the magazine, you should check when your application becomes active after it has been put in the background, and your code should be robust in the face of missing files (i.e. pop up a warning message instead of crashing).
You could zip all the files relating to each issue in an archive (objective-c wrapper for zlib here, to make life easier for you). That way you can make sure that the system either deletes your issue or not, without having to worry about individual files.