I have an iOS app that makes use of an sqlite database. I need to persist several pictures I enable the user to take and save, what should be the most appropiate way to handle that? To store them into Documents as jpeg image files? To store them into the database? I've found some posts dealing with both that options, but I'd like to know which one is the most correct or the most recommended...
Thanks in advance
You can use either approach. Like neilco, I would lean more towards storing the images as files in your documents directory and saving paths to them in your database.
You can also store them as BLOBs in your database. If you do that, make sure to make the image BLOBs separate entities, and only load them when needed. That way you don't bog down reading of your "normal" database entities with image data.
I would be inclined to store the images in Documents and create a record in the database with the path to the image.
Related
I am working on an iOS app. Client side is written in Swift.
I want users to be able to store text and images in a local DB, and then transmit the DB records to a server.
I already implemented client-side data storage (but not for image files) using SQLite DB. I know that it is possible to store image files as BLOBs in SQLite, but is it wise to do so? What are your experiences? If SQLite is not the right DB for this use case, what would be better?
This StackOverflow answer discusses why saving an image in a database isn't the greatest idea.
I think the current best practice for saving images on iOS would be to save the image to documents or the photo album, and save the file path to the image in the DB. UIKit has UIImageWriteToSavedPhotosAlbum() which will save the image for you.
I'm looking into using UIDocument en NSFileWrapper to store 'projects' that contain quite a few large video files and some small text files. There are a few problems that I run into, and I'm starting to wonder if UIDocument is still the right strategy.
Performance
As far as I can tell, NSFileWrapper loads everything in memory. This can be a problem when working with large video files. I think it's possible to work around this by using custom save and load methods that forego the standard NSFileWrapper.
Metadata
I want to display a list of all the documents along with some metadata. This can for example include a preview image, number of recorded scenes, length of videos etc. The only way to fetch this data now is to open each document and retrieve it. Probably quite slow, especially with large documents.
Solutions?
I see two solutions now: ditch UIDocument altogether and go for a custom architecture, or use some kind of centralized metadata file. Drawbacks of the latter is that I have to manage metadata in two separate places and that I need to keep them in sync manually.
Is UIDocument still the way to go here, and if so: What could be a way to solve these problems?
Based on the comments the asker found a way to move forward as such:
drop UIDocument in favor of a Core Data solution. I now save all my
data using Core Data and manually manage the large files on the
filesystem. It works pretty well for me, and I'm glad I made the
switch. The only thing I had to give up was easy iCloud syncing. But
with files as large as these, that wasn't really feasible anyway. It
seems you can create your own file wrapper class to work around some
performance problems with large files.
I'm starting a new project (and very new to Core Data) and was curious about how to manage images within Core Data and an Asset Library. I've done some reading and am just unclear on how everything works together.
Is it possible for each Managed Object to have an "asset library" of images? ie. can the asset library be populated with Core Data data.
What is the best way to handle having a large array of images attached to a managed object?
If anyone can point me in a direction of an article/tutorial or provide further guidance, that would be greatly appreciated.
Thanks!
Yes Core Data can handle storing an image asset database as well as the images themselves. Core Data has an option that will let it store large binary objects as files, rather than in the sqlite database itself. Core Data would be effective for storing details about the images and for categorising them into albums, projects etc.. It would also be useful for searching on these attributes.
Typically you would not attach a large array of images to a managed object. An image would be represented by a managed object and one of the attributes of the managed object would be the image (which Core Data might decide to store as a file somewhere).
I think you might be out of luck if you want to use iCloud for replicating this image library because I don't think Core Data will sync these externally stored image files.
https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS5.html
Managed objects support two significant new features: ordered relationships, and external storage for attribute values. If you specify that the value of a managed object attribute may be stored as an external record, Core Data heuristically decides on a per-value basis whether it should save the data directly in the database or store a URI to a separate file that it manages for you.
if you store your images in image assets and Managed Object have the "asset library" of images, then you will have the problem on updating the images.
and even if you do not want to ever update the images then why to store it in core data ?
solution is : have the images in image assets and also store the binary data of images in core data in launching the app.
by checking a date of modified coming from a web server you can check whether to update the images or not.
this link is helping you to import anything to core data easily done.
I have a working drawing app that uses a Core Data database to store drawings. It allows the user to creates multiple documents but I'm using only one database with multiple drawing entities.
Now I'm making some big improvements in the app and I'm trying to do things right. I think the way to do this kind of app is using UIManagedDocument.
My guess is that I should use one UIManagedDocument for every drawing so they'll be saved as independent documents on disk, but I haven't been able to find any examples of this anywhere.
If that's the correct approach (which I'm not sure), I need to know:
How do I retrieve a list of all the documents (drawings) created?
How do I save a preview image of the drawing? Do I save it inside the UIManagedDocument or somewhere else?
Thanks.
Maybe you can use this article as starting point:
http://www.informit.com/articles/article.aspx?p=1842295&seqNum=10
The main idea of UIManagedDocument is that each document has it's own managedObjectContext that is persisted in the document's bundle.
How do I retrieve a list of all the documents (drawings) created?
To display a list of local drawings you could just display your storage directory contents in a collection view.
When dealing with documents stored in iCloud, Apple suggests to use NSMetadataQuery.
How do I save a preview image of the drawing? Do I save it inside the
UIManagedDocument or somewhere else?
To store additional information (like your doc preview) in the bundle, UIManagedDocument provides writeAdditionalContent:toURL:originalContentsURL:error:
Please also keep in mind, that NSDocument/UIDocument are controller classes (and not model classes).
I'm developing an app which needs to show some logos. These logos are just 8kb PNG files, and I'm just going to handle a little amount of them (10-20 at most). However, these are downloaded from the Internet because they might change. So, what I'm trying to achieve is, making the app to download them (done), storing them into the file system, and only downloading again whenever they change (might be months).
Everyone seems to use Core Data, which in my opinion is something designed for bigger and more complex things, because my files will always have the same name plus don't have relations between them.
Is the file system the way to go? Any good tutorial?
Yes, the file system is probably your best option for this. You say that you've already implemented the downloading. How have you done so? With NSURLConnection? If so, then at some point, you have an NSData object. This has a couple of write... methods you can use to save the data to a file on the filesystem. Be sure to save the files in the right place, as your app is sandboxed and you can't write anywhere you like.
The advantage Core Data brings is efficiency. Using NSFetchedResultsController to display your logos in a tableview gets you optimized object loading and memory management. It will automatically load only the items which can be displayed on one screen, and as the user flicks through the table it will handle releasing items which move offscreen. Implementing that on your own is not a simple task.
If you want to build and display your data without Core Data, you'll probably want to use NSKeyValueCoder, which will allow you to easily write an array or dictionary of objects (including nested arrays, dictionaries, and images).