Core Data to populate UITableView: can't get a NSString - objective-c

my app stores players's data and I want to populate a UITableView with it, but I'm afraid I'm a bit lost.
Here's my code:
ShowResults.h
#import <UIKit/UIKit.h>
#interface ShowResults : UITableViewController<UITableViewDelegate,UITableViewDataSource, NSFetchedResultsControllerDelegate>
{
NSManagedObjectContext *managedObjectContext;
NSFetchedResultsController *fetchedResulstController;
NSArray *fetchedObjects;
}
#property (nonatomic) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic) NSManagedObjectContext *managedObjectContext;
#property (nonatomic,strong) NSArray *fetchedObjects;
#end
ShowResults.m
#import "ShowResults.h"
#import "F1AppDelegate.h"
#interface ShowResults ()
#end
#implementation ShowResults
#synthesize managedObjectContext;
#synthesize fetchedResultsController;
#synthesize fetchedObjects;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
F1AppDelegate *appDelegate =[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context =[appDelegate managedObjectContext];
NSError *error;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] &&[managedObjectContext save:&error]) {
NSLog(#"Unresolved error %#,%#",error, [error userInfo]);
abort();
}
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Players" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
// Test reading core data
for (NSManagedObject *player in fetchedObjects) {
NSLog(#"Name: %#", [player valueForKey:#"name"]);
NSLog(#"Surname: %#", [player valueForKey:#"surname"]);
NSLog(#"Address: %#", [player valueForKey:#"address"]);
NSLog(#"Email: %#", [player valueForKey:#"email"]);
NSLog(#"Phone: %#", [player valueForKey:#"phone"]);
NSLog(#"City: %#", [player valueForKey:#"city"]);
NSLog(#"Country: %#", [player valueForKey:#"country"]);
NSLog(#"Store: %#", [player valueForKey:#"store"]);
NSLog(#"Age: %#", [player valueForKey:#"age"]);
NSLog(#"Gender: %#", [player valueForKey:#"gender"]);
NSLog(#"Time: %#", [player valueForKey:#"time"]);
}
// End test
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSInteger rows = [fetchedObjects count];
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
NSString *pieceOfData =[NSString stringWithFormat:#"%#", [fetchedObjects objectAtIndex:indexPath.row]];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
cell.textLabel.text = pieceOfData;
NSLog(#"cellContent: %#",pieceOfData);
return cell;
}
#end
What I get on console output is
Name: Otto
Surname: Von Bismarck
Address: Schuhe, 3
Email: otto#munchen.de
Phone: +34988556633
City: MÜNCHEN
Country: GERMANY
Store: MÜNCHEN
Age: 44
Gender: Male
Time: 03:01:00
cellContent: <Players: 0x6b8f3c0> (entity: Players; id: 0x6b8b450 <x-coredata://C61C85CA-EB53-4B88-87AF-CC45EABFF8ED/Players/p1> ; data: {
address = "Schuhe, 3";
age = 44;
city = "M\U00dcNCHEN";
country = GERMANY;
email = "otto#munchen.de";
gender = Male;
name = Otto;
phone = "+34988556633";
store = "M\U00dcNCHEN";
surname = "Von Bismarck";
time = "03:01:00";
})
Can you help me to write these values into the tableView cells?
Thanks !

It looks like you are just need to do something like this:
// in your cellForRowAtIndexPath:
Players *player = [fetchedObjects objectAtIndex:indexPath.row];
// switch email for whatever other property you want to display
cell.textLabel.text = player.email;
It also looks like you might need to import Players.h into your class.

Related

How to use CoreData in Xcode 8?

I am trying use CoreData, but when I add it to my project I only get two new methods :
- (NSPersistentContainer *)persistentContainer
and
- (void)saveContext
Now I can't get old methods to work with CoreData, and I can't find any tutorials with these new methods and Objective-C. How can I save and get data from CoreData using persistentContainer in Xcode 8 with Objective-c?
You can Get context as -
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
or as in Objective-C
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).persistentContainer.viewContext;
And fetch data like -
var resultArray = try self.context.fetch(EntityName.fetchRequest())
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And fetch data with sorting -
var resultArray = [EntityName]()
do {
let request : NSFetchRequest<EntityName> = EntityName.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "somekey", ascending: true)
let sortDescriptors = [sortDescriptor]
request.sortDescriptors = sortDescriptors
resultArray = try self.context.fetch(request)
} catch {
print("Error")
}
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"someKey" ascending:YES];
fetchRequest.sortDescriptors = #[sortDescriptor];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And add data like -
let entityNameObj = EntityName(context: context)
entityNameObj.title = "title"
or as in Objective-C
NSManagedObject *entityNameObj = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:context];
[entityNameObj setValue:#"someValue" forKey:#"someKey"];
And save context like -
do {
try self.context.save()
} catch _ as NSError {
print("Error")
}
or as in Objective-C
[((AppDelegate*)[[UIApplication sharedApplication] delegate]) saveContext];
-(void)profileDatabase {
NSManagedObjectContext* context=[ADM.persistentContainer viewContext];
NSManagedObject *profile=[NSEntityDescription insertNewObjectForEntityForName:#"Profile" inManagedObjectContext:context];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"firstName"] forKey:#"firstName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"surName"] forKey:#"surName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"batchID"] forKey:#"batchID"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"role"] forKey:#"role"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"userObj:%#",profile);
NSError* error;
[context save:&error];
NSFetchRequest *fetchRequest=[[NSFetchRequest alloc]initWithEntityName:#"Profile"];
fetchRequest.returnsObjectsAsFaults=NO;
NSArray* results=[context executeFetchRequest:fetchRequest error:&error];
NSLog(#"Result:%#",results);
NSManagedObject *result=[results objectAtIndex:0];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"firstName"] forKey:#"firstName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"surName"] forKey:#"surName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"batchID"] forKey:#"batchID"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"role"] forKey:#"role"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"dic:%#",ADM.databaseResponseOfProfileDict);}
I have found a solution using Objective C. It runs, but I'm not sure that it is the correct solution.
- (void)dbManager {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
abort();
}
NSManagedObject *customAnimal = [NSEntityDescription insertNewObjectForEntityForName:#"Animals" inManagedObjectContext:context];
[customAnimal setValue:#"Lion" forKey:#"type"];
[customAnimal setValue:#"Rabit" forKey:#"name"];
[customAnimal setValue:#"Blue" forKey:#"color"];
[customAnimal setValue:#12 forKey:#"age"];
NSLog(#"Get data from DB");
NSMutableArray* animalsArray;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Animals"];
animalsArray = [[context executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"array is %#", animalsArray); // array is (
"<Animals: 0x6000000aee80> (entity: Animals; id: 0x60000022e120 <x-coredata:///Animals/tAAC7332D-6BEF-441C-9041-0ECB57469FA62> ; data: {\n age = 12;\n color = Blue;\n name = Rabit;\n type = Lion;\n})"
}
For all the beginners out there, this will give you the basic idea.
welcome.m
==========
#import "welcomepage.h"
#import "Register.h"
#import "login.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "loginbtn.h"
#import "King+CoreDataProperties.h"
#interface welcomepage ()
{
AppDelegate *a;
NSManagedObjectContext *context;
}
#end
#implementation welcomepage
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)login:(id)sender
{
loginbtn *lb=[[loginbtn alloc]init];
[self.navigationController pushViewController:lb animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)register:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context1=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
Student *ss=[NSEntityDescription insertNewObjectForEntityForName:#"Student" inManagedObjectContext:context1];
ss.name=[NSString stringWithFormat:#"%#",_txtfld1.text];
ss.age=[NSString stringWithFormat:#"%#",_txtfld2.text];
ss.place=[NSString stringWithFormat:#"%#",_txtfld3.text];
[a saveContext];
if (_txtfld1.text.length && _txtfld2.text.length && _txtfld3.text.length != 0)
{
UIAlertView *al=[[UIAlertView alloc]initWithTitle:#"THANK YOU" message:#"DATA SUCESSFULLY SAVER. YOU CAN LOGIN NOW WITH YOUR PASSWORD AND NAME" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al show];
_txtfld1.text=#"";
_txtfld2.text=#"";
_txtfld3.text=#"";
Register *rg=[[Register alloc]init];
[self.navigationController pushViewController:rg animated:YES];
}
else
{
UIAlertView *al2=[[UIAlertView alloc]initWithTitle:#"WARRNING" message:#"PLEASE FILL THE DATA COMPLETELY" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al2 show];
}
}
===================================================
Register.m
==========
#import "Register.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "welcomepage.h"
#interface Register ()<UITableViewDelegate,UITableViewDataSource>
{
AppDelegate *a;
NSManagedObjectContext *context01;
NSArray *array01;
}
#end
#implementation Register
- (void)viewDidLoad
{
[super viewDidLoad];
a=((AppDelegate *)[UIApplication sharedApplication].delegate);
context01=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
// specifying nsrequest and nsentity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity01=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context01];
[req setEntity:entity01];
// putting datas from reto array
NSError *err=nil;
array01=[context01 executeFetchRequest:req error:&err];
// Do any additional setup after loading the view from its nib.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return array01.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ci=#"hai";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ci];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ci];
}
if (indexPath.row==0) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"name"];
}
if (indexPath.row==1) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"age"];
}
if (indexPath.row==2) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"place"];
}
return cell;
}
==================================================
Loginbtn.m
============
#import "loginbtn.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "login.h"
#interface loginbtn ()
{
AppDelegate *a;
NSArray *arraylb;
}
#end
#implementation loginbtn
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)lgbtn:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
//xcode 8.2.1 specification code
NSManagedObjectContext *context=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
//creating feathch request and entity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context];
[req setEntity:entity];
// setting predicate
NSPredicate *pre=[NSPredicate predicateWithFormat:#"age like %# and place like %#",_txt1.text,_txt2.text];
[req setPredicate:pre];
//creating error and array to store
NSError *err=nil;
arraylb=[[NSArray alloc]init];
arraylb=[context executeFetchRequest:req error:&err];
login *lg=[[login alloc]init];
if (arraylb.count!=0)
{
lg.array001=arraylb;
}
//
// if (arraylb.count!=0)
//// {
////
//// lv *lvi=[[lv alloc]init];
////
//// //passing value
//// lvi.array001=arraylb;
////
////
//// //lv.str1=self.tf1.text;
//// //lv.str2=self.tf2.text;
//// [self.navigationController pushViewController:lvi animated:YES];
////
////
//// }
//// else
//// {
//
// self.lb.text=#"Invalid username & password";
//
// }
//
[self.navigationController pushViewController:lg animated:YES];
}
=====================================================
Lohin.m
=========
#import "login.h"
#import "Student+CoreDataProperties.h"
#import "AppDelegate.h"
#import "loginbtn.h"
#interface login ()
{
AppDelegate *a;
NSArray *array01;
}
#end
#implementation login
- (void)viewDidLoad
{
[super viewDidLoad];
_txt11.text=[[_array001 objectAtIndex:0]valueForKey:#"name"];
_txt22.text=[[_array001 objectAtIndex:0]valueForKey:#"age"];
_txt33.text=[[_array001 objectAtIndex:0]valueForKey:#"place"];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
// Dispose of any resources that can be recreated.
}

How to Get Duplicate Contact list iOS and merge or delete Contact?

I Want to Delete Duplicate or Merge duplicate Contact Can anyOne Provide me Sample Code for it !!!!!
I want to get the List of Duplicate Contact in tableview and merge them or delete them
I created sample project for you.I got the solution.it works perfectly.
Addressbook framework is deprecated from iOS 9.So we need to use Contact framework.
We must import Contact framework
Next in plist If you want to access contacts,you have to get
authorization permission so you need to add Privacy - Contacts Usage
Description
Key is Privacy - Contacts Usage Description
Type is string
Value is contact (whatever you want add here as string)
ViewController.h
#import <UIKit/UIKit.h>
#import <Contacts/Contacts.h>
#interface ViewController : UIViewController<UISearchBarDelegate,UITableViewDataSource,UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tblViewContact;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrData;
NSMutableArray *arraySearchContactData;
}
#end
#implementation ViewController
#synthesize tblViewContact;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrData = [[NSMutableArray alloc]init];
[self getContact];
[tblViewContact registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
}
//Get Contact and Authorization Access
-(void)getContact
{
// Request authorization to Contacts
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES)
{
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
UIImage *profileImage;
NSMutableArray *contactNumbersArray = [[NSMutableArray alloc]init];
NSMutableArray *arrContacts = [[NSMutableArray alloc]init];
for (CNContact *contact in cnContacts)
{
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:#"person-icon.png"];
}
for (CNLabeledValue *label in contact.phoneNumbers)
{
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,#"fullName",profileImage,#"userImage",phone,#"PhoneNumbers", nil];
[arrContacts addObject:[NSString stringWithFormat:#"%#",[personDict objectForKey:#"fullName"]]];
}
//Removing Duplicate Contacts from array
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:arrContacts];
NSArray *arrayWithoutDuplicates = [orderedSet array];
arrData = [arrayWithoutDuplicates mutableCopy];
NSLog(#"The contacts are - %#",arrData);
dispatch_async(dispatch_get_main_queue(), ^{
[tblViewContact reloadData];
});
}
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableView Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
cell.textLabel.text = arrData[indexPath.row];
return cell;
}
The Printed results For Contacts
The contacts are - (
"John Appleseed",
"Kate Bell",
"Anna Haro",
"Daniel Higgins",
"David Taylor",
"Hank Zakroff"
)
Screenshot below
When first you run the app
Now it shows contacts in table view

'NSInternalInconsistencyException', reason: 'attempt to insert row 3 into section 0, but there are only 2 rows in section 0 after the update'

I use Core Data in my project and when trying to add new row, I get an error:
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1377
2015-01-16 22:45:47.172 LinguaCard[26439:599761] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 3 into section 0, but there are only 2 rows in section 0 after the update'
CardsTableViewController.m
#import "CardsTableViewController.h"
#import "Lesson.h"
#import "Card.h"
#import "CoreDataHelper.h"
#interface CardsTableViewController ()
#property (strong, nonatomic) NSMutableArray *cards;
#end
#implementation CardsTableViewController
-(NSMutableArray *)cards{
if (!_cards)
_cards = [[NSMutableArray alloc] init];
return _cards;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSSet *unordereCards = self.lesson.cards;
NSSortDescriptor *nameDescr = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSArray *sortedCards = [unordereCards sortedArrayUsingDescriptors:#[nameDescr]];
self.cards = [sortedCards mutableCopy];
#pragma mark - helpers
-(Card *)cardWithName:(NSString *)name{
NSManagedObjectContext *context = [CoreDataHelper managedObjectContext];
Card *card = [NSEntityDescription insertNewObjectForEntityForName:#"Card" inManagedObjectContext:[CoreDataHelper managedObjectContext]];
card.name = name;
card.lesson = self.lesson;
NSError *error = nil;
if (![context save:&error]){
//we have an error
NSLog(#"error: %#", error);
}
return card;
}
#pragma mark - UIAlertViewDelegate
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 1) {
NSString *alertText = [alertView textFieldAtIndex:0].text;
[self.cards addObject:[self cardWithName:alertText]];
[self.tableView insertRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:[self.cards count]-1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Card"];
NSError *error = nil;
NSArray *fetchedCards = [[CoreDataHelper managedObjectContext] executeFetchRequest:fetchRequest error:&error];
self.cards = [fetchedCards mutableCopy];
[self.tableView reloadData];
}
- (IBAction)addCard:(id)sender {
UIAlertView *newCard = [[UIAlertView alloc] initWithTitle:#"Enter new card name:" message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Add", nil];
[newCard setAlertViewStyle:UIAlertViewStylePlainTextInput];
[newCard show];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.lesson.cards.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Card Cell" forIndexPath:indexPath];
Card *selectedCard = self.cards[indexPath.row];
cell.textLabel.text = selectedCard.name;
return cell;
}
When your UIAlertViewDelegate method adds a card it adds it to a controller property. When you report the number of rows in your section you use the lesson object which doesn't know about the controller's cards.

Access properties and methods from one class inside another class in Objective C

I am trying to build a class in Objective C that contain serve the web service and database methods for my application. In this class I want to call a web service and grab employee records and then load them into an SQL table for later use in a view.
I got this working when all the code as in the view, but in trying to make this new class (what I am calling GetEmployee) I am running into problems. I do not understand well how to access properties and methods from one class in another.
Here is my GetEmployee Class
#import <Foundation/Foundation.h>
#import "employee.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "FMDatabasePool.h"
#import "FMDatabaseQueue.h"
#import "FMResultSet.h"
#import "Utility.h"
#interface GetEmployee : NSObject
{
NSMutableArray *employees;
}
#property (nonatomic, copy) NSString *databaseName;
#property (nonatomic, copy) NSString *databasePath;
- (void)updateEmployeeData;
- (void)callWebService;
- (void)fetchedData:(NSData *)responseData;
- (NSMutableArray *) getEmployees;
#end
implementation
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define scoularDirectoryURL [NSURL URLWithString: #"https://XXXXXXXXX/mobile/mobilede.nsf/restServices.xsp/PeopleByName"]
#import "GetEmployee.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "FMResultSet.h"
#implementation GetEmployee
- (id) init
{
if (self = [super init])
{
self.databaseName = #"employees.db";
}
return self;
}
#pragma
- (void)updateEmployeeData{
//Delete database if it exists and then copy fresh DB
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success;
success = [fileManager fileExistsAtPath:self.databasePath];
if (success) {
[fileManager removeItemAtPath:self.databasePath error:nil];
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
//Call the web service
[self callWebService];
[self populateDatabase];
}
- (void) callWebService {
dispatch_sync(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
scoularDirectoryURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSMutableArray *jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
employees = [[NSMutableArray alloc] init];
if (!jsonArray) {
} else {
for (jsonObject in jsonArray){
employee *thisEmployee = [employee new];
thisEmployee.fullName = [jsonObject objectForKey:#"$13"];
thisEmployee.ste = [jsonObject objectForKey:#"state"];
thisEmployee.city = [jsonObject objectForKey:#"city"];
[employees addObject:thisEmployee];
}
}
}
-(void) populateDatabase {
////Call the web service and populate the db
//dispatch_sync(kBgQueue, ^{
// NSData* data = [NSData dataWithContentsOfURL:
// scoularDirectoryURL];
// [self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
//});
//Populate the db
FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
[db open];
for (employee *thisemployee in employees) {
BOOL success = [db executeUpdate:#"INSERT INTO employees (fullname,city,state) VALUES (?,?,?);",thisemployee.fullName,thisemployee.city,thisemployee.ste, nil];
if (success) {} // Only to remove success error
}
[db close];
}
- (NSMutableArray *) getEmployees
{
//NSMutableArray *employees = [[NSMutableArray alloc] init];
employees = [[NSMutableArray alloc] init];
FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
[db open];
FMResultSet *results = [db executeQuery:#"SELECT * FROM employees"];
while([results next])
{
employee *thisEmployee = [employee new];
thisEmployee.fullName = [results stringForColumn:#"fullname"];
thisEmployee.city = [results stringForColumn:#"city"];
thisEmployee.ste = [results stringForColumn:#"state"];
[employees addObject:thisEmployee];
}
[db close];
return employees;
}
#end
And here is the MasterViewController
header
#import <UIKit/UIKit.h>
#import "employee.h"
#import "FMDatabase.h"
#import "FMResultSet.h"
#import "FMDatabaseAdditions.h"
#import "Utility.h"
#import "GetEmployee.h"
#interface MasterViewController : UITableViewController
{
NSMutableArray *employees;
//GetEmployee *ScoularEmployees;
}
#end
implementation
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define scoularDirectoryURL [NSURL URLWithString: #"https://xxxxxxxx/mobile/mobilede.nsf/restServices.xsp/PeopleByName"]
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "employee.h"
#import "GetEmployee.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#property(strong, nonatomic) GetEmployee *ScoularEmployees;
#end
#implementation MasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
//GetEmployee *ScoularEmployees = [[GetEmployee alloc] init];
[self.ScoularEmployees init];
//[self.ScoularEmployees init];
//_ScoularEmployees = [[GetEmployee alloc] init];
//[_ScoularEmployees getEmployees];
//GetEmployee *ScoularEmployees = [[GetEmployee alloc] init];
//GetEmployee *thisEmployeeData = [[GetEmployee alloc] init];
//[self.ScoularEmployees updateEmployeeData];
//[self.ScoularEmployees getEmployees];
//[ScoularEmployees updateEmployeeData];
//[ScoularEmployees getEmployees];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return employees.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *fullName = [[employees objectAtIndex:indexPath.row] valueForKey:#"fullName"];
cell.textLabel.text = fullName;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
employee *dtlEmployee = [employees objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:dtlEmployee];
}
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSMutableArray *jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
//employees = [[NSMutableArray alloc] init];
if (!jsonArray) {
} else {
//NSMutableArray *employees = [[NSMutableArray alloc ]init];
for (jsonObject in jsonArray){
employee *thisEmployee = [employee new];
thisEmployee.fullName = [jsonObject objectForKey:#"$13"];
thisEmployee.ste = [jsonObject objectForKey:#"state"];
thisEmployee.city = [jsonObject objectForKey:#"city"];
[employees addObject:thisEmployee];
}
}
}
//-(NSMutableArray *) getEmployees
//{
//NSMutableArray *employees = [[NSMutableArray alloc] init];
//employees = [[NSMutableArray alloc] init];
// FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
// [db open];
// FMResultSet *results = [db executeQuery:#"SELECT * FROM employees"];
//
// while([results next])
// {
// employee *thisEmployee = [employee new];
// thisEmployee.fullName = [results stringForColumn:#"fullname"];
// thisEmployee.city = [results stringForColumn:#"city"];
// thisEmployee.ste = [results stringForColumn:#"state"];
// //[employees addObject:thisEmployee];
// }
//
// [db close];
//
// return employees;
// return true;
//}
#end
Any help would be greatly appreciated.
I thought it was clear but I can see it is not. In the view class I want to be able to load an NSMutableArray called *employees that comes from the SQLLite database and out them on the screen. I have tried to centralize the code for data access in the GetEmployee class. Everything in that class deals with the data - web service, load the data to the database, and getting the data out of the database as well. So in that Class I have a method "getEmployees" that gets data from the db and loads it into that NSMutableArry. So here is the problem, in the class I cannot get access to the methods or properties in GetEmpployee. That is my question.
Without reading through all the code you've posted...
For using a Class method, the syntax is:
[ClassName methodName];
[ClassName anotherMethod:withArguments];
Methods that are called using this syntax will look like this in the corresponding .h file:
+(void)methodName;
+(void)anotherMethod:(NSNumber*)number;
For using an instance method, the syntax is:
ClassName myObj = [[ClassName alloc] init];
[myObj someMethod];
[myObj someOtherMethod:withArguments];
Methods that are called using this syntax will look like this in the corresponding .h file:
-(void)someMethod;
-(void)someOtherMethod:(NSString*)parameter;

need to save contents of table view as txt file and the reload it later

i need to be able to save the contents of my table view which is given data by an NSMutableArray to a txt file and then need to reopen that file automatically when the window containing the table view. i am making an application for mac
thanks
this is the code for the data source:
#import "tableViewData.h"
#import "Customer.h"
#implementation tableViewData
-(id) init
{
self = [super init];
if (self) {
list = nil;
filepath = #"/Users/Gautambir/Desktop/CustomerNames.txt";
if ([[NSFileManager defaultManager]fileExistsAtPath:filepath]) {
list = [[NSMutableArray alloc] initWithContentsOfFile:filepath];
}
else
list = [[NSMutableArray alloc]initWithObjects:name,memberNumber ,nil];
[list writeToFile:filepath atomically:YES];
}
return self;
}
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
return [list count];
}
-(id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
Customer *Customer = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
return [Customer valueForKey:identifier];
}
-(void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
Customer *Customer = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
[Customer setValue:object forKey:identifier];
}
-(void)save{
[list writeToFile:filepath atomically:YES];
}
-(IBAction)add:(id)sender{
[list addObject:[[Customer alloc]init]];
[tableView reloadData];
NSLog (#"array:%#",list);
}
-(IBAction)remove:(id)sender{
NSInteger row = [tableView selectedRow];
if (row != -1) {
[list removeObjectAtIndex:row];
}
[tableView reloadData];
}
-(void)dealloc
{
[super dealloc];
}
#end
and this is the .m file for the customer object class:
#import "Customer.h"
#implementation Customer
#synthesize name;
#synthesize memberNumber;
-(id) init
{
self = [super init];
if(self) {
name = #"Test";
int i = arc4random()%1000000000000000000;
if (i<0) {
memberNumber = i*-1;
}
else
memberNumber = i;
}
return self;
}
-(void)dealloc
{
[name release];
[super dealloc];
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
name = [[aDecoder decodeObjectForKey:#"name"]retain];
memberNumber = [aDecoder decodeIntForKey:#"memberNumeber"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:name forKey:#"name"];
[aCoder encodeInt:memberNumber forKey:#"memberNumber"];
}
#end
strong text
im sorry to post another answer - i misread the tags, and my first answer was relying to iOS.
this is the way to do it in OSX:
saving
NSMutableArray *array = ... //your array
[array addObject:...];
[array addObject:...];
[array addObject:...];
...
// then use an NSData to store the array
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
NSString *path = #"/Users/User/path...";
[data writeToFile:path options:NSDataWritingAtomic error:nil];
retrieving
NSMutableArray *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
sebastian