问题
I have a scenario in my basic inventory app.
i fetched the records from the core data entity and want other records to be entered against that one.
I have two core data entities Category and Product
i have made their relationship as well.
i have done with the category part.
now i want to add Products against the selected category.
for that i am using a UIPICKERVIEW
to show the category name.
I am currently showing the names to the UIPICKERVIEW
When the user select the name and enter records the id
should be stored in the Product entity where the relational field is.
Currently the UIPICKERVIEW is showing the name of the category from the Category table
where their is a form to insert the data to the Product table against that category.
In Simple i want to show names in the picker and in backend the id will be stored against that name.
In Category.h entity i have
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * is_active;
@property (nonatomic, retain) NSString * descript;
@property (nonatomic, retain) NSSet *products;
IN Product.h I have
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * is_active;
@property (nonatomic, retain) NSString * descript;
@property (nonatomic, retain) Category *category;
IMSAddProductViewController.h
#import <UIKit/UIKit.h>
#import "IMSAppDelegate.h"
@interface IMSAddProductViewController : UIViewController < UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate>
@property (weak, nonatomic) IBOutlet UIPickerView *categoryPicker;
@property (weak, nonatomic) IBOutlet UITextField *txtEnterName;
@property (weak, nonatomic) IBOutlet UITextField *txtEnterDescription;
@property (weak, nonatomic) IBOutlet UISwitch *txtIsActive;
@property (weak, nonatomic) IBOutlet UILabel *lblValuePicker;
@property(nonatomic,retain)NSArray *arr;
@property (assign, nonatomic) NSMutableArray *categoryArray;
- (IBAction)btnSave:(id)sender;
@end
Getting results From Entity 1 Category
IMSAddProductViewController.m //(UIViewController sub class)
#import "IMSAddProductViewController.h"
#import "IMSAppDelegate.h"
#import "Product.h"
#import "Category.h"
@interface IMSAddProductViewController ()
{
NSManagedObjectContext *context;
}
@end
@implementation IMSAddProductViewController
@synthesize arr;
@synthesize txtIsActive;
@synthesize categoryArray;
@synthesize txtEnterName;
@synthesize txtEnterDescription;
@synthesize categoryPicker;
@synthesize lblValuePicker;
- (void)viewDidLoad
{
[super viewDidLoad];
self.categoryPicker.delegate = self;
IMSAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
context = [appDelegate managedObjectContext];
NSEntityDescription *category = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc ] init];
request.resultType = NSDictionaryResultType;
[request setEntity:category];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"name" ascending:YES];
[request setSortDescriptors:@[sortDescriptor]];
// request.propertiesToFetch = [NSArray arrayWithObject:[[category propertiesByName] objectForKey:@"name"]];
request.returnsDistinctResults = YES;
request.resultType = NSDictionaryResultType;
NSError *error;
NSArray *array = [context executeFetchRequest:request error:&error];
// NSMutableArray *results = [[context executeFetchRequest:request error:&error] mutableCopy];
if (array == nil) {
//error handle here
}
NSArray* results2 = [array valueForKeyPath:@"name"];
[self setArr:results2];
// [self setArr:results];
NSLog (@"name: %@",self.arr);
}
//-(void) addProducts:(NSSet *)values {
//
//}
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
// return _countryNames.count;
return self.arr.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
//return _countryNames[row];
return self.arr[row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
categoryArray = [self.arr objectAtIndex:row];
NSLog (@"name: %@",self.categoryArray );
// both of these are returning the name of categories.
self.categoryPicker = [self.arr objectAtIndex:row];
NSLog (@"name: %@",self.categoryPicker);
NSLog(@"id : %d", row);
}
THE CODE WHERE I AM INSERTING DATA TO PRODUCT
- (IBAction)btnSave:(id)sender {
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Product" inManagedObjectContext:context];
NSManagedObject *newProduct = [[NSManagedObject alloc]initWithEntity:entityDesc insertIntoManagedObjectContext:context];
[newProduct setValue:self.txtEnterName.text forKey:@"name"];
[newProduct setValue:self.txtEnterDescription.text forKey:@"descript"];
if (self.txtIsActive.isOn) {
[newProduct setValue: @(self.txtIsActive.isOn) forKey:@"is_active"];
}
else{
[newProduct setValue: @(self.txtIsActive.tag == '0') forKey:@"is_active"];
}
// what should be done in this block of code
/*
lblValuePicker.text = [NSString stringWithFormat:@"%d",[self.categoryPicker selectedRowInComponent:0]];
NSLog(@"row number: %@", lblValuePicker.text);
[newProduct setValue:lblValuePicker.text forKey:@"category"];
*/
NSError *error = nil;
if (![context save:&error]) {
//handle the error
NSLog(@"some error");
}
else
{
NSLog(@"dataentered");
}
}
HERE IS THE SNAPSHOT I HAVE IT FROM BASE
THE CORE DATA IT SELF MANAGES THE INDEXES I HAVEN'T CREATE ANY ID OR PRIMARY KEY FOR THAT.
回答1:
1. I would suggest you read this Official documentation on How to create, initialize and save a Managed Object.
2. Understand when you select the row in picker view then the below delegate is called, in which I can see you have used an array. This is wrong:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
categoryArray = [self.arr objectAtIndex:row];
}
From the selected row, you would get only the name of the Category because that is in the array. I guess you must be getting an error here, because you are equilating an NSString
to an array.
To do it correctly I would suggest you to change the previous code as well. Instead, of fetching only name property from Category entity from Core Data, you fetch the whole Category entities.
I can give you code here but that wont be any good for you. You must try first.
Fetch the whole Category Entity, use a sort desciptor for 'name'- otherwise it may create problem later and in UIPickerView
- titleForRow
delegate method, use dot(.) operator to display name.
3.
Change your didSelectRow
implementation. Donot put anything in the array. You need the selected Category to map against the newly created Product.
Create an instance variable of type Category, and using objectAtIndex
method, get the corresponding Category and put it inside your instance variable.
4.
In btnSave
method, use the instance variable to map your Product against the selectedCategory. Please go through he link mentioned above to understand how to create, initialize and save the managed object, because I can see you are using a lot of key- value coding which is though not wrong, but is not the largely followed policy.
来源:https://stackoverflow.com/questions/19059128/how-to-manage-data-between-the-entities-with-the-uipickerview