Storing words for ios offline flashcard app - ios

I'm trying to build a flashcard app that requires words and definitions to be stored somewhere on the device. What is the correct/best way to store this information? I have read about ways to prepopulate Core Data but the solutions I've read seem like hacks. This seems like a basic feature needed by many apps so am I missing something here?

Core Data is the way to go here. There is nothing hacky about pre-populating a persistent store and including it in your app bundle.

Core Data seems like overkill for a flashcard app. I'd probably just save the contents to a plist. Is this content read-only, or do you need to update it at runtime?
If you need to updated it you could copy check for a plist in the documents directory at launch, and if it doesn't exist, copy it from the bundle into the documents directory. You can also use the same approach with a Core Data database, but unless you're familiar with Core Data the learning curve to learning it probably isn't worth it for something as simple as a flashcard app.

Related

Is it possible to use Core Data in a document-based application?

I'm working on an iOS app that will need to save data onto files. I chose to go for a Document Based app, precisely an app based on a UIDocumentBrowserViewController so that I can easily save and load files from the system's Files app.
Since the data I need to save/load on a file is quite complex: big hierarchy of different objects, with meta-data, image files, etc. I'm wondering what is the best technology to use going forward.
I came across NSFileWrapperand its ability to save different files as one. And I could definitely use that. But I also saw UIManagedDocument and the ability to use Core Data in my project while maybe saving the content of the Core Data database (I know it's not quite a database, but you know what I mean) into a file that I could write somewhere in the File App.
Is this a behavior I can expect?
To reformulate: I'm wondering if I can read/write files through a UIDocumentBrowserViewController, with data described by a UIManagedDocument that works with Core Data.
Thank you in advance. 🙂
As you have discovered, UIManagedDocument is there for your kind of application. And it does feature methods to write and read additional content like the metadata or image files you have, within the document package.
That being said, I have never used UIManagedDocument, and have never seen it used by others. A quick search of GitHub finds only this one project with two contributors who wrote a wrapper around it in 2013. Also, there does not seem to be any sample code from Apple, and the remark in the the writeAdditionalContent(_:to:originalContentsURL:) documentation that Additional content is not supported on iCloud leaves me a little concerned, but maybe it's a good sign that the Core Data team knows where to draw the line.
I have used the macOS counterpart of UIManagedDocument, NSPersistentDocument. It is in a similar situation of not being used very much, but with many more known technical issues. So a few years ago I switched to BSManagedDocument, which purportedly mimics UIManagedDocument to support Core Data in all its modern glory. I have been happy with BSManagedDocument.
In summary, if I was in your situation, yes I would give UIManagedDocument a try. But don't be surprised if you need to use a DTS support incident or two during your development.

Sync Core Data across Devices

Hey at the moment I'm learning Swift and started to create an App for that. Everything is fine and I think I know the basics now. In that App, I use CoreData to save my Data but I would like to Sync that across Devices
Is there a way with Icloud to do that, I found there is something called "Core Data Ensembles" But is there a better way, or should I use the IcloudKit, if I can do the same things in IcloudKit with the relations like in coreData.
I just found old posts about that, so maybe there is a better way to do this.
Thanks in advance
Such synchronization works without any libraries involved. The main trick here is to place SQL file (or whatever you use for storing data) into a special folder that is going to be synced, so-called ubiquity container, and specify path to it for your persistent store coordinator. Here you can check high-level description of how it works, and there are a lot of step-by-step tutorials about it, e.g. here.

Blob data in Ensembles

Im using a strategy where I'm saving images and pdfs as NSData in the respective managed objects where they belong. I'm having a problem syncing with Ensembles that the pdf doesn't always carry over from one device to another. Now I'm not sure if this is due to some flaws in my code or if it's not a good way of syncing chunks of data like this. Does anyone have experience of this?
I'm using Ensembles 2.2 syncing through CloudKit.
Ensembles should handle this fine. I use it for exactly this purpose, syncing image data including PDF.
I would look closer at the handling of the data. Is the value transformer working (if you are using one)? Is the device capable of unpacking and displaying the PDF data?
An alternative to syncing the PDF directly is transforming to a format like PNG before putting it in your store.
Transformable data type is really just binary under the covers with some additional metadata. Have you tested a simple lightweight migration on an existing store? I suspect the migration would work and would leave the existing data in the store.
If you are looking to get the existing binary data actually moved out of the SQLite file then you are looking at something a bit more involved.
A heavy migration will accomplish what you are looking for but if the stores are large it may take took long and potentially not provide enough feedback for a good user experience. I personally do not use heavy migrations, ever, on IOS but it will accomplish your goal.
An export/import will also work. I generally recommend export/import when a lightweight migration won't work. It involves a medium amount of code but in the end you own the code, understand the entire process and can tweak it to your exact needs.

Core Data for iOS Store in External Record File

First time asking a question on here, so please go easy if I don't provide enough info. Basically part of my iOS app allows users to take a picture which will be stored in a Core Data store. The attribute is a Transformable type, and I have created an NSManagedObject subclass which I simply use to set its image attribute to the new image provided by the user.
I know storing large files in Core Data is a bad idea, which is why I was excited when I saw the "Store in External Record File" option under the image attribute in the Core Data entity. However, my app performance says otherwise, taking several seconds on an iPhone 5 to load only a few images (which I know doesn't sound like much time, but considering how powerful the iPhone 5 is, older devices would likely take much longer with the same data).
I've looked around, and some people say that the Store in External Record File option is only applicable to the OS X environment, even though it is available in an iOS app. However, I also saw this under Apple's "What's New in iOS 5" doc (it's the next to last item under Core Data, near the end):
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 URL to a separate file that it manages for you.
So my question is, who's right? Is it true that Apple made a mistake in giving this option for iOS apps, and that it actually does nothing unless you're on the Mac, or does it actually do something and I'm not configuring it the right way, or is it doing what it's supposed to do and the performance is bad anyway?
I've seen some guides explaining how to store large files (like images) as files, and save the URL to them in the Core Data store instead, but since this is essentially what this new option is doing, or maybe should be doing, I'm not sure if following these guides would even help.
I'm really sorry if this has been asked before. Normally I'd be fine with figuring this out on my own, but Core Data is totally new to me, and I'm still not sure how I managed to squeak by the initial setup. Thank you for any help you can offer!
who's right ?
the iOS docset for the NSAttributeDescription class does mention the allowsExternalBinaryDataStorage and the setAllowsExternalBinaryDataStorage: methods so there is little chance that there is a mistake from Apple.
are you doing something wrong or is slow anyway ?
You said that
The attribute is a Transformable type
But Core Data has a Binary data type. Maybe only this one is linked to the external storage capability.
if that's not it, we don't have enough info here:
How many pictures do you store ?
What are their sizes ? 
Do you automatically fetch all the images ?
Also, the Apple doc states that:
Core Data heuristically decides on a per-value basis…
Did you use a migration or are you starting from scratch ?
You could have a look in your app's sandbox to see if your pictures are really saved outside of CoreData.
Hope this helps.
Good question!
Check this post:
Storing blobs in external location using built-in CoreData option
Apparently it should work. You should also try it in the simulator and inspect the application data folder to see if the folders are created as described (~/Library/Application Support/iPhone Simulator/... - you will figure out the rest of the path). Also you could inspect the sqlite file with the sqlite3 command to see if the binary data is in the database.
I haven't personally used this option as I would prefer to go for manually saving the images in a folder and store a reference to them in the database instead. This way it will be easier to create UIImage object from the file to be displayed, would have better control on what goes where and so on and so forth. Will take some extra labour though!
Hope that helps you out.

Best practice to deliver Core Data App with content?

Hey guys,
what would you say is the best way to ship initial data with an Core Data iOS App?
Is it maybe to once run the app, store the data and then insert the datafile in the build?
There must be a better way..
I have had good experiences with loading the data into a sqlite backing in the simulator, and then bundling the resulting sqlite file with the app.
Especially for bigger datasets, first-run filling of the database is not really an option.
I've been toying around with the same problem myself, recently; and what I opted for was to store the data in the app in some easily parsable (for me) format, and parse and incorporate it on first run.

Resources