Core Data: Relationships and User Objects - ios

I'm using StackMob with CoreData (remote Database), but I think this is a general Core Data question.
I have 3 entities:
User (login)
Cars
Bikes
Each entity has several attributes.
A User can have multiple Cars and Bikes objects (to-many relationship). Cars and Bikes can only have one owner (User) (inverse to-one relationship).
Now lets say we have 2,000 Users. Each User is a car dealer and has 500 cars and 300 bikes records/objects stored in CoreData. I would like the User to fetch based on attributes of Cars and Bikes. I plan to use predicates for this. To cut back on constant fetch request, I also plan to use Cache.
However, the questions I have are:
How should I save the record/object under each User? Is there a term for that in CoreData?
I would like the User to login and be able fetch all the Cars/Bikes based on its attributes (Model, Manufacture, DateStamp, etc.) only within the objects the User created. I guess what I'm trying to avoid is when the User does a fetch request based on attributes in the Cars and Bikes entity, it only searches under its own User objects. I don't want the fetch request to search through all the others User's objects because that would be a waste as I'm afraid that'll slow down the app. What's the best way to set this up in CoreData?
Just went though 2 core data books and I'm not sure how to approach this. I know I'm not the brightest so I turn to the experts for some advice. Thank you.

CoreData is actually really excelently optimized. What you need is an NSSearchPredicate and and NSFetchedResultsController. These are both kind of complicated and I can't just "tell" you how to use them. I found this open course to be EXTREMELY helpful
http://www.stanford.edu/class/cs193p/cgi-bin/drupal/
It builds a website fetching app in iOS using core data. Check the Core Data episode and if you don't know what he's talking about go back and watch some earlier ones

Related

What is best practice to handle Core Data relationship if I don't have the full data-set?

I have two type of models in the application I'm working on: User and Account.
Every account has many users. Every user has one account.
When I download the user object from an API, I get the account_id, but not the actual account object. The account object will be downloaded after the user object.
What is the best practice for establishing the relationship between the user and his account in this situation?
Should I insert an empty row into the Accounts table with just its account_id field filled in? And then later, when I download the account, update that row?
First, Core Data centric definitions, you have 2 entities (User and Account) and no tables (because this is an object store, not a SQLite database).
So, you wouldn't have empty rows, you would have stub objects (partially complete objects that will be filled in later).
There is no best practice when it comes to stub objects. Whether you should create them is entirely dependent upon your use case. In some cases it helps to have the basic information about an item so that you have something to show the user while you go and get the details. In your case, you only have an identity so the benefit of stub objects seems very low.

Deciding whether to use a one-to-many, many-to-many, or one-to-one relationship with Parse.com for iOS photo sharing app

I am creating a photo sharing app for the iPhone using Parse.com and so far everything has been pretty easy and I just finished writing the code for uploading photos to the Parse server.
So far, I have been using the default "_User" class. Here are some of the key types of data that are being stored for each user: objectId, username, email, and an array object called "friends" that contains the usernames of other users in the database that the user has added to their friends list.
Now, I need to setup the actual sharing functionality between users. I have been going through the Parse documentation and I need to decide whether to use a one-to-many, many-to-many, or one-to-one relationship. Depending on which one I end up choosing, I then will need to decide between using pointers, arrays, parse relations, or join tables.
I am going to quickly explain the "sharing" functionality that I am trying to achieve:
For my photo app, user1 starts the "relationship" by taking a photo and choosing to send it to a friend on their friends list named user2 .
The photo is then uploaded to Parse and sent to user2.
user2 receives the photo from user1.
user2 opens the photo and it is their job to "finish" the "relationship" by using the app's editing tools and drawing something random on the original photo. Example: user2 draws a heart next to user1's face in the photo.
When user2 is finished, the final photo is saved to their profile and also sent back to the original sender, user1, and the "relationship" is now finished and completed/closed.
After reading through the docs and doing my own research, I have come to the conclusion that I need to use a Many-To-Many relationship using Join Tables so that I can include metadata.
However, I am new to objective-c and programming in general and it would be lazy of me if I did not ask for input and advice before getting started when it is possible that I have chosen the wrong solution or an unnecessary solution.
Your question is more about your DB management than anything to do with Obj-C.
Think about using a new class in your DB called SharedImage which hosts the image(s), a link to the originator and the recipient (1 to 1, so could us a pointer or a relationship) and any other data you need.
Now you can create these objects are you require and you can fetch them based on queries using the current user.
Also, for your existing friends array which you said holds the usernames of the friends - it would probably be better to store the objectIds of the friends instead of the usernames (because the username can usually be changed, but the objectId is static).

What is the best way to store a user's Facebook friends list in my database?

Overview
I'm creating a Ruby on Rails website which uses Facebook to login.
For each user I have a database entry which stores their Facebook User ID along with other basic information.
I'm also using the Koala gem in order to retrieve a user's friendlist from Facebook, but I'm unsure as to how I should store this data...
Option 1
I could store the user's friends as a serialized hash in the User table, then if I wanted to display a list of all the current user's friends, I could grab this hash and do something along the lines of SELECT FROM Users WHERE facebook_user_id IN hash
Each time the user logs in I could update this field to store the latest friends list.
Option 2
I could create a Friend table and store friendship information in here, where a User has many Friends. So there would be a row for each friendship, (User1 and User2 columns). Then to display a list of the current user's friends I could do something like SELECT User2 FROM Friends WHERE User1 = current_user
This seems like the better option to me, but...
It has the disadvantage that there would be many rows... If there were 100,000 users, each with 100 friends, that's now 10,000,000 rows in the Friends table.
It also means each time the user logs in, I'd need to loop over their Facebook friends list returned using Koala and create a Friend record if someone on their friendlist is in my User table and there isn't a corresponding entry in the Friends table. This seems like it'd be slow if a user has 1000 Facebook friends?
I'd appreciate any guidance on how it would be best to achieve this.
Apologies for the badly worded question, I'll try and reword/organise it shortly.
Thanks for any help in advance.
If you need to store a lot of data, then you need to store a lot of data. If you are like most, you probably won't run into that problem sooner than you have the cash to solve it. In other words, you are probably assuming you'll have more traffic and data than you'll get, at least in the short-term. So I doubt this is an issue, even though it is a good sign that you are thinking about it now rather than later.
As I mentioned in my comment below, the easiest solution is to have a tie table with a row for each side of the friend relationship (a has_many :friends, through: :facebook_friend_relationships, class_name: 'FacebookFriend' on FacebookFriend, per the design mentioned below). But your question seemed to be about how to reduce the number of records, so that is what the remainder of the answer will address.
If you have to store in the DB and you know for sure that you will absolutely have every FB user on the planet hitting your site because it is so awesome, but they won't all hit at once, then if you are limited in storage, you may want to use a LRU algorithm (remove the least recently used records) possibly with timed expiration also. You could just have a cron job that does a query on the DB then deletes old/unused records to do this. Wouldn't be perfect, but it would be a simple solution.
You could also archive older data rather than throw it away. So, frequently used data could stay in the table of active users, and then you might offload older data to another table or even another database (and you might see the apartment and second_base gems for that). However, once you get to the size, you're probably looking at a number of other architectural solutions that have much less to do with ActiveRecord models/associations or schema design. Though it pays to plan ahead, I wouldn't worry about that excessively until you are sure that the application will get enough users to invest the time in that.
Even though ActiveRecord has some caching, you could just avoid the DB and cache friends in memory yourself in the beginning for speed, especially if you don't yet have many users, which you probably don't yet. If you think you'll run out of memory because of the high number of users, LRU might be a good option here also, and lru_redux looks interesting. Again, you might want to time the cache also so expires and re-gets friends when the cache expires. Even just storing the results in the user session may be adequate, i.e. in the controller action method, just do #friends ||= Something.find_friends(fb_user_id), and the latter is what most might do as a first shot at it while you're getting started.
If you use ActiveRecord, in your query in the controller (or on the association in the model) consider using include: to avoid n+1 queries. That will speed up things.
For the schema design, maybe:
User - users table with email and authN info. Look at the Devise gem.
FacebookUser - info about the Facebook user.
FacebookFriendRelationship - a tie model with (id and) two columns, one for one FacebookUser id and one for the other.
By separating the authN info (User) from the FB data (FacebookUser and FacebookFriendRelationship), you make it easier to have other social media accounts, etc. each with information specific to those accounts in other tables.
The complexity comes in FacebookUser's relationship with friends if the goal is to minimize rows in the relationship table. To half the number of rows, you'd have a single row for a relationship where the id of FacebookUser could be in either foreign key column. Either the user has a friend or is a friend, so you could have two has_many :through associations on FacebookFriend that each use a different foreign key in FacebookFriendRelationship. Or you could do HABTM without the model and use foreign_key and association_foreign_key options in each association. Either way, you could add a method to add both associations together (because they are arrays). Instead, you could use custom SQL in a single has_many if you didn't care about having to use ActiveRecord to remove associations the normal way. However, per your comments, I think you want to avoid this complexity, and I agree with you, unless you really must limit the number of relationship rows. However, it isn't the number of tie table rows that will eat the data, it is going to be all of the user info you keep in the FacebookFriends table.

storing number of yet nonexistent objects in relationship in Core Data

I have some data that needs to be loaded from the server (backend). For example, let's just say I have an entities of user and event. The relationship between them is many-to-many (user can attend many events and event can have many attendees). All the data is stored remotely on backend and locally in Core Data. When I download data from backend I convert it into NSManagedObjects and store it in NSManagedObjectContext. Everything's very simple, but...
When I download a list of events I want to know, how many attendees this event has. But I cannot download a list of users in the same request, because it's totally overkill. What I need is to download, let's say, a list of users' unique ids so that I can have two things: total number of attendees and means to download detailed data of concrete users (via unique id). Or there's another example: I need to know total number of attendees and download a limited set of them, so I can create some entities in CoreData, but not all of them.
So the main question is how am I supposed to store such information in my CoreData? Meaning I need to know that for some entity there are some related entities in relationship that are not actually currently present in CoreData, but I know how many of them there should be. The first thing that came in my mind is to have a attribute called something like usersCount in my event entity, but that seems to be kind of dirty. What is the best practice for such situation?
Please comment if the question is not clear enough so I can maybe add some more specifics.
When you download an event with a list of corresponding user ids, then you can create
the Event object and also the related User objects, but you fill only the "userId"
attribute in the user object.
Later, when you download the complete user info, you update the existing (incomplete) objects
or create new user objects. Implementing Find-or-Create Efficiently in the "Core Data Programming Guide"
describes a pattern that might be useful.
So the idea is to create Core Data objects with incomplete information first and update the
objects with detailed information later. The advantage is that you can set up all relationships immediatly, and e.g. counting related users works even if the user information
is yet incomplete.
There is nothing dirty about having an attribute to store the count, especially if those entities are retrieved and paged via separate requests.

How to user Core Data to construct my model object

i am using Core Data for the first time in my iOS application. I am testing how it works, but i have some problems like this : I have 3 entities (Page, User, Note), my application is a book, a user can consult the pages and take notes, the user can take several notes in several pages. How i can organize the model of my objects in core Data and the relationships between my Objects. thanks.
For starters, you might add a Book entity which has to-many relationships with Page and Note. You could also add methods to Book like -pageForPageNumber: and -notesForPage: just to make it easy to access the things you're likely to need. If your app represents a single book, then you can have some appropriate class like your app delegate or your root view controller fetch the one instance of Book in the store. If your app is more like a reader that contains multiple books, you might instead start by fetching all the books and displaying them in a list so that the user can choose one.

Resources