I need to take UIImages that are being fed in a video stream, all of this is on the iPad with limited memory, save them to the file system quickly while the stream is still feeding, then process them after a "recording" session. I need to save the UIImages coming in quickly to avoid interrupting the feed which will still be viewing on the iPad. I'm thinking of saving each frame to a separate file then afterward reading these files sequentially and combining them into a .mov file.
The tricks are: how to save the UIImages quickly, maybe raw data, then when processing the movie, append each UIImage file to it to make a seamless movie file? I will need to do some processing of each frame like scaling and transforms before appending.
Any advice would be greatly appreciated.
Depending on how big your images are, you could let the new coredata "use external storage" attribute do this for you.
Here is the explanation what it does copied from another answer of mine:
Since we are on IO5 now, you no longer need to write images to disk neccessarily.
You are now able to set "allow external storage" on an coredata binary attribute. According to apples release notes it means the following:
Small data values like image thumbnails may be efficiently stored in a
database, but large photos or other media are best handled directly by
the file system. You can now specify that the value of a managed
object attribute may be stored as an external record - see
setAllowsExternalBinaryDataStorage: When enabled, Core Data
heuristically decides on a per-value basis if it should save the data
directly in the database or store a URI to a separate file which it
manages for you. You cannot query based on the contents of a binary
data property if you use this option.
There are several advantages using this approach.
First coredate is saving the files at least as fast as you could when writing to the file system. But if there are any small images which apply to the conditions described above, it'll be much faster because they will be saved directly in the coredata sqlite file.
Further with iOS 5 it is very easy possible to work on separate managed contexts and perform changes on a child context in background. If finished successfully you can merge this child context into your main managed object context and do the processing you need.
[child performBlock:^{
[childsave:&parentError]; //do this in background on child context
}];
There is a NSPrivateQueueConcurrentType for creating "child-moc" - see [apple documentation][1]
And at least you can work with coredata objects which enables you to cache, limit and optimize further processing after your download completed
[1]: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385 for more info
Related
Over many different Objective-C iOS coding projects I have frequently come across the issue of having data be accessible after I initially got it.
For example, currently I am reading from the stackoverflow API. I do this with a session and get a dictionary back (my JSON response).
But outside the scope of the session, the dictionary is unavailable! I can't copy the contents to a different dictionary that I've defined globally, or anything. It's like it disappears outside of the session.
So I am wondering, what's the best way to save this data that I want to use? From what I've been reading it seems like NSUserDefaults or maybe creating a plist file, although admittedly I've been having trouble with both options. If there is a method that is best for this then I can concentrate on that.
Thank you!
It depends on how persistent you want to be.
If you save this dictionary into a global variable, it is stored in the part of device's RAM that is reserved for the running app. When the app stops running (gets killed by OS or removed by the user) or if your device reboots - this memory is lost.
If you save this dictionary onto the device's flash memory drive (and its file system) - it will live past restarts/reboots.
Usually people combine the approaches: when you get the data from the network, you keep it in a global variable, and save it to the file system. After the app restart you try to load the data from the file system. The reason for not using the FS all the time is that it is much slower than RAM access. I guess I'm describing caching.
Note that you can implement manual caching (using plain data or text files, NSUserDefaults, Core Data or other libraries), but also you can utilize a builtin HTTP cache - NSURLCache. If you create a session with NSURLSession.sharedSession it will use the default NSURLCache and respect a caching policy dictated by the server side.
For more control and full offline support I'd recommend to implement caching manually. See this about reading and writing plists and writeToFile:atomically:.
What approach do you use to write critical app files like settings, configuration files, user files in WinRT, or in general?
To illustrate my concern - in my app I am saving the list of user selected data sources as a JSON file. In case the user updates the list and saves it, I just overwrite the current file with the new JSON serialized list. But if the app were killed from the task manager or the computer lost power in that very moment when the file is being written, it would stay in an inconsistent state and would probably cause the app not to launch or the user would definitely lose data.
I considered writing into a different file and then swap them when finished. Is this solution the best one possible?
I have a program that generates information from the contents of files, however, I believe it would be more efficient if I were able to do this as the files are being written; rather than having to then read the contents back after some delay, since I can simply generate the data as the file is writing to disk.
What method(s) are available for an application to hook into the file-write process, i.e- to process the data stream as it's being written to disk? Also, which of these (if any) are allowable for app store apps?
I've been considering using a Spotlight Importer, however this still involves reading the contents of a file after they've been written, in which case I'm relying on the file still being in the RAM cache to reduce disk access.
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 in the process of porting an application originally in java to cocoa, but I'm rewriting it to make it much better, since I prefer cocoa a lot anyway.
One of the problems I had in the application, was that when you uploaded images to it, I had the images created, (as say an NSImage object) and then I just had them sitting in memory, the more I uploaded the more memory they took up, and I ended up running out of memory.
My question is this: if I am going to have users upload images to this application in cocoa, how should I go about storing them? I don't just want to copy the file paths, because I want what is saved to contain the images, etc. Is there any way to upload an image and copy it into a different place only for my application? Then load that image with the new path name as needed?
Only I would like it all to be consolidated. I'm going to implement saving by archiving one "master" object into an NSData*- so I'd like the images to be saved with that.
Is there a temporary location maybe where I could write the images to disk for my application, and then when I saved, they would all be archived into a single file? Also, how do I do this? Thanks.
If you only want to store the images temporarily, you can store the images in the temporary folder that you get by calling NSTemporaryDirectory(). You would then be able to load the images only when you need to display them.
If you want to save the images with your document then you should investigate using a package format for your document, so that the document is actually a folder containing your images and your archived data file. You can create a file wrapper containing all the files for your document bundle using the various methods of NSFileWrapper and then you would implement the -fileWrapperOfType:error: method of NSDocument in order to handle saving.
This would allow you to store the images unaltered and then lazily load them from the document bundle when required.