I have two entities. (Deal, Customer)
Deal and Customer have 1:1 relationship. so Deal has customer, and Customer has deal.
first, I made Customer object named "John".
second, I made Deal object and set customer with "John" (#1 deal)
third, I made another Deal object and set customer with "John" (#2 deal)
at that time, I found some problem.
that is #1 deal's customer set nil automatically, and #2 deal's customer is "John".
how can I solve that?
ps1. I got the data from web server as JSON like this
deals = [id: .., ..., customer: { ... }]
ps2. I update objects whenever receive data from server.
+ (Deal *)dealWithDealsDictionary:(NSDictionary *)dic inManagedObjectContext:(NSManagedObjectContext *)context
{
Deal *deal = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Deal"];
request.predicate = [NSPredicate predicateWithFormat:#"deal_id = %#", [dic[#"id"] description]];
// Execute the fetch
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:request error:&error];
// Check what happened in the fetch
if (!matches || ([matches count] > 1)) { // nil means fetch failed; more than one impossible (unique!)
deal = [matches lastObject];
// handle error
} else if (![matches count]) {
deal = [NSEntityDescription insertNewObjectForEntityForName:#"Deal" inManagedObjectContext:context];
} else {
deal = [matches lastObject];
}
deal.deal_id = [dic[#"id"] description];
deal.deal_status = [dic[#"deal_status"] description];
deal.deal_stage = [dic[#"deal_stage"] description];
deal.deal_desc = [dic[#"deal_desc"] description];
deal.localized_deal_status = [dic[#"localized_deal_status"] description];
deal.localized_deal_stage = [dic[#"localized_deal_stage"] description];
if (dic[#"customer"]) {
[context performBlock:^{
deal.customer = [Customer customerWithDictionary:dic[#"customer"] inManagedObjectContext:context];
}];
}
return deal;
}
you don't have a 1:1 relationship:it is 1:N
2 deals have the same customer, so 1 customer has N deals.
CoreData wanted to keep the 1:1 constraints where 1 deal has always 1 unique customer and vice versa.
Change to one-to-many
Make the relationship 1 to many or many to many if you want a customer to have many deals and / or many customers each to have many deals (where customers can each have the same deal).
The reference was set to nil because you said there could only be 1 reference at a time.
Related
I have made one sample demo on core data relationships.I have one Table "User" which is connected another table "Account" In form of "One to Many" relation.
Code
-(IBAction)savePersonData:(id)sender
{
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:context];
[newDevice setValue:self.personName.text forKey:#"name"];
[newDevice setValue:self.personAddress.text forKey:#"address"];
[newDevice setValue:self.personMobileNo.text forKey:#"mobile_no"];
NSManagedObject *newAccount = [NSEntityDescription insertNewObjectForEntityForName:#"Account" inManagedObjectContext:context];
[newAccount setValue:self.accountNo.text forKey:#"acc_no"];
[newAccount setValue:self.accountType.text forKey:#"acc_type"];
[newAccount setValue:self.balance.text forKey:#"balance"];
NSLog(#"Saved Successfully");
[self dismissViewControllerAnimated:YES completion:nil];
}
Image is
My Question is
I have find so many time but could not find proper answer.So I post this question second time.
My question is I have insert Manually Three person With their Account's Details.
Now ,I Want A balance which I have entered for specific person when I enter Mobile number.
Ex
1)Enter 1st Mobile Num. Should be display first Person's Balance.
2)Enter 2nd Mobile Num. Should be display second Person's Balance.
1)Enter 3rd Mobile Num. Should be display third Person's Balance.
Balance Check Code
-(IBAction)checkBalance:(id)sender
{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Person"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"mobile_no = %#",self.textField.text];
[fetchRequest setPredicate:predicate];
NSError *error;
NSArray *result = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if(!([result count] == 0))
{
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *newFetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Account"];
NSMutableArray *temp = [[managedObjectContext executeFetchRequest:newFetchRequest error:nil] mutableCopy];
for (NSManagedObject *object in temp)
{
NSString *intValue = [object valueForKey:#"balance"];
NSString *alertString = [NSString stringWithFormat:#"%#",intValue];
[self displayAlertView:#"Available Balance" withMessage:alertString];
}
}
else
{
[self displayAlertView:#"Error" withMessage:#"Please Enter Valid Mobile Number That you have entered in Bank"];
}
}
Images
Output
I want Balance With Specific Person Which I enter Person Mobile No on TextField.
Sorry Guys,I have asked second time ,But Could no able to solve this core data relationships.
Thank you.
First...
Fix the naming of your relationships. As others have pointed out in comments on your other question, you have named them back to front: in the Person entity, the to-many relationship to Account should be named "accounts" not "person". Likewise in the Account entity, the to-one relationship to Person should be named "person" not "accounts".
Next...
Although you have defined the "accounts" relationship as to-many, the savePersonData code in this question creates only one Account and one Person - but does not then set the relationship between them. (You can see this in your Output: each Account has nil for its "accounts" relationship).
The code in your previous question did set the relationship (by adding the newAccount to the relationship on the newPerson object). In your code above you could use (after fixing the relationship names):
NSMutableSet *setContainer = [newDevice mutableSetValueForKey:#"accounts"];
[setContainer addObject:newAccount];
but with one-many relationships it is easier to set the inverse relationship:
[newAccount setValue:newDevice forKey:#"person"];
Next...
Your checkBalance method correctly fetches any Person objects whose "mobile_no" attribute matches. But your subsequent code then fetches ALL Account objects - even if you had correctly set the relationship.
If you want only those Account objects that are related to a given Person, that is precisely what the "accounts" relationship represents. So you could just use that relationship to access the related Account objects:
if(!([result count] == 0)) {
NSManagedObject *requiredPerson = (NSManagedObject *)result[0];
NSSet *temp = [requiredPerson valueForKey:#"accounts"];
for (NSManagedObject *object in temp) {
NSString *intValue = [object valueForKey:#"balance"];
NSString *alertString = [NSString stringWithFormat:#"%#",intValue];
[self displayAlertView:#"Available Balance" withMessage:alertString];
}
}
Alternatively, fetch the relevant Account objects directly (without fetching the Person object first) by specifying a predicate that traverses the relationship:
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *newFetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Account"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"person.mobile_no = %#",self.textField.text];
[newFetchRequest setPredicate:predicate];
NSMutableArray *temp = [[managedObjectContext executeFetchRequest:newFetchRequest error:nil] mutableCopy];
for (NSManagedObject *object in temp)
{
NSString *intValue = [object valueForKey:#"balance"];
NSString *alertString = [NSString stringWithFormat:#"%#",intValue];
[self displayAlertView:#"Available Balance" withMessage:alertString];
}
I have a problem checking whether a particular attribute of an Entity exists in the Core Data Database (through predicates) before creating a new object; if the object exists, I'd rather return it than create a new object.
I have a simple App which has a table view with a plus button in the Navigation Bar; the user clicks that and is presented with a View Controller with 4 text fields. They fill in that information, press save and it gets saved to Core Data and displayed in the TableView (through the use of NSFetchedResultsControllers).
The data model is as follows:
Transaction Entity with isReceived BOOL attribute
Person Entity with name string attribute
Occasion Entity with title string attribute
Item Entity with amount string attribute
The transaction has a relationship to the Person (whoBy), Occasion (Occasion) and Item entities.
In the view controller with the save method, I have the code below which will insert new objects into the Transaction, Person, Occasion Entities, etc. Each Transaction is of course unique, but with each transaction, the user can select an existing PERSON and/or Occasion and if that person then does not exist, it will be created (likewise with the occasion).
I'm slightly confused as to the format of the code here.
EDIT: I have tried a combination of code and can just not get this working. In the code below, I'm referencing person.name in the predicate, but I also tried creation a local NSString variable to hold the self.nameTextField.text code but that did nothing. I tried creating a NSString property to reference it that way and that not work. I tried using the words MATCHES, LIKE, CONTAINS, == and every combination in-between.
- (IBAction)save:(id)sender
{
NSManagedObjectContext *context = [self managedObjectContext];
Transaction *transaction= [NSEntityDescription insertNewObjectForEntityForName:#"Transaction" inManagedObjectContext:context];
Person *person = [NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:context];
Occasion *occasion = [NSEntityDescription insertNewObjectForEntityForName:#"Occasion" inManagedObjectContext:context];
Item *amount = [NSEntityDescription insertNewObjectForEntityForName:#"item" inManagedObjectContext:context];
NSFetchRequest *personFind = [NSFetchRequest fetchRequestWithEntityName:#"Person"];
personFind.predicate = [NSPredicate predicateWithFormat:#"name == %#", person.name];
// I have tried every combination of the predicate like MATCHES, LIKE.
// I created a local NSString variable and an NSString property
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
personFind.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:personFind error:&error];
if (!matches || ([matches count] > 1))
{
// Handle Error
}
else if ([matches count] == 0)
{
person.name = self.nameTextField.text;
transaction.whoBy = person;
occasion.title = self.occasionTextField.text;
transaction.occasion = occasion;
}
else
{
person = [matches lastObject];
transaction.whoBy = person;
occasion.title = self.occasionTextField.text
transaction.occasion = occasion;
}
if (![context save:&error])
{
NSLog(#"Can't save! %# %#", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Logically, what I want to achieve is:
When the user is adding a Transaction, check if it's for a new person or an existing one — if it's an existing one, choose it from a list of Persons (and when the user selects a person, get its NSManagedObjectID). If it's a new one, create it on the spot.
The same for the Occasion.
Set all the other fields of the Transaction object (amount, etc.).
My question is:
What predicate do I use to get this working?
When I put a break point in this method, a NEW NAME (one that doesn't exist before) correctly calls the else if ([matches count] == 0) method and if I create an entry with an existing name, it calls the
else
{
person = [matches lastObject];
transaction.whoBy = person;
occasion.title = self.occasionTextField.text
transaction.occasion = occasion;
}
Even with the this statement, it is still creating a new person object for the same name.
I will correctly implement the occasion after getting the person working, but I'm just lost on how to get this working.
Any help would be massively appreciated!
"Is this correct?":
No. You are creating a new Person and Occasion objects whether you are using an existing person/occasion or not.
First check for existence and only if the object not already exist, insert a new one.
Alternatively, if the person/occasion exist, delete the inserted object.
"How do I retrieve the managedObjectID for person/event?":
Person* person = /*Get an existing person object*/
NSManagedObjectID* personId = person.objectID /*This is the person object ID, will work for any NSManagedObject subclass*/
To find a person that start with a string str use this predicate in a fetch request:
/*UNTESTED*/
[NSPredicate predicateWithFormat:#"(name BEGINSWITH[cd] %#)", str];
Edit:
To be more precise, you practice find or create using something like this:
(this is very limited, and only good for a single object performance-wise)
(NOT TESTED)
- (NSManagedObject*) findOrCreateObjectByValue:(id)value
propertyName:(NSString*)propertyName
entityName:(NSString*)entityName
additionalInfo:(NSDictionary*)additionalInfo
context:(NSManagedObjectContext*)context
error:(NSError* __autoreleasing*)error
{
NSManagedObject* res = nil;
NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:entityName];
[r setPredicate:[NSPredicate predicateWithFormat:#"%K == %#",propertyName,value]];
NSArray* matched = [context executeFetchRequest:r
error:error];
if (matched) {
if ([matched count] < 2) {
res = [matched lastObject];
if (!res) { //No existing objects found, create one
res = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:context];
[res setValue:value
forKey:propertyName];
[res setValuesForKeysWithDictionary:additionalInfo];
}
} else {
if (error) {
*error = [NSError errorWithDomain:#"some_domain"
code:9999
userInfo:#{#"description" : #"duplicates found"}];
}
}
}
return res;
}
So now, your save: method should look something like:
(I assume here that the person name and occasion title are held by a UITextField on the view controller [txtPersonName and txtOccasionTitle respectively] )
- (void) save:(id)sender
{
//create a clean context so that changes could be discarded automatically on failure
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[context setParentContext:[self managedObjectContext]];
//A Transaction is always created in save event, so add it to the context
Transaction* transaction = [NSEntityDescription insertNewObjectForEntityForName:#"Transaction" inManagedObjectContext:context];
__block NSError* error = nil;
Person* p = (Person*)[self findOrCreateObjectByValue:self.txtPersonName.text
propertyName:#"name"
entityName:#"Person"
additionalInfo:nil
context:context
error:&error];
if (!p) {
NSLog(#"Error: %#, person name: %#",error,self.txtPersonName.text);
return;
}
Occasion* o = (Occasion*)[self findOrCreateObjectByValue:self.txtOccasionTitle.text
propertyName:#"title"
entityName:#"Occasion"
additionalInfo:nil
context:context
error:&error];
if (!o) {
NSLog(#"Error: %#, occasion title: %#",error,self.txtOccasionTitle.text);
return;
}
transaction.whoBy = p;
transaction.occasion = o;
//Not sure what you are using this property for
transaction.item = [NSEntityDescription insertNewObjectForEntityForName:#"Item"
inManagedObjectContext:context];
NSManagedObjectContext* ctx = context;
if ([context obtainPermanentIDsForObjects:[context.insertedObjects allObjects]
error:&error])
{
//save your changes to the store
__block BOOL saveSuccess = YES;
while (ctx && saveSuccess) {
[ctx performBlockAndWait:^{
saveSuccess = [ctx save:&error];
}];
ctx = [ctx parentContext];
}
if (!saveSuccess) {
NSLog(#"Could not save transaction, error: %#",error);
}
} else {
NSLog(#"Could not obtain IDs for inserted objects, error: %#",error);
}
//Do what you have to do next
}
This is just for making things a bit clearer on what you should do to avoid duplications, and reuse existing objects.
I have the following core data relationship set up in my model.
Category -> Product -> CartProduct <<- Cart (See picture below).
But I have a hard time figuring out how to establish these relationships (in code). I have made 2 Objective-C Categories, with the names: CartProduct+Product & Cart+CartProduct.
CartProduct+Product contains the following code - this method is called, when the user pushes the "add to cart" button.
+ (CartProduct *)addProductToCartProducts:(Product *)theProduct inManagedObjectContext:(NSManagedObjectContext *)context {
CartProduct *cartProduct = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"CartProduct"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"products" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *cartProducts = [context executeFetchRequest:request error:&error];
if (!cartProducts || ([cartProducts count] > 1)) {
// handle error
} else if (![cartProducts count]) {
cartProduct = [NSEntityDescription insertNewObjectForEntityForName:#"CartProduct"
inManagedObjectContext:context];
/*This method is called from an background context, to prevent context conflicting, get nsmangedobject by its id, which is threadSafe. */
NSManagedObjectID *retID = [theProduct objectID];
//Setup One-One relationship from Product to CartProduct
cartProduct.product = (Product *) [context objectWithID:retID];
/*Call method from class Cart+CartProduct to establish to-many relationship from Cart to CartProduct.*/
[Cart addCartProductToCart:cartProduct inManagedObjectContext:context];
} else {
cartProduct = [cartProducts lastObject];
}
return cartProduct;
}
Cart+CartProduct contains the following code:
+ (Cart *)addCartProductToCart:(CartProduct *)theCartProduct inManagedObjectContext:(NSManagedObjectContext *)context {
Cart *cart = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"CartProduct"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"productsInCart" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *cartProducts = [context executeFetchRequest:request error:&error];
if (!cartProducts || ([cartProducts count] > 1)) {
// handle error
} else if (![cartProducts count]) {
cart = [NSEntityDescription insertNewObjectForEntityForName:#"Cart"
inManagedObjectContext:context];
[cart addProductsInCartObject:theCartProduct];
} else {
cart = [cartProducts lastObject];
}
return cart;
}
Now I want to view, the objects the user has added to his Cart, I therefore fetch from the Cart entity. But I can't figure out if the I have "connected" the relationships correct? and how to fetch the products in the cart, so I can show the products. (which is in a one-many relationship with CartProduct).
So my question is:
Is the relationship established correct?
How do I manage to fetch the products which is added to the cart?
NB: Earlier this year, I made the following post: Add to cart functionality - Core data and this question is based on that.
Your relationships seem mostly correct, though I think you do not even need the CartProduct entity. Core Data can handle many-to-many relationships behind the scenes. You can just have Cart have a relationship "products" and Product have the inverse relationship "inCarts". A Cart can have many Products and a Product can be in many Carts.
But anyway, you can keep it as is. The only problem is that Product's relationship "cartProduct" should be to-many (and therefore should be named "cartProducts". That is, if you want it to be possible that a product is in more than one cart. Also, be sure you have all your inverse relationships correctly defined.
Your code looks all wrong to me. It's way too complicated for achieving what you're trying to do. Core Data makes it simple. It looks like you are trying to create a new Cart and add the Product to it. You shouldn't need to do any fetching to do this. It seems like maybe you are thinking like a database. With Core Data, you do not think about modifying tables, you think about setting pointers between objects. I would do it this way:
+ (Cart *)startNewCartWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {
Cart *cart = [NSEntityDescription insertNewObjectForEntityForName:#"Cart" inManagedObjectContext:context];
CartProduct *cartProduct = [NSEntityDescription insertNewObjectForEntityForName:#"CartProduct" inManagedObjectContext:context];
// with correct inverse relationships, automatically adds cartProduct to cart:
cartProduct.cart = cart;
cartProduct.product = product;
return cart;
}
Now for your question #2. To get the products in a cart, use code like this:
+ (NSSet *)productsInCart:(Cart *)cart {
NSMutableSet *result = [NSMutableSet setWithCapacity:[cart.productsInCart size]];
for (CartProduct *cartProduct in cart.productsInCart)
[result addObject:cartProduct.product];
return result;
}
Ha det bra!
I have the following relationship in my app:
Product ->> ProductOrder <<- Order
I then have two Obj-c categories in order to etablish these relationship:
ProductOrder+Product
+ (ProductOrder *)addProductToOrderWithProduct:(Product *)product inManagedObjectContext:(NSManagedObjectContext *)context {
ProductOrder *orderProduct = nil;
orderProduct = [NSEntityDescription insertNewObjectForEntityForName:#"ProductOrder" inManagedObjectContext:context];
NSManagedObjectID *productID = [product objectID];
orderProduct.qnty = product.qnty;
orderProduct.price = product.price;
[(Product *)[context objectWithID:productID] addOrderedProductsObject:orderProduct];
return orderProduct;
}
And then Order+ProductOrder
+ (Order *)addOrderedProductToOrderWithOrderedProduct:(ProductOrder *)orderedProduct inManagedObjectContext:(NSManagedObjectContext *)context {
Order *order = nil;
order = [NSEntityDescription insertNewObjectForEntityForName:#"Order" inManagedObjectContext:context];
NSManagedObjectID *orderedProductID = [orderedProduct objectID];
[order addOrderProductsObject:(ProductOrder *)[context objectWithID:orderedProductID]];
return order;
}
I add products to these relationship like so:
for (Product *prod in [self.fetchedResultsController fetchedObjects]) {
[[[DataManager sharedInstance] backgroundManagedObjectContext] performBlock:^{
ProductOrder *prodOrder = [ProductOrder addProductToOrderWithProduct:prod inManagedObjectContext:[[DataManager sharedInstance] backgroundManagedObjectContext]];
Order *order = [Order addOrderedProductToOrderWithOrderedProduct:prodOrder inManagedObjectContext:[[DataManager sharedInstance] backgroundManagedObjectContext]];
NSInteger amount = [order.orderNumber integerValue];
amount++;
order.orderNumber = [NSString stringWithFormat:#"Order %#", [NSNumber numberWithInteger:amount]];
[[DataManager sharedInstance] saveBackgroundContext];
[[DataManager sharedInstance] saveMasterContext];
}];
}
I now want to group these products in headers. I have this orderNumber attribute in my Order entity, I want to increment for every group of products added to the relationship. How would I manage to do this?
Visual example:
Your code has a number of problems.
First, is there a particular reason you need different managed object context? If not, eliminate that part. Remember, you can access each managed object's context with
product.managedObjectContext;
Second, you are using ObjectIDs which is really only necessary if you pass objects across contexts. In your method, you extract the ID from product and then call objectWithID to get it back. That does not make any sense at all.
Third, you need a very good reason to have this ProductOrder entity at all. Even if you have not told us, let's assume it is necessary because you want to include, say, different quantities for the products in an order, as well as an ordering number. However, the name you chose is very confusing. Let's call it Item.
Your scheme should now look like this:
Product <---->> Item <<------> Order
You could simply use the Core Data generated methods to add relationships and throw away your categories.
For your table you could fetch the Order entity and inform the datasource as follows:
// number of sections
fetchedObjects.count;
// title for section
Order *order = fetchedObjects[section];
order.name;
// number of rows in section
Order *order = fetchedObjects[section];
order.items.count;
// row data
Order *order = fetchedObjects[section];
NSArray *items = [order.items sortedArrayUsingSortDescriptors:
#[[NSSortDescriptor sortDescriptorWithKey:#"sequenceNumber" ascending:YES]]];
Item *item = items[indexPath.row];
item.product.name;
I am developing an application where i used core data framework for the purpose of maintaining a database. My entity contains three attributes called: name, start time and end time of a list of applications. I am getting the correct values for name and start time attribute.
Now my problem is my end time attribute should contain the value of the next entries start time value. If anybody having any idea about this please let me know.
Thanks
You can leave the endTime attribute blank until you create the next entity. In the +Create category on the entity, get the last/first object (assuming you are using ordered entities) and update the endTime with the same value used for the new startTime.
If your objects are not ordered it could be a bit tricky since all the entities are in a set. But if ordered, you are good since NSOrderedSet responds to lastObject (and firstObject).
Enjoy,
Damien
EDIT: Here is an example factory method that either 1) returns the existing stock entity for a stock symbol or 2) creates a new entity for that symbol. Pretty easily modified to get entities and select the first/last depending on your sort order. Again see the Core Data classes from Prof. Hegarty.
+ (Stock *)stockForSymbol:(NSString *)symbol inManagedObjectContext:(NSManagedObjectContext *)context {
Stock *stock = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Stock"];
request.predicate = [NSPredicate predicateWithFormat:#"symbol = %#",symbol];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"symbol" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || [matches count] > 1) {
// handle error
} else if ([matches count] == 0) {
stock = [NSEntityDescription insertNewObjectForEntityForName:#"Stock" inManagedObjectContext:context];
stock.symbol = symbol;
stock.strategyPosition = [NSNumber numberWithInt:StrategyPositionFlat];
stock.userPosition = stock.strategyPosition;
stock.userOwns = [NSNumber numberWithBool:NO];
} else {
stock = [matches lastObject];
}
return stock;
}