I have a game where each level has its own logic, so it is a module with level-specific code and graphics.
I am confused on whether its possible to download and integrate dynamically in the app each level.
Searching the web, I found that nsbundle is the standard way for performing this task, however loadable bundles are not supported in iOS.
Is there a way to approach such a task,and if yes, it is not even clear to me if it is even permitted by Apple
Why do not you want just hide all extra levels in your app and unlock/show them instead of downloading?
By the way, apple will not allow you plugging in any code that is not approved by them.
Downloading code is not allowed by the App Store rules.
Thechnically, it's possible by simply saving the files you want into the document folder of your app.
You can get this path with:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
Then use whatever API to write your levels there.
Now while you are allowed to download additional assets, you are not allowed to download additional code. But I'm unclear on this, I know an app that download some .lua script files and never had any trouble with Apple. For the legal side, you'll have to trust someone else.
EDIT: By code, I mean compiled code (like a dylib), while using dlopen of the iPhone may work, it's not allowed or documented.
Related
My iOS app was rejected because I use the /Document directory to store downloaded images.
I will move the downloaded images in the /Library/Caches directory to solve my problem.
But my sqLite database also contains elements manually created by the user.
This file must be copied into the /Library/Caches directory or /Documents directory to be accepted by the Reviewer ?
Sincerely,
Maxime
As per the iOS Storage Guidelines (which can be found at http://developer.apple.com/icloud/documentation/data-storage/) you should put all user-generated content in the Documents directory and all re-downloadable content in the Caches directory. So you should be fine putting the sqLite database there.
The background on this is that starting with iOS 5 the Documents directory is backed up to iCloud. As a lot of apps tend to store their complete data there the iCloud backups get rather large, which uses up the free space and creates network traffic, both of which in turn anger the user because he/she wonders why. To mitigate this Apple now seems to take a much closer look on what is saved into the Documents directory and if this is possibly regeneratable content (e.g. downloadable files).
Beware, that the Caches directory can and will be purged on iOS 5 by the operating system at times when the free space on the device gets low. Thus your app cannot longer just assume that everything is there as it was before but you rather have to re-check every time you access something out of your cache.
The data manually created can be stored with in your app directory.
You can use below code to get the current directory -
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
and then append you file name to get the full path.
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:#"myfile.format"] ;
Instead of using a web-service to get current application version number and comparing it in my code for popping up update alert, Is there any way to obtain the application version number from App-Store / i-Tunes directly?
After going through all the comments correct me if i am wrong.
We should not show a Local Notification(as alert) to User regarding availability of new update programatically?
I went though HIG Guidelines, but could not fing such creteria. So little confused in deciding.
Alert updates like this will certainly be against Apple guidelines. For iOS devices, application alerts are displayed by the App store app with a badge displaying the number of updates available. There is nothing a developer needs to do.
If you are worried about the user missing your app update, rest assured that iOS users keep an eye on the app-store app & know that all updates come through it.
However, there are hacky ways by which you can figure out that this is your first run after an update without contacting any web service or iTunes/App store.
One of the hacks known to me:
Fetch the library directory path-
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
libPath would be something like - /var/mobile/Applications/8CFB747F-9446-44CB-98B9-C6FF1CF7BF93/Library
This random string before /Library changes with every update. You can save this string in NSUserDefaults, and compare the path with the saved string on every launch. If the strings are found to be different, it implies that this is your first run after the update. Display the update alert! Then update the saved string with the new one.
Yes. You could do an HTTP request to the itunes.apple.com server, while mimicking the User Agent string of iTunes, for your app's URL in the App store, and parse the returned HTML or XML you get back to find the version string, which may or may not be acceptable to Apple's approval team. But that's unlikely to be worth it, and it also presents an uncommon and unexpected user experience.
I have an iPhone game, where, dunno, the player has like 3000 gold. Sweet.
Then his iPhone had some badass spontaneous combustion.
The player gets a new iPhone, but logically the game will reset him to 0 gold.
What method do you recommend me for saving such important data? Also, the data I might want to store can be a bit larger (loads of arrays containing important player stuff).
Thank you.
Store the info you need in the application support directory for your app.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *appSupportDirectory = [paths objectAtIndex:0];
You can write your arrays out to a plist file in this directory. Then if they choose to restore from a backup from the destroyed phone and they have made sure to sync their phone before they let it combust they will get their gold back.
Keep in mind that one could use the restore from backup feature to get to a previous amount of gold so you want to store their purchases and progress in a similar manor.
Also, depending on what you mean by "loads of arrays" you should probably consider using core data instead of plist files. Your code will scale much better. You can store your database in the same directory to get the same backup behavior.
Recently some apps tried to provide an option to sync data with dropbox. There must be some easy code snippets to do that. You could give an option to sync the save game data with Dropbox.
You can use GameCenter or OpenFeint or both. In fact, most devs use both.
I've got an iPhone app under development that I plan on using for research purposes. As testers use the app on my development phone, it stores analytics data in a local database (right now SQLite, but I'm not opposed to migrating to CoreData).
After testing is done, I need to be able to copy this analytics database off of the phone onto my computer so I can run queries on the data. What is the easiest way to accomplish this? If necessary I'll iterate through the data, print it to the device log, and then import it back into a database on the desktop, but I'd like to find a way to just grab the .sqlite file without running it through an intermediary format.
You can use the Xcode Organizer to download a zipped snapshot of your app's Documents and Library directories from your device.
You can always try to print it to a PDF, using the UIKit is a simple way to export information and formating in a easy way, unless you think this method can't apply to your database ;)
Do you know if we can email the SQLite database directly from the iOS device?
Easiest way would be to add the UIFileSharingEnabled key (as a boolean, set to YES) to your Info.plist, then use something like this:
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
[[NSFileManager defaultManager] copyItemAtPath:whereverTheDatabaseIs toPath:[docsPath stringByAppendingPathComponent:#"exported.sqlite"] error:NULL];
Then, you or your users will be able to grab the database off the device using iTunes's file-handling malarkey.
edited - actually, see Ole's answer: I didn't know about that trick, and it'll probably be much faster.
Thanx ole begemann.
In organizer open your app and then Download that particular send Box. So It will create a .xcappdata extension file.
You can rename the extension to .zip then you will find the same folder as in InApp directory folder in your finder. and you can work with your data.
My iPhone app (well, idea of it) needs to do changes to iPhone's filesystem. Does iPhone API allow that?
Your app has its own piece of filesystem that you can read from and write to but you can't access anything outside that, ie you cannot access the filesystem areas of other apps or the OS itself.
Yes Cocoa Touch for iPhone OS allows file access. With the caveat that it naturally only allows file access for files that the current user has read-write permissions to access. Each application runs as single user, and really only have access to it's own small sandbox of files. So you will not be able to access system files, or files from another application.
There are two main directories that you might want your app to access:
NSDocumentDirectory - Analogous to you own Documents folder, the contents of this folder is backed up when you synch the device.
NSCachesDirectory - This one resides in /Library/Caches/ and is not backed up when synching the device.
You get the path to these directories using the NSSearchPathForDirectoriesInDomains function. When searching you will get an array of potential paths, it is safe to use the first path as long as you only search in the user domain. For example:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* docsPath = [paths objectAtIndex:0];
Once you have a path you can work away with your files using the default file manager. For example remove a file:
NSFileManager* fm = [NSFileManager defaultManager];
[fm removeItemAtPath:filePath error:NULL];
i just wrote a tutorial on how to do this using NSMutableArrays that you can check out that should help you. http://idevkit.com/iphonedev/2009/09/saving-nsmutablearrays/
if you have anymore questions on it lemme know and ill add to it