Encryption with Core Data in background - ios

This question is different from questions here, because of the app being mostly in the background.
It is a requirement for our application that we keep the data store encrypted.
Our current implementation is using SQLite using SQLCipher. The plan is to move to Core Data.
I'm looking for a solution to keep the data encrypted, while still accessible in the background and is not restricting in terms of queries-NSPredicates and migration (schema change).
Below are all the options I've been looking into:
NSFileProtectionComplete - will not allow file access in the background
encrypted-core-data - This library does appear to be kept up-to-date. However, I've had second thoughts about using it in production after seeing the list of known issues. Has anyone used this recently?
NSIncrementalStore - This was the way that Apple engineers recommended that we follow. encrypted-core-data is using this method.
Transformable Attributes in core data - is this solution scalable for larger data sets?
Does anyone have a recommendation that meets all of the criteria and can be used in production apps?

I ran some proof-of-concept apps using each of the above options. I ran numbers and bench-maked it against our existing solution (SQLCipher).
Looks like using core data with incremental store (encrypted-core-data) came out to be the best.
After analyzing runtime performance times for read, write and search on DB with small and large sizes, encrypted-core-data turned out to be the most efficient and simpler to implement.

Related

iOS optimal performance persistent data solution?

I am building a healthKit based app and am wondering how to best save healthKit data persistently.
My current approach is to get the data and save it as attributes of a custom class object and then save it in core data as NSData.
In terms of performance is Realm faster than CoreData?
According to http://qiita.com/moriyaman/items/1a2916f4c2b79e934370 CoreData is apparently slower than FMDB which is slower than Realm. Can someone confirm if this is true even after taking into account faults and indexes?
Disclaimer: I work at Realm
The question of which persistence product will perform best among the solutions you mentioned is highly dependent on the type/amount/frequency of your data. Since Core Data and FMDB are layers over SQLite, they can't be faster than SQLite by design, but they provide enough convenience to be worthwhile to many users. On the other hand, Realm isn't based on SQLite, but rather its own custom database engine that was designed specifically for modern smartphones. It was designed to strike a better balance between powerful features, simple API without adding a large performance hit.
You can see public benchmarks comparing Realm/SQLite/Core Data/FMDB in Realm's launch blog post here: http://realm.io/news/introducing-realm#fast
Finally, your approach of serializing HealthKit information into NSData using something like NSCoding is going to be terribly inefficient. No matter the persistence solution you choose, you'll be better served by using the serialization built in to those products rather than storing an already serialized data blob.
As I commented to #jpsim, it is difficult to simply compare the performance of Core Data to lower-level frameworks like FMDB, or differently-abstracted frameworks like Realm. Which approach you choose will dramatically impact how you build your program, which will tend to shuffle the performance problems around to different places.
Core Data and SQLite solve very different problems. SQLite is a relational database. Core Data is an object persistence engine. I'm not an expert on Realm, but it seems to be trying to strike a balance between those two approaches with more low-level control than Core Data affords, but a closer tie-in to the object model than SQLite. The fact that Realm (at least in my impressions of it) gives you more low-level control opens up opportunities for you to optimize things, or to mess things up IMO. That's neither good nor bad, it just makes it hard to apples-to-apples compare them, and particularly makes generic "performance benchmarks" problematic. The question isn't whether it's possible for someone to write faster code using engine A vs. engine B. The question is whether you will likely write acceptably performant code in each engine, while avoiding bugs, and minimizing development time.
In general, I believe HealthKit data is supposed to be stored in HealthKit in order to protect privacy. You should be careful about storing this data in your own storage anyway. Be particularly aware of the guidelines about iCloud:
Apps using the HealthKit framework that store users’ health information in iCloud will be rejected
I don't know how this will impact documents that you store and are then backed-up to iCloud. Just leaving the data in HealthKit is the best way to not have to worry about such problems.
In any case, though, performance is just one axis to consider. You didn't indicate anything to suggest that you have very special performance problems (for example, that you're handling tens of thousands of records, or real-time data, or something like that). So I would focus first on what tool meet your general needs best, and then do some basic experiments to make sure the performance is reasonable, and then optimize as you find issues.

Changing existing Core Data Image Store from Transformable to Binary Data/Allows External Storage

I am about to undertake the daunting project of converting my live (i.e. already on the app store for a number of years) app from Transformable to Binary Data store for images in Core Data.
I have many users with very large databases that store lots of images. This has really slowed down the Backup/Restore process, and probably caused some other behind-the-scenes issues as well. I didn't know any better when I set it up this way years ago.
How can I undergo this process so as not to lose even one of my customer's images? If it were just me and my own data, I'm sure I could get things working. But I want to be sure to do this properly, step by step, and I knew that this community could be a big help in that area. I really don't know where to start for the existing images.
Basically, I am looking for 1) steps to take, so as not to miss a beat. and 2) general advice, warnings, etc. in this process. I really need a clean migration when this version goes live.
Thanks in advance to anyone who can help.
One piece of advice: don't use "Allows External Storage", especially if you plan to use iCloud syncing with Core Data in the future. Reference: http://www.objc.io/issue-10/icloud-core-data.html
Instead, you might want to consider moving the images into their own files, and saving the URL to those files inside your database instead. You will have to work out how best to do the migration: lightweight migration is probably not an option if you go down this route.
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.

When should I use the various storage mechanisms in iOS?

I thought this would be covered already, but my search returned nothing of relevance.
I am aware that there is NSUserDefaults, Core Data, object archiving, raw SQLite, plists, and of course, storage by web servers. What is unclear and somewhat hazy to a beginner is when to employ each of these various tools.
The usages of web servers vs Core Data is obvious, but what about NSUserDefaults vs plists?
Core Data vs object archiving? A simple breakdown of use cases would really help me understand why there are so many options for storage in iOS.
I try to write a quick and simple list of common use cases, because as #rmaddy says this answer could fill a book chapter:
NSUserDefaults: stores simple user preferences, nothing too complex or secure. If your app has a setting page with a few switches, you could save the data here.
Keychain (see SSKeychain for a great wrapper): used to store sensitive data, like credentials.
PLists: used to store larger structured data (but not huge): it is a really flexible format and can be used in a great number of scenarios. Some examples are:
User generated content storage: a simple list of Geopoint that will be shown by a map or list.
Provide simple initial data to your app: in this case the plist will be included in the NSBundle, instead of being generated by user and filled by user data.
Separate the data needed for a
particular module of your application from other data. For example,
the data needed to build a step-by-step startup tutorial, where each step is similar to the others but just needs different data. Hard-coding this data would easily fill your code, so you could be a better developer and use plists to store the data and read from them instead.
You are writing a library or framework that could be configured in some
way by the developer that uses it.
Object archiving could be useful to serialize more complex objects, maybe full of binary data, that can't (or that you don't want to) be mapped on simpler structures like plists.
Core Data is powerful, can be backed by different persistent stores (SQLite is just one of them, but you can also choose XML files or you can even write your own format!), and gives relationships between elements. It is complex and provides many features useful for the development, like KVO and contexts. You should use it for large data sets of many correlated records, that could be user generated or provided by a server.
Raw SQLite is useful when you need really, really fast access to a relational
data source (Core Data introduces some overhead), or if you need to support the same SQLite format across multiple platforms (you should never mess with CoreData inner SQLite: it uses its own format, so you can't just "import" an existing SQLite in CoreData). For example, for a project I worked for, a webservice provided me some large SQLite instead of jsons or xmls: some of this SQLite were imported to CoreData (operation that could take a while, depending on the source size), because I needed all the features of it, while other SQLites were read directly for a really fast access.
Webserver storage well it should be obvious: if you need to store data to a server it is because the device shouldn't be the only owner of that data. But if you just need to synchronize the same App across different iOS devices (or even with a Mac-ported version of the App) you could also look at iCloud storage, obviously.

What type of data store should I use for my ios app?

I am pretty new to ios and using servers so forgive me.
I am building an ios app for research. I need to monitor things that the user does and then push it up to a server for analysis (yes, with user and IRB permission). On the client's side I need to keep quite a bit of data that won't really change except in the case of pulling an updated version from the server, and then a minimal amount of user-specific data. Most of the data I will collect needs to be pushed to a server for analysis and then can be deleted from the client side.
I am struggling to figure out what kind of data store I need to use, especially since I am not quite sure how the pushing and pulling from the server process works yet. Does it make sense to use Core Data? XML? SQLite? I like the Core Data idea, but I am not sure what kind of problems I will run into when I need to send large amounts of data to it and from it from the server. I imagine I might need to send data in a different form than it is probably stored in on either end - so what kind of overhead am I likely to run into in the process of converting that data? Is there a good format to save stuff in that would work well for me on both ends AND for sending the data?
As you can probably tell, I could use some advice. Thanks!
Core Data is probably the way to go.
Either Core Data or SQLite is likely to be great for this sort of app. Core Data actually uses SQLite behind the scenes. But Core Data has some advantages over SQLite and really is the preferred iOS database technology.
Regarding your performance concerns, I wouldn't worry about it. Core Data (or SQLite) is plenty fast enough. The bandwidth to the server will be the gating factor, so you should be fine there.
It sounds like your data structure is likely to be rich enough or large enough that I wouldn't contemplate other approaches (plists, NSUserDefaults, other file formats, etc.).

XCode : reasons for not using Core Data?

I'm a new iPhone dev and I integrated a team of iOS developper, in the domain of education. First, I thank you for your help.
Here is my question : The lead developper told that for the project (iOS 5), they will not use Core Data to deal with the database of the app, but they will use their own SQLite libraries.
I have been told by the lead dev that Core Data will not fit in that project, because of the data they are dealing with... No more details
Since Core Data uses SQLite, (and so will the library they created), do you have any ideas why Core Data could be a problem (in general)
I really thank you if you have any clue.
EDIT :
I've just learnt that the lead is creating an sqlite database and we are going to use it in the app. And the fields contains a lot of html (a lot of special characters like \ or & or <), and we are going to display it in some UIWebViews. Is he right when he says that those special characters can turn wrong with core data ?
The only reason I can think of is cross-platform portability. If you use a manually-generated schema, and perhaps even provide common library code, then that database schema/library can be used on non-Apple platforms.
It's hard to guess at other people's reasons but.... The purpose of Core Data is object persistence. The fact that it can use a database as a storage mechanism is an implementation detail. For problems that are specifically object-oriented in nature, it works very well.
If you are dealing with a problem that is more suited to solutions that are about rows, columns, and tables, it isn't necessarily a good fit.
I like using objects and have a lot of experience with Object/Relational mapping in other systems, so I tend to be pro-Core Data. People with a database-only background probably have a different view.

Resources