I am trying to build an app for my website. I was under the impression that all I had to do was get and put json from the server to my phone. But then today I came across Core Data ( I am new to iOS).
So my question is, that to make a faster iOS app, is it a normal practice to fetch json data and save it as core data? Would apps like Facebook, Twitter follow this approach? or is just fetching and parsing json is a normal practice, and core data is not needed.
I am sorry if the question is dumb.
It is normal to retrieve data from a server (XML or JSON) and keep it in memory, if the memory foot print is reasonable. If you are talking about hundreds upon thousands of rows from a database, then persistent storage, with a dedicated data model(s) is probably the best choice; you can read it when needed.
If your needs are such that a complex data model is needed, one-to-many and/or many-to-many relationships, then consider Core Data (or SQLite directly).
You define your needs first, then try to define the data model that fits your needs (custom objects or maybe just a few instances of NSDictionary), then decide how that data needs to persist and how you plan on interacting with that data.
A few starting points:
Core Data Overview - Shoud help you decide if you should use it
RestKit - Just a suggestion
Tutorial on Data Persistence
Good luck.
I remember facing this anomaly not so long ago.
As already pointed out in some of the comments, it depends on your needs.
Not all data are eligible to be saved in core data after retrieving it from the web side. You might have integrity issues with that. To do the checks for large chunks of data might have even severe overheads. But if you feel that certain data are not likely to change very often then you can employ this technique for some portions.
If you decide to stick with Request/Fetch data, be sure you process the requests using NSOperation, GCD or NSThread, in order to avoid UI freezes.
Although, they are used for same purpose, they all have advantages and disadvantage, plz check out this topic on NSOperation vs Grand Central Dispatch
I hope this helps.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I would like to develop a stock/item inventory app as I progress through learning swift. It would basically be something that has, Item Name, Quantity, and Location.
eg.
Lightbulbs, 25, Work Van
Switches, 6, Warehouse
When the user inputs this data and presses a button, whats the best method of storing this data and retrieving it later. I know I could append this to an array and display the array, but what if the app closes?
Should I be looking at learning database storage? Can I save data to the phone?
whats the best method of storing this data and retrieving it later.
The best method will depend on a bunch of factors, like:
How many records do you want to save?
Do you need to sync this data with a server?
How much does performance matter?
How much do you know about storing data using Swift and iOS?
How likely is it that the data you want to save will change?
The answers to all of those questions are likely to change over time, as you learn more and make more progress on the app and perhaps come to understand the users' needs more. So the best method for saving data is to build something that will let you easily change or even replace the data storage system without requiring changes through the rest of the app.
In other words, you need to define an interface for your data storage needs. The interface is like a fence, with the actual data storage on one side, and the rest of the app (user interface, networking, etc.) on the other.
Having a clear interface to your data storage system will let you get your app up and running quickly with the simplest data storage system that could possibly work. You can store your data as an array of dictionaries, for example, write it all out to a property list using the Array method write(to:atomically:), and read it back using init(contentsOf:). So far, you've only described a need for a single kind of record, with each record having only a few fields. Storing the data in an array and writing it to a property list will work fine for hundreds, maybe thousands of entries; you'll likely have you rethink your user interface before you have a real need to rewrite your data storage system, because nobody likes to scroll through a list of hundreds of items.
As your app evolves and you discover that you don't want to keep all the data into memory at once, or you'd like to ship some data with the app and keep that separate from the data the user enters, or you'd like to speed up your data storage, you can write a new data storage system that conforms to the same interface. Then you can swap the new system in without affecting the rest of the app. So you can switch up to using something fancy like Core Data, or you can implement server-based storage, without having to rewrite big chunks of your app.
Creating a clear interface for your data storage system will also make it easy to write a set of unit tests that ensure that your data storage system does exactly what it's supposed to do and doesn't break. And having a set of unit tests will make it easy to ensure that a future version of your data storage system is as correct as the one it replaces.
Some others here have suggested using Core Data. Core Data is great, but using it is a lot more complicated than just reading your data from a file and writing it back when you're done. The difference between using an array to store your data and using Core Data to do it is very like the difference between a text file and a relational database. Core Data is an object graph manager: it can store many of different types of objects and the relationships between them, and it can store many thousands of all those objects and access them very quickly. When you start to keep track of images of the items in the inventory, the suppliers each of the items comes from, the customers who buy the items, the prices the items are bought and sold for, etc., Core Data will really simplify the task of managing all that data. But trying to learn and use Core Data now, while your needs are very simple, and while you're also trying to learn a new language, will slow you way down without any real benefit. Remember the KISS principle and start simple, but in a way that makes it easy to evolve.
If the data you want to store is very little and not sensitive, you can use UserDefaults
For example, user's name, their age etc.
For Large amounts of data you should use Core Data, its a good and an easy way to manage your objects. For example, you have 1000 items, each with a property, you can basically use core data for that. It is pretty straightforward as how to create Managed Objects, store them and how to later retrieve them using queries.
Basically when you configure your project with core data, project creates an sqlite file attached to your project.
There are many tutorials on how to get started with Core Data, if you have an average experience with iOS, it will be a piece of cake for ya.
Here's a nice tutorial that will help you setup core data in your project:
https://www.raywenderlich.com/173972/getting-started-with-core-data-tutorial-2
You can use either of the methods below depending on your exact requirement.
Core data: You can find a tutorial here.
Using a SQLite DB: You can find a tutorial here.
If it is simple and does not require to store a lot of information, then you can even use the file system to store data. Even PLists are possible.
For a single user who just logs in then you can store it in UserDefaults. But if you have to manage a list of users then use Core Data.
There is a huge difference between these two. SQLite is a database itself like we have MS SQL Server.
However CoreData is an ORM (Object Relational Model) which creates a layer between the database and the UI. It speeds-up the process of interaction as we dont have to write queries, just work with the ORM and let ORM handles the backend. For save or retrieval of large data, I recommend to use Core Data because of its abilities to handle the less processing speed of device.
As a result:
SQLite:
Have Data Constrains feature.
Operates on data, stored on disk.
Can Drop table and Edit data without loading them in memory.
Slow as compared to core data.
You can use SQL for complex data structure
Core Data:
Don't have Data Constraints,if required need to implement by business
logic.
Operates on in memory.(data needs to be loaded from disk to memory)
Need to load entire data if we need to drop table or update.
Fast in terms of record creation.(saving them may be time consuming)
No sql for this. Just load data to array and use in that array.
In my opinion; IF you need several data which settings of your app, or user authentication info or similar works use CoreData
If you have big data to storage, you need to select one of many data records use SQLLite.
Hope It helps.
A few weeks ago, I decided to learn Core Data for my new project and apply it to my entire model. There was a steep learning curve, but eventually I got familiar with the stack and I'm now rather comfortable with at least the basic concepts and the few common pitfalls such as thread concurrency.
I have to say, the first few weeks after getting comfortable where pretty amazing. NSFetchedResultsController give you a good way to communicate between my model and my controllers. However the more I use Core Data, the more annoying it gets.
As a concrete example, my app fetches a few pieces of data from my server (the posts) which appear in a feed. Each post has an owner, of class User, which I also fetch from the server. Now, Core Data has been great for managing the realtionship between a post and a user. The relationship is updated automatically and getting the post's origin is as simple as calling post.owner. However, there are also inconveniences:
1.Core Data forces objects to the disk that I do not want forced to the disk. This is probably the main issue. With the posts, I do not want them to be forced to disk, and would rather make calls to the server again. Why? Because the more posts I store persistently, the more housekeeping there is to do. A post can be edited, deleted, flagged, etc... and keeping those posts locally means having to plan updates.
2.Having to constantly worry about concurrency of contexts, objects and the likes. I wrote an object factory that always returns objects on the right thread and the right context, but even then bugs occur here and there, which quickly becomes frustrating.
3.Decreased performance. Perhaps the least important one at this point, going from cached objects to Core Data has taken a (barely noticeable) toll on the performance of my application (most notably the feed).
So what are your recommendations regarding Core Data? Would you suggest a different approach to Core Data?
I was thinking of a hybrid caching + Core Data where I store the information I will actually use many times (such as users) persistently and then use the RAM for things like posts, or simply creating posts without an NSManagedContext. Input welcome!
Core Data forces objects to the disk that I do not want forced to the disk.
It does no such thing. If you don't want to save your Post objects to the persistent store, don't put them in Core Data and don't make them managed objects. Your User object can have a posts property even if the Post object is not managed by Core Data. Managed objects can have properties of any type, not only to other managed objects.
Having to constantly worry about concurrency of contexts, objects and the likes.
Concurrency is complex no matter how you model your data. It's a fundamentally complex problem. You're encountering it with Core Data because you're using Core Data. If you use something else, you'll deal with it there.
Decreased performance.
"Product" menu --> "Analyze" and run Instruments to find out why. There's no reason this should happen, and you have the tools to discover what's actually going on.
I'm trying to write a iOS note taking app that is blazingly fast for a large number of notes and that syncs without ever blocking the UI. (Don't worry, it's just a learning project, I know there are a billion note apps for iOS). I have decided to use Core Data (mostly because of the excellent posts by Brent Simmons about Vesper). I know UIManagedDocument can do async reads and writes and has a lot of functionality built in, so I'm wondering if there is any information on which would be faster for a fairly simple notes app. I can't really find a lot of information about people using UIManagedDocuments for anything other than a centralized, basically singleton, persistent store. Is it suitable for 1000s of documents? Would it be faster or slower than just a database of NSManagedObjects? It seems like most information I can find about Core Data is oriented towards people using NSManagedObject, so any information about UIManagedDocuments being used in production apps would be really helpful. At this point, the only thing I can think of is to just write the whole app both ways, load 10,000 notes into it, and see what happens.
Update
To clarify, I'm not learning iOS development and Objective-C, the "learning project" mostly means that I've never used Core Data and would like to learn how to write a really performant Core Data application.
UIManagedDocument is designed/intended for document based applications. One UIManagedDocument instance per document. If you are not building a document based application then you should not be using UIManagedDocument.
Everything that people like about UIManagedDocument can be accomplished with very little effort using the Core Data stack directly. UIManagedDocument abstracts you away from what your persistence layer is doing. Something you really do not want.
If you want a high performance Core Data application you do not want to be using UIManagedDocument. You will run into issues with it. It will do things at random times and cause performance issues.
You are far, far, better off learning the framework properly.
In the case of Vesper, those are not documents; they are too small. Think of documents as Word files, or Excel files. Large complicated data structures that are 100% isolated from each other.
Also, whether you use a UIManagedDocument or not, you will be using NSManagedObject instances. NSManagedObject, NSManagedObjectContext, NSPersistentStoreCoordinator are all foundational objects in Core Data. UIManagedDocument is just an abstraction layer on top.
Finally, Core Data is not a database. Thinking of it that way will get you into a jam. Core Data is an object model that can persist to disk and one of the persistence formats happens to be SQLite.
Update (Running Into Problems)
UIManagedDocument is an abstraction on top of Core Data. To use UIManagedDocument you actually need to learn more about Core Data than if you just used the primary Core Data stack.
UIManagedDocument uses a parent/child context internally. Don't understand that yet? See the point above. What it also means is that your requests for it to save are "taken under advisement" as opposed to being saved right then and there. This can lead to unexpected results if you don't understand the point of it or don't want it to save when it feels like it.
UIManagedDocument uses asynchronous saves and at most you can request that it save. Doesn't mean it is going to save now, nor does it mean you can easily stop and wait for the save to complete. You need to trust that it will complete it. In addition, it may decide to save at an inopportune moment.
When you start looking for performance gains with Core Data you tend to want to build the stack in a very specific way to maximize the benefit to your application. That is application dependent and with the abstracts in UIManagedDocument you get limited very quickly.
Even in a situation where I was building a document based application I would still not use UIManagedDocument. Just to much behind the curtain.
Performance is likely to come down to how the rest of your code is implemented, and not necessarily the difference between a UIManagedDocument or a NSManagedObject.
Think of UIManagedDocument as a specific niche implementation of CoreData, that already has the parts of CoreData you want baked into it's structure to save you (the developer) a little bit of time writing code. It's been purpose built for handling UIDocuments, and multi-threading.
Under the hood, it's likely that UIManagedDocument is using CoreData as well as you would (assuming you know what you're doing), but it's theoretically possible you could cut some corners by knowing the exact and inane details of your implementation.
If you're new to CoreData, or GCD and NSOperationQueue, then you'll likely save a ton of developer time by leveraging UIManagedDocument instead of rolling your own.
A very apt analogy would be to using a NSFetchedResultsController to run your UITableView, rather then rolling your own CoreData and UITableView implementation.
If you're new to objective-C, I'd recommend you bang out something functional with UIManagedDocument at first. Later you get lost in the weeds of dispatch_asynch() and NSFetchRequest, and pick up a few milliseconds of performance here and there.
Cheers!
Just store a plain text file on the disk for each note.
Keep a separate database (using sqlite or perhaps just -[NSDictionary writeToFile:atomically]) to store metadata, such as the last user modification date and the last server sync date for each note.
Periodically talk to the server, asking it for a list of stuff that has changed since the last time you did a sync, and sending any data on your end that has changed in the same time period.
This should be perfectly fast as long as you have less than a million note files. Do all network and filesystem operations on an NSOperationQueue.
I've developed quite a few local apps, however this is the first time I'm introducing networking (more specifically posting to, and reading from a database). I am receiving back a JSON object from the database but I am currently using arrays and dictionaries. The objects do have relationships to each other, and I was wondering whether CoreData is the way to go. If so, do I just replicate part of the database I wish to be made viewable in the app and store it in my CoreData model? Are there any tutorials out there for this?
Also, just as a side note, I've also included Facebook integration with which I download the users list of friends. Would CoreData be good for storing this kind of information too? Or would I be better sticking with dictionaries?
Thanks in advance.
Based on my experience (other could say different things) Core Data is the right choice but its adoption could depend on the time you could dedicate to it. At first could be very complicated but I think you could take advantage applying the knowledge in some other projects.
Out of there there are some tutorials or books on Core Data.
First I suggest to read about core-data-on-ios-5-tutorial-getting-started. In the site there are, I think, other tutorials. Then, you could try to read a post on core data I've written some time ago: Mapping Business Objects with Core Data in iOS. Also Apple doc is your friend. So read the Introduction to Core Data Programming Guide to have the details that are going on.
If so, do I just replicate part of the database I wish to be made
viewable in the app and store it in my CoreData model?
Yes, just a part. You can create a minimal model that includes the key parts you need to have in your device. What I want to highlight is that you don't need to take care of normalization concepts when you deal with Core Data. Yes you could, but in CD you deal with objects and it's important to make attention to memory consumption (the framework helps you) and performances.
Would CoreData be good for storing this kind of information too? Or
would I be better sticking with dictionaries?
With CD you could take advantage of NSFetchedResultsController. A NSFetchedResultsController objects is optimized to work with tables and it used to display data also in batches. Through this component you can deal with a lot of elements (say friends in Facebook) without overload the memory. See core-data-tutorial-how-to-use-nsfetchedresultscontroller.
If you want to know something else, let me know.
Hope that helps.
I have developed an app that downloads the whole dataset into an array of objects. Should I be using core data to store the data? Aside from having some off-line data at hand for the user, are there any other advantages?
Thanks,
Steve
It's difficult to say with so little information. But if you need to store and access a bunch of data in iOS, Core Data is usually a good option.
It's obviously more complex than just storing the data in files (an array/dictionary can write its contents to disk) but you get a lot of other stuff for "free." Nice things include NSFetchResultController which means you can push your data into a table view with very little code. It makes things like undo and transactions easier.
Another option is using SQLite directly. If you know SQL and your data structure doesn't easily fit into an object graph (for whatever reason) or you want more control than Core Data can give you, it can be a good option.