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.
Related
I have made an app which has 15 levels, in which each level has 3 stages.
So overall I have 45 scenes/viewcontrollers.
I'm trying to figure out how I can create a saving function, so that if you close the app on the phone and you open it later, it will remember which level/stage you were at. I just started with swift and I am also wondering if this is way too ahead of my programming level to create this, but hopefully it might be more simple than I thought?
As long as the desired pieces are small, which simply saving level/stage text info would be, NSUserDefaults is the way to go.
Core Data is a great technology, but takes a bit of learning and is overkill for only saving a tiny bit of information. Been using NSUserDefaults myself a bunch lately, and it's working well.
//in Swift:
let defaults = NSUserDefaults.standardUserDefaults()
//send data to NSUserDefaults:
defaults.setObject(desiredValue, forKey: stringNameOfValue)
//retrieve data from NSUserDefaults:
desiredValue = defaults.objectForKey(stringNameOfValue)
for more info:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/
As already noted, NSUserDefaults is a great option for the scale of data storage you're looking at. But another good option is to use NSUbiquitousKeyValueStore. That class works similarly, but adds the ability to sync the small data items you're saving to iCloud.
There's a little bit more you have to think about when using iCloud KVS, but it's almost the same as using NSUserDefaults. And for that tiny bit of extra effort, your users get a huge win: when you close the app on your phone, you can open it later, on the same iPhone or on your iPad, Apple TV, Mac, iPod touch, other iPhone, etc, and still have it remember where you left off.
I am working on an iOS app that I want to use iCloud for storing documents/presets.
As you can see in the screenshots its quite a simple solution I have now. I Simply archive a list of presets (title, description, expression, and source). What would be the best solution for storing those presets/documents in iCloud so you can continue your work on iPhone/iPad/ (Maybe even OS X)?
Inherit from UIDocument, or use KVS with NSUbiquitousKeyValueStore?
Thanks!
I would suggest NSUbiquitousKeyValueStore since you are not storing an actual document and more configuration setting, plus NSUbiquitousKeyValueStore has the auto synchronize with your app and iCloud that you don't have to worry about. Also this is basically free memory in iCloud that doesn't count against the users memory allocation on iCloud.
If you are storing things like images, Documents would be a better fit.
Good example here:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/UserDefaults/StoringPreferenceDatainiCloud/StoringPreferenceDatainiCloud.html#//apple_ref/doc/uid/10000059i-CH7
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'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.
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.