I am developing a Windows Phone 7.1 application. The app serializes objects to JSON and saves them to the IsolatedStorageSettings file.
The objects also have images that the user may capture with a camera. These images are saved to Isolated Storage as a jpeg file with the "Extensions.SaveJpeg" method. Images are referenced by a unique ID from the object JSON so they can be loaded from the storage with the object itself or loaded only when needed.
Now that I have this up and running, I would like to create a backup to SkyDrive functionality with recovery.
What I want to ask is how can I simply backup the Isolated Storage as whole, and recover as whole?
I've been thinking if there is a way to (1) generate a zip file containing the whole Isolated Storage, (2) upload that to SkyDrive, (3) downloading from SkyDrive and (4) unzipping it replacing any existing files in the storage.
The steps (2) and (3) I know how to do (instructions found easily by google). I can also do step (1) but with many lines of code. I am seeking for a simple solution to zip the whole storage and recover from it.
I recommend you to use Perst as the local database solution for your windows phone application.It can be imported or exported as xml which you can upload/download to/from SkyDrive or other cloud system.
Home page of Perst:http://www.mcobject.com/perst/
Related
I have an iOS 7 app, that is using Core Data. Some of the Core Data objects has a related (one to one relationship) images that are > 1MB & < 4MB and are stored in the app’s Document folder. Core Data objects only stores image names as string.
I want to integrate iCloud support for the app so I can sync data between devices. I am planning to use iCloud Core Data storage to sync Core Data objects. But what to do with the images?! After reading different posts, I found a couple of options that are highlighted underneath. I am struggling to pick one, that would suit me best. It would be nice to know someones experience/recommendations. What I should be careful with, or what didn't I think of? I also need to consider migration of the existing data to the option I will pick.
OPTION 1. Store UIImage in the Core Data as Binary Data with External Binary Data option (read here). At this moment is seems to be the easiest solution, but I guess not the best. From Documentation:
It is better, however, if you are able to store BLOBs as resources on
the filesystem, and to maintain links (such as URLs or paths) to those
resources.
Also will the external files be synced? If so, how reliable the sync would be if the user quits on minimises the app, will the sync process resume? From objc.io about External File References:
In our testing, when this occurs, iCloud does not always know how to
resolve the relationship and can throw exceptions. If you plan to use
iCloud syncing, consider unchecking this box in your iCloud entities
OPTION 2. Store images using UIDocument (good tutorial here) and somehow track relation between Core Data entry and UIDocument. From what I understand whatever I put in this directory will be automatically synchronised to the iCloud by a system daemon. So if the user quits the app, the images will still be synced to the iCloud, right?
OPTION 3. Using FileManager(more info here). I haven’t read a lot about this approach, but I think it can also work.
OPTION 4. Any other?
There are similar posts (e.g. Core Data with iCloud design), but unfortunately they don't fully answer my question.
Seems Apple will reject application because of large database iCloud synchronization.
I think the best solution is to store images on a remote host, and keep Image URL in CoreData.
And also Local path of image should be resolvable from remote URL.
So the algorithm will look like this ->
1) Getting Remote URL from CoreData.
2) Resolve local path of image.
3) If local image exists retrieve it, otherwise read it from remote and save it to local storage.
You can have a look to Amazon S3 server here.
I'm a little bit confused over the various types of storage that is available to Windows Store Apps.
Let's say I had a notepad app, where users can view, create, and edit notes. What storage type would I use for storing the notes? Local storage? Write the notes out to files in the user's Documents folder? Also, what if I wanted to sync a user's notes via the cloud? I understand that Roaming Data has a rather low size limit.
Almost all the options you mention are possible for a notepad application. Except the roaming data option, that only allows you to store 100KB of data.
I will try to sum up the options that you have and add a few more:
Localstorage
You can easily add these files to localstorage, you can store it in file format or serialize your object and store that one. Very easy to implement. Con is that only your app can access these files.
Documents folder
Also an option. Made easy by use of different filepickers. For example the FileOpenPicker or the FileSavePicker. Files can be stored in the format you like and can be accessed by other apps or through the file explorer.
Roaming data
No option for files due too the limited space
Skydrive API
If you want to store files in the Cloud and access them anywhere you could consider the skydrive api. Also note that if you use the filepickers you also have the option to save/load these files to skydrive. (Although in that case the user chooses where to store the file.)
Windows Azure Mobile Services
Another option if you want to store data in the cloud. Gives you the ability to store your data in a table/tables. Very easy to implement. More info about mobile services can be found here
SQL Lite
If you need a local database to store your data than SQLLite can be an option. Tim Heuer has wrote a nice blogpost about how to use SQLLite in your windows 8 app. You can find it here
Hopefully this clears up things a bit and gives you some ideas about what to choose for your app?
In an app like this (a notepad style app), the logical place to store you files in in the user's documents folder. That way they are accessible to the user from other apps as well as the current one. There is, of course, the option to roll your own methods to upload the data to SkyDrive as well, but you really shouldn't rely on this as being your only data source - what if the user is offline?
I have an iOS application that currently manages a small bunch of settings (via NSUserDefaults, I know how to sync these via iCloud) and some list data.
Let's say as an example I want to store a list of <color name / color / comment>. So I create a custom type, that is called ColorInfo. In my app I need to store multiple values of ColorInfo, I'd try and achieve that using an NSMutableArray or a database, but both are not easily synchronizable via the iCloud.
What ways to manage lists of data do you prefer in your iOS apps to meet the following two requirements?
You should be able to easily store the data persistently on the local phone.
You should be able to easily sync the data via the iCloud.
You want to use UIDocument its designed for local archiving and iCloud persistence.
Developer Doc
Do not use the key value storage. It is very.. weird.
I would make my own version of the key value storage by creating a local file and a remote file of the same name. To sync, you have to download the remote file and combine its contents with the local data. Write it to the file and upload the file.
Dropbox claims that during syncing only the portion of files that changes are transmitted back to main server, which is obviously a great functionality, but how do they perform changes to files stored in Amazon S3 cloud? So for example, lets say a 30 page document on user's desktop contains changes to only page 4. Dropbox now syncs the blocks representing the changes and what happens on the backend if they files that they store are in the cloud? Does that mean they have to download the 30 page document stored in S3 to their server, then perform replacement of blocks representing page 4, and then uploading back to the cloud? I doubt this would be the case because that would be somewhat inefficient. The other option I could think of is if Amazon S3 provides update of file stored in the cloud based on byte ranges, so for example, make a PUT request to file X from bytes 100-200 which will replace all the bytes from 100 to 200 with value of PUT request. So I was curious how companies that use other cloud services such as Amazon, implement this type of syncing.
Thanks
As S3 and similar storages don't offer filesystem capabilities, anything that pretends to store files and directories needs to emulate a file system. And when doing this files are often split to pages of certain size, where each page is stored in a separate file in the storage. This way the changed block requires uploading only one page (for example) and not the whole file. I should note, that with files like office documents this approach can be faulty if file size is changed - for example, if you insert a page at the beginning or delete a page, then the whole file will be changed and the complete file would need to be re-uploaded. We didn't analyze how Dropbox in particular does his job, and I just described the common scenario. There exist also different "patch algorithms", where a patch can be created locally (if Dropbox has an older local copy in the cache) and then applied to one or more blocks on the server.
There are several synchronizing tools which transfer deltas over the wire like rsync, rdiff, rdiff-backup, etc. For bi-directional synchronising with S3 there are paid services like s3rsync for example. For pure client-side synchronising, tools like zsync can be considered (which is what many people employ to roll-out app updates).
An alternative approach would be to tar-ball a directory, generate a delta file (using rdiff or xdelta3), and upload the delta file by using a timestamp as part of the key. In order to sync, all you need to do is to perform these 2 checks client-side:
You have all the delta files from S3. If not pull them and apply them to generate the latest backup state.
Your last backup state corresponds to your current directory. If not generate a new delta file and push to S3.
The concerning factor here would be the at least 100% additional space utilization, client-side. But this approach will help you revert changes if needed.
I'm building an application that needs to download web content for offline viewing on an iPad. At present I'm loading some web content from the web for test purposes and displaying this with a UIWebView. Implementing that was simple enough. Now I need to make some modifications to support offline content. Eventually that offline content would be downloaded in user selectable bundles.
As I see it I have a number of options but I may have missed some:
Pack content in a ZIP (or other archive) file and unpack the content when it is downloaded to the iPad.
Put the content in a SQLite database. This seems to require some 3rd party libs like FMDB.
Use Core Data. From what I understand this supports a number of storage formats including SQLite.
Use the filesystem and download each required file individually. OK, not really a bundle but maybe this is the best option?
Considerations/Questions:
What are the storage limitations and performance limitations for each of these methods? And is there an overall storage limit per iPad app?
If I'm going to have the user navigate through the downloaded content, what option is easier to code up?
It would seem like spinning up a local web server would be one of the most efficient ways to handle the runtime aspects of displaying the content. Are there any open source examples of this which load from a bundle like options 1-3?
The other side of this is the content creation and it seems like zipping up the content (option 1) is the simplest from this angle. The other options would appear to require creation of tools to support the content creator.
If you have the control over the content, I'd recommend a mix of both the first and the third option. If the content is created by you (like levels, etc) then simply store it on the server, download a zip and store it locally. Use CoreData to store an Index about the things you've downloaded, like the path of the folder it's stored in and it's name/origin/etc, but not the raw data. Databases are not thought to hold massive amounts of raw content, rather to hold structured data. And even if they can -- I'd not do so.
For your considerations:
Disk space is the only limit I know on the iPad. However, databases tend to get slower if they grow too large. If you barely scan though the data, use the file system directly -- may prove faster and cheaper.
The index in CoreData could store all relevant data. You will have very easy and very quick access. Opening a content will load it from the file system, which is quick, cheap and doesn't strain the index.
Why would you do so? Redirect your WebView to a file:// URL will have the same effect, won't it?
Should be answered by now.
If you don't have control then use the same as above but download each file separately, as suggested in option four. after unzipping both cases are basically the same.
Please get back if you have questions.
You could create a xml file for each bundle, containing the path to each file in the bundle, place it in a folder common to each bundle. When downloading, download and parse the xml first and download each ressource one by one. This will spare you the overhead of zipping and unzipping the content. Create a folder for each bundle locally and recreate the folder structure of the bundle there. This way the content will work online and offline without changes.
With a little effort, you could even keep track of file versions by including version numbers in the xml file for each ressource, so if your content has been partially updated only the files with changed version numbers have to be downloaded again.