Storing files in Memory - ios

I'm trying to save a file (for security reasons) to memory so I can access it via NSFileManager to pass it to different classes which are opening files with the NSFileManager method contentsAtPath:.
Is it possible to create a file at some special path and use it like a normal file stored in the filesystem (some kind of memory disk?).
I don't want to rely on the NSFileProtection...
Thanks in advance

The short answer is No, there is no ramdisk-like storage under iOS.
It looks, therefore, that you'll need to read the entire file from disk into memory (preferably as an Object) and change whatever methods you've got, that manipulate the file, to do so on the memory/object instead.

Related

How to access iCloud Documents files in an asynchronous manner

I am trying to add support for iCloud Documents in my existing app, but I am struggling badly with how to do that.
Apple seems to prefer that you use the UIDocument class for that. But UIDocument does not give direct access to the file in the file system, it expects to maintain a copy of the contents of the file in an NSData object instead. That is simply not doable in my case. All my current code and half of the 3rd party libraries that I use, work directly with the file on the file system, not with NSData. Rewriting all that code is simply not doable.
When not using the UIDocument class, Apple expects you to use the NSFileCoordinator to coordinate access to the file's contents. I am trying to do that with my code, but the methods on the NSFileCoordinator seem to expect that all reading and writing will be done in one synchronous sequence. All the methods of NSFileCoordinator take a block as argument, and expect all the reading/writing to be performed inside that block. When the block returns, you are not allowed to make any file access anymore, as far as I understand.
That is not doable in my case as well. Some of my code, and the 3rd party libraries, do the reading / writing in an asynchronous manner on background threads. I can identify the start and end of the period that the code needs access to the file contents, so if there was a separate requireAccess method, and separate relinquishAccess on the NSFileCoordinator, that would enable me to achieve the goal. But that does not seem to be the case.
It is unclear to me what the role of NSFilePresenter in this is. Some of the documentation, especially that of relinquishPresentedItemToReader() in NSFilePresenter seem to indicate that you can actually acquire / relinquish access separately:
If you want to be notified when the reader has completed its task,
pass your own block to the reader and use that block to reacquire the
file or URL for your own uses.
But it does not explain anywhere how to "reacquire" the file.
So the concrete question: I need to do the following steps in an asynchronous manner:
acquire access to the file, and obtain a file: URL for the file on the local file system
do multiple, asynchronous,
read/write operations on the file with normal file system
operations on that file: URL
relinquish access to the file
Does anybody know whether it is possible to do this, and how to do step 1 and step 3 ?

Storing CoreData to RackSpace

I am developing an app on xCode 5, iOS 7. I have some data stored in CoreData. My requirement is to upload that data to RackSpace. Whats the best way to do this?
Where can I find .sqlite file associated with CoreData?
The SQLite file is wherever you put it. There's no magic to it, you have to tell Core Data exactly where you want the file. You do this when you call addPersistentStoreWithType:configuration:URL:options:error:. The URL argument is the location of the SQLite file.
If you try and use the file directly, make sure that:
You shut down your Core Data stack completely before doing so, to make sure that all unsaved data has been flushed to disk. That means no managed objects, managed object contexts, or persistent store coordinators in memory anywhere.
Make sure to get the SQLite journal files. If your store file were named Foo.sqlite, they will be named Foo.sqlite-wal and Foo.sqlite-shm and will be located in the same directory. If you don't get these files, most or all of your data will be missing.
However simply uploading the file is not a good solution for syncing data. To sync data, you'd have to download a copy of the data, load that, and compare every object in the file with every object that's already on the phone. It's not impossible but it's definitely making things much more difficult than necessary. There are many options that can simplify the process, including full service providers like Parse, SDKs that let you use one of a variety of back ends like Ensembles.io, and others.

Solution For Monitoring and Maintaining App's Size on Disc

I'm building an app that makes extensive use of CoreData and a lot of my models have UIImage and NSData properties (for images and videos). Since it's not a great idea to store that data directly into CoreData, I built a file manager class that writes the files into different buckets in the documents directory depends on the context in which was created and media type.
My question now is how do I manage the documents directory? Is there a way to detect how much space the app has used up out of its total allocated space? Additionally, what is the best way to go about cleaning those directories; do I check every time a file is written or only on app launch, ect ect.
Is there a way to detect how much space the app has used up out of its total allocated space?
Apps don't have a limit on total allocated space, they're limited by the amount of space on the device. You can find out how much space you're using for these files by using NSFileManager to scan the directories. There are several methods that do this in different ways-- check out enumeratorAtPath:, for example. For each file, use a method like attributesOfItemAtPath:error: to get the file size.
Better would be to track the file sizes as you create and delete files. Keep a running total, stored in user defaults. When you create a new file, increase it by the amount of new data. When you remove a file, decrease the running total.
Additionally, what is the best way to go about cleaning those directories; do I check every time a file is written or only on app launch, ect ect.
If these files are local data that's inherently part of the associated Core Data object, the sensible approach is to delete a file when its Core Data object is deleted. The managed object needs the data file, so don't delete the file if you still use the object. That means there must be some way to link the two, but I'm assuming that's already true since you say that these files are used by managed objects somehow.
If the files are something like cached data that's easily re-created or re-downloaded, you should put them in the location returned by NSTemporaryDirectory(). Then iOS can delete them when it thinks the space is needed. You can also clear out old files whenever it seems appropriate, by scanning for older files or ones that haven't been used in a while (the details depend on exactly how you use the files).

Transformable images stored in CoreData - will it work with pre-seeded database?

If I use the "Transformable" attribute in Core Data to store images, it is my understanding that Core Data may or may not store it in the persistent store based on file size. Normally I wouldn't care where it stored the image, but for this app I need to ship it with a pre-seeded database in case an internet connection is not found when the app is first launched. So I basically want to take a snapshot (including images) of the database and have it load the first time the app is launched.
My question is, if Core Data decides for whatever reason to not use the persistent store, will the images still get loaded when I load the pre-seeded database? Or will it be broken because the image(s) were stored in some magic area that no longer exists when the user installs on their own device?
Making an attribute transformable has nothing to do with using external storage. The Store in External Record File option is available for both binary attributes and transformables, but is not required for either.
If you have an attribute that is transformable and uses external record files, you're correct that Core Data decides whether to actually use an external file based on its own undocumented logic (but probably by checking the size). Those external files get saved in a subdirectory of the one where the data store is located. If your data store is named Foo.sqlite, then in the same directory where that file is found is a directory named .Foo_SUPPORT/_EXTERNAL_DATA/. You can deal with this in a couple of ways:
Copy the entire directory where Foo.sqlite lives, including dot files. This is preferred, because the path to the external references directory is undocumented and (in theory) could change. You'll get the external references but you don't need to hard-code the directory name.
Copy the directory directly, since you know where it is. Probably a less good idea, for reasons described above.
Or if you prefer, just don't use external references. They're not required for any attribute, and if you like you can just have all of your data in a monolithic SQLite file.
You can just tell core data to use external storage for your images, and make it not having to figure it out when to use it and use it all the time. You can find the option to assign a property to use external storage on the core data inspector of your property.

In Memory INI File Writer

I have an MFC app which is wizard based. The App asks a user a variable number of questions which are then written to an INI file which is later encrypted when the user clicks Finish.
All the INI file parsers I have seen so far seen read or write to a physical file on Disk. I don't want to do this as the INI file contains confidential information. Instead I would like the INI file to be only based in memory and never written to disk in an un-encrypted form.
As the app allows users to go back and change answers, It occurred to me that I could use an in memory Database for this purpose but again I do not want anything written to Disk and don't want to ship a DB with my app if it can be avoided.
I have to use an INI file as it the file when un-encrypted will be processed by a 3rd party.
Any suggestions welcomed.
Thanks..
I have an IniFile C++ class which allows you to work with Ini files in memory:
http://www.lemonteam.com/downloads/inifile.h
It's a short, well documented single .h file. Sample usage:
IniFile if ( "myinifile.ini" );
if.SetString( "mykey", "myvalue" );
// Nothing gets actually written to disk until you call Flush(), Close() or the object is deleted
if.Flush();
if.Close();
You should be able to modify the Flush() method so that it applies some kind of encryption to the saved data.
Sounds like a good application for a memory-mapped file, since you can control when your in-memory view gets flushed back to the file on disk.
Why would you need to have it in an ini file format if it is never stored to disk?
Why not just keep it in memory as a data structure and use your normal ini file methods to write it to disk when you want to.
If you don't want to save into file, what is the point of using INI file then?
INI API is bascially a property bag or key value pair based on disk file.
If you don't want to use file, I suggest you use your own hash or dictionary data structure to store the key value parirs

Resources