iOS class selection NSDictionary or Core Data - ios

I am learning iOS programming and wouldn't mind an opinion or two on the most appropriate class to use for my application, NSDictionary or Core Data. I would like to be able to create an array of records with a set of attributes.
For example, Name: Joe Citizen, Age:38, Sex: Male, Profession: Zookeeper, City: Sydney etc.
I would like to be able to randomly select a record with one or more attribute. Last night I was moving towards a NSDictionary solution, where I would embed the properties into a bit mapped word, convert it to a string, and then append strings to that string to make a key unique such as k_stringbitpattern_uniquenumber. To get the random identifier I would generate a random number, mask it, convert it to a string etc, to the point that I realized that it is getting too cumbersome.
I am new to iOS programming and am trying to consider speed, memory usage, elegance and reuse. Getting
seasoned opinions will help.
I apologize in advance if my use of terms is not strictly correct (i.e. array of records).
Oh yes, the records are read-only, and I hope to be able to extend my app later to pull data from a website. Any helpful
comments appreciated.

This is really a question for programmers.stackexchange.com.
My answer for this is build the simplest and easiest to understand model possible and don't worry about optimizations.
In your case, I would recommend an NSArray of plain old Objective-C objects. In your object class, make all the attributes into properties. Use NSNumber instead of NSInteger or int for numbers. Searches can be done with a simple for loop or -filteredArrayUsingPredicate:.
Later on, if based on performance needs, switching to Core Data should not be too painful. Look into MagicalRecord. It is a much needed simplification of the complexities of Core Data.
I would not recommend building your own indexes with NSDictionary. At that point, you are beginning to write your own database. Other people have solved that problem.

Related

Fastest way to find an entity in CoreData

I have 20k unique labels that each have their own Entity with their own title.
What is the quickest way to get access to an Entity, given its title?
I know this can be done using a predicate, like so
fetch.predicate = NSPredicate(format: "title contains %#", "example title")
My issue with this approach is that it involves searching through every single one of the 20k Entities until the right one is found.
Is there a way to do this where all the titles are somehow indexed, and I can instantly get access to any label? Similar to how you can instantly get access to an item in an associative array, with array['item_name'].
Thanks.
Using a predicate is how you do it with Core Data.
Before you do anything, is this actually a problem? You don't mention that you've seen any performance issues. Are you having any, or is this still a theoretical problem?
You might improve performance by making sure that the "Indexed" box is checked for this attribute in the Core Data model editor. You might also consider adding a field to your entity that would contain a numeric hash of the title, and fetching based on the hash. You'd still be searching every entity but you'd be doing numeric comparisons instead of strings. You wouldn't be able to do substring searches (as your use of contains implies) but you would be doing the same thing as an associative array (which is also called a hash, for exactly this reason).
If none of that works well enough and you're searching strings very frequently, you'll need to investigate a different data model more suited to your needs-- like building a trie structure for fast searching.

Parse iOS backend - Objects, Arrays, and User data advice

I hope this isn't an inappropriate post, but I wanted to make sure my first steps implementing parse as my backend are in the right direction to save some time. I'm new to both iOS programming and the parse sdk, so please bear with me!
In my app, users are able to create various polygon shape overlays on a Google Maps mapView, stored as a GMSMutablePath, which is basically a list of coordinates. Users will have at least one group of paths, each with at least one path. There will also be some information stored with each group, stored as strings or numbers. This information is specific to a single group of paths.
I'm trying to figure out the best way to store this data. My first basic question is 1) Can I store the GMSMutablePath as a whole in the Object data type? Or does the Object data type refer to a class that is created through parse? This link (https://www.parse.com/questions/what-is-data-type-of-object-in-data-browser) is the 'best' explanation I found of the Object data type, and it isn't very clear to me.
My gut instinct is no, I can't store the GMSMutablePath object, and that Object refers to a Parse object. Which leads me to 2) How should I store this data, then? I can get the individual lat/long values of the coordinates that make up each path, and I can store those as numbers, and use the numbers to recreate the paths elsewhere. None of the paths should use too many coordinates, and there shouldn't be too many paths in each group.
Playing around a little bit in the data browser, I see that I can store arrays, but I'm not sure how those are formatted, as I'd need an array (of groups) of arrays (of paths) of arrays (of lat/long values). A little bit of googling tells me it can be done, but doesn't show me how. Can any datatype be stored in any array, or is a datatype specified? I'm used to C++ programming, so I'm used to an array containing a single type of element. What I'm thinking is that I'd need an array of objects, which would be the groups of paths. Each one of those objects would have the string/number information associated with the group, as well as an array for the paths within the group. For each one of those paths, it would have to be either an array or an object. Since for the path I just need the coordinate lat/long values, I think that I can get away with an each path being an array of numbers, and I can write my program to use one array, with odd indexes being lat / even indexes being long values. That all being said, I'm not sure how to create all of that. I'm not looking for somebody to write my implementation for me, but all of the examples I can find are much more simple... if anybody could point me in the right direction to do this, or has a better idea of how to do it, I'd love some pointers.
Each user is going to have their own groups, but that data is going to be shared with others at some point. The data will be associated with the user it belongs to. With that in mind, my last question is 3) Should I store all of this information specific to a user and their groups on the User class, or make it all a separate class entirely? My guess it that I should add an Object to the User class, and store the groups within that Object. I just want to make sure I have that right, with future scalability in mind. Like, when I pull the group data, am I going to have to pull the entire User data from another user, and if so, is that going to slow things down significantly? I'm thinking that I do have to send entire user data, but I don't know if that poses any security risks. Would it be best to have a separate class for the groups, and store the user id associated with the groups? If I do this, should I also store the groups as an object on the User class?
Sorry for the wall of text, but thank you for any guidance you can provide!
If you need any clarification, let me know.
Thanks,
Jake
Creating a class to hold all the objects turned out to be unnecessary. It only had a few extra details that were just as convenient to add to the user object, and then have an array of objects on the user.
Some main things to note that I learned are: use addObject to add to an array, rather than setObject to add a single object to a PFObject/User.
Parse fetching/saving happens in background threads, so if you're loading the data to do something specific with it, make sure the code using the data occurs inside a block using the [PFObject fetchInBackgroundWithBlock] method.
Also, as changes are made to the structure of your data on a parse user/object, make sure you sign out of the current user and create a new one on your app, or you may run into lots of undefined behaviour that could crash your app.

Neo4j - individual properties, or embedded in JSON? (ROR)

I want to know which is more efficient in terms of speed and property limitations of Neo4j.. (I'm using Ruby on Rails 3.2 and REST)
I'm wondering whether I should be storing node properties in a single property, much like a database table, or storing most/all for a node in a single node property but in JSON format.
Right now in a test system I have 1000 nodes with a total of 10000 properties.. Obviously the number of properties is going to skyrocket as more features and new node types are added to my system.
So I was considering storing all the non-searchable properties for a node in an embedded JSON structure.. Except this seems like it will put more burden on the web servers, having to parse the JSON after retrieving it, etc. (I'm going to use a single property field with JSON for activity feed nodes, but I'm addressing things like photo nodes, profile nodes etc).
Any advice here? Keep things in separate properties? A hybrid of JSON and individual properties?
What is your goal by storing things in JSON? Do you think you'll hit the 67B limit (which will be going up in 2.1 in a few months to something much larger)?
From a low level store standpoint, there isn't much difference between storing a long string and storing many shorter properties. The main thing you're doing is preventing yourself from using those fields in a query.
Also, if you're using REST, you're going to have to do JSON parsing anyway, so it's not like you're going to completely avoid that.

Which is the best solutions to store a data (coredata or sql)?

I'm developing a quiz application. I have 100 questions. For example, what city is the capital of Great Britain?
A. Rome
B. Milan
C. London
D. Oslo
Which is the best solutions to store a data (coredata or sql)?
Core Data is a bit more complex to set up than SQL, however in my opinion Core Data is MUCH easier to work with, and keeps you in "objective-c land" where as SQL requires writing tons of SQL statements (as far as I know).
Specific to your use-case, I would think CoreData would be a better fit. You would probably have a Question object with an NSString text property for the actual question and then an NSArray of Answer objects. In CoreData/SQL speak, you would have a table of Questions with a text column. Each Question has a to-many relationship with a table of Answer objects (CoreData handles the dirty work for relationships, but in SQL you'd use primary keys).
As I said in a comment on another answer below, because your database isn't very large and complex initially, you could package a plist or download one from a server to initially populate the CoreData database. Using CoreData instead of a plist means it's much easier to update values on the fly, so you can do things like have a property on each answer object that you can set if the user chooses that answer so you can save state between launches.
Check out Core Data vs SQLite 3 and many other stack overflow answers that talk about the pros and cons of several different methods.
For a simple question/answer database with only 100 entries I would use a plain text file.
It's simple to create, edit, and read. It's cross-platform should you ever want an Android or other version of your application.
You could use XML, JSON, or a plist (as mentioned above) but why bother? Just alternate lines between questions and answers. Read in the file using [NSString stringWithContentsOfFile] and split up the lines into an array using [myFileContentString componentsSeparatedByString:#"\n"].
NSError *error = nil;
NSArray *testArray = [[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error] componentsSeparatedByString:#"\n"];
It's 1-2 lines of code and no learning curve. The odd entries in the array will be the questions and the even entries will be the answers.
(Reading a plist requires only one line of code, which is nice, but they're harder to edit by hand and aren't simple to read on other platforms should you ever branch out)
You could also consider just using a .plist file with an array. Your data is not that complex (from what I understand), and plist makes for easy external maintaining/reading and updating via http.

entity framework ref, deref, createref [duplicate]

This question is about why I would use the above keywords. I've found plenty of MSDN pages that explain how. I'm looking for the why.
What query would I be trying to write that means I need them? I ask because the examples I have found appear to be achievable in other ways...
To try and figure it out myself, I created a very simple entity model using the Employee and EmployeePayHistory tables from the AdventureWorks database.
One example I saw online demonstrated something similar to the following Entity SQL:
SELECT VALUE
DEREF(CREATEREF(AdventureWorksEntities3.Employee, row(h.EmployeeID))).HireDate
FROM
AdventureWorksEntities3.EmployeePayHistory as h
This seems to pull back the HireDate without having to specify a join?
Why is this better than the SQL below (that appears to do exactly the same thing)?
SELECT VALUE
h.Employee.HireDate
FROM
AdventureWorksEntities3.EmployeePayHistory as h
Looking at the above two statements, I can't work out what extra the CREATEREF, DEREF bit is adding since I appear to be able to get at what I want without them.
I'm assuming I have just not found the scenarios that demostrate the purpose. I'm assuming there are scenarios where using these keywords is either simpler or is the only way to accomplish the required result.
What I can't find is the scenarios....
Can anyone fill in the gap? I don't need entire sets of SQL. I just need a starting point to play with i.e. a brief description of a scenario or two... I can expand on that myself.
Look at this post
One of the benefits of references is that it can be thought as a ‘lightweight’ entity in which we don’t need to spend resources in creating and maintaining the full entity state/values until it is really necessary. Once you have a ref to an entity, you can dereference it by using DEREF expression or by just invoking a property of the entity
TL;DR - REF/DEREF are similar to C++ pointers. It they are references to persisted entities (not entities which have not be saved to a data source).
Why would you use such a thing?: A reference to an entity uses less memory than having the DEFEF'ed (or expanded; or filled; or instantiated) entity. This may come in handy if you have a bunch of records that have image information and image data (4GB Files stored in the database). If you didn't use a REF, and you pulled back 10 of these entities just to get the image meta-data, then you'd quickly fill up your memory.
I know, I know. It'd be easier just to pull back the metadata in your query, but then you lose the point of what REF is good for :-D

Resources