I have a quiz.vc and i am passing an NSString from on vc to another and it passes null. (i am using a UITextView)
Quiz.h
#property (nonatomic,strong) IBOutlet UITextView *textField;
#property (nonatomic, retain) NSString *userText;
Quiz.m
- (IBAction)next:(id)sender {
// i have tried NSString *userText also and passing in userText to sfvc.string
self.userText = self.textField.text;
selectFriendsViewController *sfvc = [[selectFriendsViewController alloc] init];
sfvc.string = self.userText;
}
selectFriendsViewController.h
#property (nonatomic, strong) NSString *string;
selectFriendsViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", _string);
}
its always logging null at runtime? i have tried so many ways and methods!
any ideas as to how i can pass a string and not null???
Thanks
Your error
selectFriendsViewController *sfvc = [[selectFriendsViewController alloc] init];
sfvc.string = self.userText;
This create a new instance of selectFriendsViewController,but you do not use it.It will be dealloced when the method is done.So,you got nothing.
If you fire a segue in the IBAction,use prepareForSegue to pass data.
Edit,
If you fire a segue when the button clicked.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.destinationViewController isKindOfClass:[selectFriendsViewController class]]) {
selectFriendsViewController * dvc = (selectFriendsViewController*)segue.destinationViewController;
dvc.string = self.textField.text;
}
}
If you don't want to show null,use the below code
#pragma mark - check string is empty or not
- (IBAction)next:(id)sender
{
self.userText = self.textField.text;
selectFriendsViewController *sfvc = [[selectFriendsViewController alloc] init];
sfvc.string = [self checkEmpty:self.userText];
}
- (void)checkEmpty:(NSString *)check
{
#try
{
if (check.length==0)
check = #" ";
if([check isEqual:[NSNull null]])
check = #" ";
}
#catch (NSException *exception)
{
check = #" ";
}
}
I think u can't navigate and push the value to next viewController
use this code if you using xib files.
- (IBAction)next:(id)sender {
selectFriendsViewController *sfvc = [[selectFriendsViewController alloc] init];
sfvc.string = self.textField.text;
[self.navigationController pushViewController:sfvc animated:YES];
}
hope that code helps you.
I have an NSMutablearray that I have data saved to. Data is input on my main ViewController. When you tap on a saved item, the SecondViewController has a textfield that the data entry is loaded into in order to be edited. I want to be able to edit that item and then save it back to the array.
I am fairly new to Objective-C / Cocoa Touch so please go easy on me.
- (ToDoItem *) updateToDoItem: (ToDoItem *) todoitem {
NSLog(#"ToDoItemSvc.updateToDoItem: %#", [todoitem description]);
NSMutableArray *toDoItems = [NSMutableArray array];
for (NSString *todoitem in toDoItems) {
if ([[ToDoItem] isEqualToString:toDoItems]) {
[toDoItems replaceObjectAtIndex:todoitem];
}
}
I know this isnt completely correct and may be completely off base but Im hoping I am moving in the right direction with this.
EDIT
Here is my ToDoItemSvcArchive.m file
#import "ToDoItemSvcArchive.h"
#implementation ToDoItemSvcArchive
NSString *filePath;
NSMutableArray *toDoItems;
- (id) init {
NSArray *dirPaths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
filePath = [[NSString alloc] initWithString: [docsDir
stringByAppendingPathComponent: #"ToDoItems.archive"]];
[self readArchive];
return self;
}
- (void) readArchive {
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: filePath])
{
toDoItems = [NSKeyedUnarchiver unarchiveObjectWithFile: filePath];
}
else
{
toDoItems = [NSMutableArray array];
}
}
- (void) writeArchive {
[NSKeyedArchiver archiveRootObject:toDoItems toFile:filePath];
}
- (ToDoItem *) createToDoItem: (ToDoItem *) todoitem {
NSLog(#"ToDoItemSvc.createToDoItem: %#", [todoitem description]);
[toDoItems addObject:todoitem];
[self writeArchive];
return todoitem;
}
- (NSMutableArray *) retrieveAllToDoItems {
return toDoItems;
}
- (ToDoItem *) updateToDoItem: (ToDoItem *) todoitem {
NSLog(#"ToDoItemSvc.updateToDoItem: %#", [todoitem description]);
NSMutableArray *toDoItems = [NSMutableArray array];
for (NSString *todoitem in toDoItems) {
if ([[ToDoItem] isEqualToString:toDoItems]) {
[toDoItems replaceObjectAtIndex:todoitem];
}
}
// return todoitem;
}
- (ToDoItem *) deleteToDoItem: (ToDoItem *) todoitem {
NSLog(#"ToDoItemSvc.deleteToDoItem: %#", [todoitem description]);
[toDoItems removeObject:todoitem];
[self writeArchive];
return todoitem;
}
#end
EDIT
I guess what I dont really understand is how to get the actual index of the object that needs to be replaced.
Edit
I think this is better
- (ToDoItem *) updateToDoItem: (ToDoItem *) todoitem {
NSLog(#"ToDoItemSvc.updateToDoItem: %#", [todoitem description]);
NSUInteger index = [toDoItems indexOfObject:todoitem];
[toDoItems replaceObjectAtIndex:0 withObject:todoitem];
return todoitem;
}
Im still not sure how to specify the correct index.
Over complicating the entire thing
Changed todoitemtext to todoitemobject and made it a todoitem rather than an NSString. Now when I click update, it updates the object and when you go back to the list, the view calls reloaddata and the view is updated with the new object
- (IBAction)updateToDoItem:(id)sender {
NSLog(#"updatingToDoItem: entering");
toDoItemObject.todoitem = toDoItem.text;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
toDoItem.text = toDoItemObject.todoitem;
}
Works like a champ now.
Data I need to displayed has been stored into a temp file.When I execute the application, NSLog can receive the data, but UITextField didn't respond. I don't know if I am using the correct syntax. And I am not sure why it doesn't work...
Update: I tried to assign a value to UItextField, but the UItextField doesn't display it neither
-(void)readFilewin
{
// ....
NSString *pathsWin;
NSArray *pathsWin1= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
pathsWin = [[pathsWin1 objectAtIndex:0] stringByAppendingPathComponent:#"arraycountwin.plist"];
NSArray *getfile = [NSArray arrayWithContentsOfFile:pathsWin];
//NSArray *getfile = [NSArray arrayWithContentsOfFile:#"arraycountwin.plist"];
//self.TotalWinTextField.text = [getfile objectAtIndex:0];
NSString * win = [[NSString alloc]init];
win = [getfile objectAtIndex:0];
NSLog(#"Win : %#", win);
self.TotalWinTextField.text = [NSString stringWithFormat:#"%#", win];
}
-(void)readFileLoss{...}
-(void)readFilestats
{
// ....
NSString *statspath;
NSArray *statspaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
statspath = [[statspaths objectAtIndex:0] stringByAppendingPathComponent:#"arraystats.plist"];
NSArray *getfile = [NSArray arrayWithContentsOfFile:statspath];
NSString * time = [[NSString alloc]init];
time = [getfile objectAtIndex:0];
NSLog(#"Time : %#", time);
NSString * time1 = [[NSString alloc]init];
time1 = [getfile objectAtIndex:1];
NSLog(#"Time1 : %#", time1);
self.textField1.text = time; //broke here after update the viewDidLoad as #paul11 advise
self.textField2.text = time1;
}
Update for testing purpose to make sure the textfield is working, but it cannot even read the assigned value:
- (void)readFilewin
{
self.TotalWinTextField.text = #"23"; //DONT WORK
}
I think you forgot to reference UITextField in the storyboard with your property
#property (weak, nonatomic) IBOutlet UITextField *totalWinTextField;
that is easy you just need to select your UITextField in the storyboard holding down the key control and you drag it to your property. You can see when the property is referenced when in the left side has a circle filled.
I hope to be helpful.
From your comment, this is your viewDidLoad -
- (void)viewDidLoad {
//win
self.TotalWinTextField = 0;
//loss
self.TotalLossTextField = 0;
//stats
self.textField1 = 0;
self.textField2 = 0;
self.textField3 = 0;
[self readFilewin];
[self readFilelose];
[self readFilestats];
}
This is setting all of your IBOutlets to nil (0).
I presume that what you meant was -
- (void)viewDidLoad {
//win
self.TotalWinTextField.text = #"0";
//loss
self.TotalLossTextField.text = #"0";
//stats
self.textField1.text = #"0";
self.textField2.text = #"0";
self.textField3.text = #"0";
[self readFilewin];
[self readFilelose];
[self readFilestats];
}
First of all make sure that outlet is created correctly
Secondly, check it is properly synthesized
thridly, make sure outlet is nonatomic
change ur viewDidLoad to this
- (void)viewDidLoad {
// Do any additional setup after loading the view.
[super viewDidLoad];
//win self.TotalWinTextField = 0;
//loss self.TotalLossTextField = 0;
//stats self.textField1 = 0;
self.textField2 = 0;
self.textField3 = 0;
[self readFilewin];
[self readFilelose];
[self readFilestats];
}
Here is my mainAppDelegate.h:
#import <UIKit/UIKit.h>
#interface mainAppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property NSMutableArray *toDoItems;
#end
and my mainAppDelegate.m:
#import "mainAppDelegate.h"
#implementation mainAppDelegate
- (void)applicationWillTerminate:(UIApplication *)application
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"toDoItems.plist"];
[self.toDoItems writeToFile:filePath atomically:TRUE];
}
#end
I have another file, XYZToDoListViewController.m with the code:
#import "XYZToDoListViewController.h"
#import "XYZToDoItem.h"
#import "XYZAddItemViewController.h"
#interface XYZToDoListViewController ()
#property NSMutableArray *toDoItems;
#end
#implementation XYZToDoListViewController
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
XYZAddItemViewController *source = [segue sourceViewController];
XYZToDoItem *item = source.toDoItem;
if (item != nil) {
[self.toDoItems addObject:item];
[self.tableView reloadData];
}
}
- (IBAction)clearData:(UIBarButtonItem *)sender;
{
[self.toDoItems removeAllObjects];
[self.tableView reloadData];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.toDoItems = [[NSMutableArray alloc] init];
self.navigationController.view.backgroundColor =
[UIColor colorWithPatternImage:[UIImage imageNamed:#"bg_full.png"]];
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, -35, 0);
}
#end
This is at least what I think is relevant. My basic framework is something I followed from this tutorial. So as you can see I have an NSMutableArray named .toDoItems. and I want it to remember the list when I exit the application (not just minimizing it; it does that already. I think I have the code which is saving the data, but what do I use to check if the file exists, and if so, display it?
And would this affect my clearData method when the app resumes as well?
As if i understood true you want to save your NSMutableArray even after restart your app.
So you may use this codes to save your NSMutableArray with NSUserDefaults.
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaultsPhoneId setObject:yourArray forKey:#"yourKey"];
[defaultsPhoneId synchronize];
And it is how you can take it back
yourArray=[[NSMutableArray alloc]initWithArray:[[NSUserDefaults standardUserDefaults]objectForKey:#"yourKey"]];
But dont forget to initialize it before save with NSUserDefaults.
By the way you may check yourArray anytime if it is loaded or not with
if([yourArray count]==0){
//Your array is empty so you have to call it with #"yourKey". (second codes part)
}
"what do I use to check if the file exists"
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:your_file_path])
"..and if so, display it?"
Please read about UITableView and UITableViewDataSource
https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html
"And would this affect my clearData method when the app resumes as well?"
clearData is a button action. It will be called only if user will tap
a button. It is not connected with application launch/stopping.
When a user run my app for the first time a LoginViewController appears. Once he is logged in, I present a ModalViewController with all the stuff of the app. If the user want to log out, I dismiss the modal view, showing the LoginViewController again.
The problem comes if the user runs the app when is already logged. In the self.window.rootViewController, I set directly the main view of the app (embebed in a UITabBarController), so if the user want to log out, I don't know the way to "dismiss" the view and show the LoginViewController.
SCENARIO:
User no logged yet: LoginViewController -> (Log in) -> UITabBarController -> (Log out) -> LoginViewController.
User already logged: UITabBarController -> (Log out) -> LoginViewController.
I think there must be a simple way to do this, because it is a very normal behavior in an app with a login system, but I haven't found a clean way to do it.
After struggling with this many times, we published an open source library called CLHoppingViewController which handles exactly this kind of scenarios.
So, in your case, you would do something like this to describe the start up flow:
UIViewController *loginViewController;
UIViewController *mainViewController;
if (user_not_logged_in) {
[self hopToViewController:loginViewController then:^{
[self hopToViewController:mainViewController then:nil];
}];
}
else {
[self hopToViewController:mainViewController then:nil];
}
The library can support much more advanced conditional sequences. For example, you can display a splash screen, conditionally show onboarding UX, etc.
There's a short tutorial here.
Try following way :
TabBarController *tabBarController1 = [[TabBarController alloc] init];
self.window.rootViewController = tabBarController1.myTabBarController;
[self.window makeKeyAndVisible];
// if not Logedin
if() {
self.viewController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.tabBarController1 presentModalViewController:navController animated:NO];
}
After Login, dismiss LoginViewController. Again while logout present LoginViewController modally on tabBarViewController as above.
I did this:
App Delegate:
if() //signed in
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
TabBarController *tabBarController1 = [[TabBarController alloc] init];
self.window.rootViewController = tabBarController1.myTabBarController;
[self.window makeKeyAndVisible];
}
else //signed out
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[SigninTabBarTemplateViewController alloc] initWithNibName:#"SigninTabBarTemplateViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
}
If you are signed out, I implement the tabbarcontroller as a separate UITabBarController like that:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIViewController *viewController1 = [[FirstTab alloc] initWithNibName:#"FirstTab" bundle:NSBundle.mainBundle];
UINavigationController *firstNavController = [[UINavigationController alloc]initWithRootViewController:viewController1];
UIViewController *viewController2 = [[SecondTab alloc] initWithNibName:#"SecondTab" bundle:NSBundle.mainBundle];
UINavigationController *secondNavController = [[UINavigationController alloc]initWithRootViewController:viewController2];
myTabBarController = [[UITabBarController alloc] init];
myTabBarController.viewControllers = [NSArray arrayWithObjects:firstNavController, secondNavController, nil];
}
return self;
}
An elegant way to handle login states is to use a statemachine. The principle is, to define all possible states and the transitions between them. This might seem like an overkill on the first look, but as larger as your app grows, this investment will pay off.
For small apps, the if/else way should be fine.
#import <UIKit/UIKit.h>
#import "EditInfoViewController.h"
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, EditInfoViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UITableView *tblPeople;
- (IBAction)addNewRecord:(id)sender;
#end
#import "ViewController.h"
#import "DBManager.h"
#interface ViewController ()
#property (nonatomic, strong) DBManager *dbManager;
#property (nonatomic, strong) NSArray *arrPeopleInfo;
#property (nonatomic) int recordIDToEdit;
-(void)loadData;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Make self the delegate and datasource of the table view.
self.tblPeople.delegate = self;
self.tblPeople.dataSource = self;
// Initialize the dbManager property.
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"sampledb.sql"];
// Load the data.
[self loadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
EditInfoViewController *editInfoViewController = [segue destinationViewController];
editInfoViewController.delegate = self;
editInfoViewController.recordIDToEdit = self.recordIDToEdit;
}
#pragma mark - IBAction method implementation
- (IBAction)addNewRecord:(id)sender {
// Before performing the segue, set the -1 value to the recordIDToEdit. That way we'll indicate that we want to add a new record and not to edit an existing one.
self.recordIDToEdit = -1;
// Perform the segue.
[self performSegueWithIdentifier:#"idSegueEditInfo" sender:self];
}
#pragma mark - Private method implementation
-(void)loadData{
// Form the query.
NSString *query = #"select * from peopleInfo";
// Get the results.
if (self.arrPeopleInfo != nil) {
self.arrPeopleInfo = nil;
}
self.arrPeopleInfo = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
// Reload the table view.
[self.tblPeople reloadData];
}
#pragma mark - UITableView method implementation
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.arrPeopleInfo.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Dequeue the cell.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"idCellRecord" forIndexPath:indexPath];
NSInteger indexOfFirstname = [self.dbManager.arrColumnNames indexOfObject:#"firstname"];
NSInteger indexOfLastname = [self.dbManager.arrColumnNames indexOfObject:#"lastname"];
NSInteger indexOfAge = [self.dbManager.arrColumnNames indexOfObject:#"age"];
// Set the loaded data to the appropriate cell labels.
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfFirstname], [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfLastname]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Age: %#", [[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:indexOfAge]];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60.0;
}
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
// Get the record ID of the selected name and set it to the recordIDToEdit property.
self.recordIDToEdit = [[[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:0] intValue];
// Perform the segue.
[self performSegueWithIdentifier:#"idSegueEditInfo" sender:self];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the selected record.
// Find the record ID.
int recordIDToDelete = [[[self.arrPeopleInfo objectAtIndex:indexPath.row] objectAtIndex:0] intValue];
// Prepare the query.
NSString *query = [NSString stringWithFormat:#"delete from peopleInfo where peopleInfoID=%d", recordIDToDelete];
// Execute the query.
[self.dbManager executeQuery:query];
// Reload the table view.
[self loadData];
}
}
#pragma mark - EditInfoViewControllerDelegate method implementation
-(void)editingInfoWasFinished{
// Reload the data.
[self loadData];
}
#end
===================
#import <UIKit/UIKit.h>
#protocol EditInfoViewControllerDelegate
-(void)editingInfoWasFinished;
#end
#interface EditInfoViewController : UIViewController <UITextFieldDelegate>
#property (nonatomic, strong) id<EditInfoViewControllerDelegate> delegate;
#property (weak, nonatomic) IBOutlet UITextField *txtFirstname;
#property (weak, nonatomic) IBOutlet UITextField *txtLastname;
#property (weak, nonatomic) IBOutlet UITextField *txtAge;
#property (nonatomic) int recordIDToEdit;
- (IBAction)saveInfo:(id)sender;
#end
#import "EditInfoViewController.h"
#import "DBManager.h"
#interface EditInfoViewController ()
#property (nonatomic, strong) DBManager *dbManager;
-(void)loadInfoToEdit;
#end
#implementation EditInfoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Make self the delegate of the textfields.
self.txtFirstname.delegate = self;
self.txtLastname.delegate = self;
self.txtAge.delegate = self;
// Set the navigation bar tint color.
self.navigationController.navigationBar.tintColor = self.navigationItem.rightBarButtonItem.tintColor;
// Initialize the dbManager object.
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"sampledb.sql"];
// Check if should load specific record for editing.
if (self.recordIDToEdit != -1) {
// Load the record with the specific ID from the database.
[self loadInfoToEdit];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#pragma mark - UITextFieldDelegate method implementation
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
#pragma mark - IBAction method implementation
- (IBAction)saveInfo:(id)sender {
// Prepare the query string.
// If the recordIDToEdit property has value other than -1, then create an update query. Otherwise create an insert query.
NSString *query;
if (self.recordIDToEdit == -1) {
query = [NSString stringWithFormat:#"insert into peopleInfo values(null, '%#', '%#', %d)", self.txtFirstname.text, self.txtLastname.text, [self.txtAge.text intValue]];
}
else{
query = [NSString stringWithFormat:#"update peopleInfo set firstname='%#', lastname='%#', age=%d where peopleInfoID=%d", self.txtFirstname.text, self.txtLastname.text, self.txtAge.text.intValue, self.recordIDToEdit];
}
// Execute the query.
[self.dbManager executeQuery:query];
// If the query was successfully executed then pop the view controller.
if (self.dbManager.affectedRows != 0) {
NSLog(#"Query was executed successfully. Affected rows = %d", self.dbManager.affectedRows);
// Inform the delegate that the editing was finished.
[self.delegate editingInfoWasFinished];
// Pop the view controller.
[self.navigationController popViewControllerAnimated:YES];
}
else{
NSLog(#"Could not execute the query.");
}
}
#pragma mark - Private method implementation
-(void)loadInfoToEdit{
// Create the query.
NSString *query = [NSString stringWithFormat:#"select * from peopleInfo where peopleInfoID=%d", self.recordIDToEdit];
// Load the relevant data.
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
// Set the loaded data to the textfields.
self.txtFirstname.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:#"firstname"]];
self.txtLastname.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:#"lastname"]];
self.txtAge.text = [[results objectAtIndex:0] objectAtIndex:[self.dbManager.arrColumnNames indexOfObject:#"age"]];
}
#end
=====
===================
#import <Foundation/Foundation.h>
#interface DBManager : NSObject
#property (nonatomic, strong) NSMutableArray *arrColumnNames;
#property (nonatomic) int affectedRows;
#property (nonatomic) long long lastInsertedRowID;
-(instancetype)initWithDatabaseFilename:(NSString *)dbFilename;
-(NSArray *)loadDataFromDB:(NSString *)query;
-(void)executeQuery:(NSString *)query;
#end
#import "DBManager.h"
#import <sqlite3.h>
#interface DBManager()
#property (nonatomic, strong) NSString *documentsDirectory;
#property (nonatomic, strong) NSString *databaseFilename;
#property (nonatomic, strong) NSMutableArray *arrResults;
-(void)copyDatabaseIntoDocumentsDirectory;
-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable;
#end
#implementation DBManager
#pragma mark - Initialization
-(instancetype)initWithDatabaseFilename:(NSString *)dbFilename{
self = [super init];
if (self) {
// Set the documents directory path to the documentsDirectory property.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
// Keep the database filename.
self.databaseFilename = dbFilename;
// Copy the database file into the documents directory if necessary.
[self copyDatabaseIntoDocumentsDirectory];
}
return self;
}
#pragma mark - Private method implementation
-(void)copyDatabaseIntoDocumentsDirectory{
// Check if the database file exists in the documents directory.
NSString *destinationPath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
if (![[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
// The database file does not exist in the documents directory, so copy it from the main bundle now.
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseFilename];
NSError *error;
[[NSFileManager defaultManager] copyItemAtPath:sourcePath toPath:destinationPath error:&error];
// Check if any error occurred during copying and display it.
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}
}
-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable{
// Create a sqlite object.
sqlite3 *sqlite3Database;
// Set the database file path.
NSString *databasePath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
// Initialize the results array.
if (self.arrResults != nil) {
[self.arrResults removeAllObjects];
self.arrResults = nil;
}
self.arrResults = [[NSMutableArray alloc] init];
// Initialize the column names array.
if (self.arrColumnNames != nil) {
[self.arrColumnNames removeAllObjects];
self.arrColumnNames = nil;
}
self.arrColumnNames = [[NSMutableArray alloc] init];
// Open the database.
BOOL openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
if(openDatabaseResult == SQLITE_OK) {
// Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement.
sqlite3_stmt *compiledStatement;
// Load all data from database to memory.
BOOL prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &compiledStatement, NULL);
if(prepareStatementResult == SQLITE_OK) {
// Check if the query is non-executable.
if (!queryExecutable){
// In this case data must be loaded from the database.
// Declare an array to keep the data for each fetched row.
NSMutableArray *arrDataRow;
// Loop through the results and add them to the results array row by row.
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Initialize the mutable array that will contain the data of a fetched row.
arrDataRow = [[NSMutableArray alloc] init];
// Get the total number of columns.
int totalColumns = sqlite3_column_count(compiledStatement);
// Go through all columns and fetch each column data.
for (int i=0; i<totalColumns; i++){
// Convert the column data to text (characters).
char *dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);
// If there are contents in the currenct column (field) then add them to the current row array.
if (dbDataAsChars != NULL) {
// Convert the characters to string.
[arrDataRow addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
// Keep the current column name.
if (self.arrColumnNames.count != totalColumns) {
dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i);
[self.arrColumnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
}
// Store each fetched data row in the results array, but first check if there is actually data.
if (arrDataRow.count > 0) {
[self.arrResults addObject:arrDataRow];
}
}
}
else {
// This is the case of an executable query (insert, update, ...).
// Execute the query.
BOOL executeQueryResults = sqlite3_step(compiledStatement);
if (executeQueryResults == SQLITE_DONE) {
// Keep the affected rows.
self.affectedRows = sqlite3_changes(sqlite3Database);
// Keep the last inserted row ID.
self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database);
}
else {
// If could not execute the query show the error message on the debugger.
NSLog(#"DB Error: %s", sqlite3_errmsg(sqlite3Database));
}
}
}
else {
// In the database cannot be opened then show the error message on the debugger.
NSLog(#"%s", sqlite3_errmsg(sqlite3Database));
}
// Release the compiled statement from memory.
sqlite3_finalize(compiledStatement);
}
// Close the database.
sqlite3_close(sqlite3Database);
}
#pragma mark - Public method implementation
-(NSArray *)loadDataFromDB:(NSString *)query{
// Run the query and indicate that is not executable.
// The query string is converted to a char* object.
[self runQuery:[query UTF8String] isQueryExecutable:NO];
// Returned the loaded results.
return (NSArray *)self.arrResults;
}
-(void)executeQuery:(NSString *)query{
// Run the query and indicate that is executable.
[self runQuery:[query UTF8String] isQueryExecutable:YES];
}
#end
enter code here
#interface ViewController ()
{ sqlite3 *dbref;
NSString *dbpath;
BOOL flag;}
#end
#implementation ViewController
#synthesize usertxt,passtxt;
- (void)viewDidLoad
{[super viewDidLoad];
NSString *docpath;
NSError *error;
NSArray *docarr=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"directory path=%#",docarr);
docpath=[docarr objectAtIndex:0];
// docpath=[docpath stringByAppendingString:#"/simpledb.sqlite/"];
[[NSFileManager defaultManager] createDirectoryAtPath:docpath withIntermediateDirectories:YES attributes:nil error:&error];
dbpath=[[NSString alloc] initWithString:[docpath stringByAppendingString:#"/simpledb.sqlite"]];
NSFileManager *fmgr=[NSFileManager defaultManager];
if([fmgr fileExistsAtPath:dbpath]!=YES)
{ char *err;
const char *dbp=[dbpath UTF8String];
if(sqlite3_open(dbp, &dbref)==SQLITE_OK)
{ const char *crstmt = "CREATE TABLE IF NOT EXISTS Login(Login_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,Username TEXT , Password TEXT)";
if(sqlite3_exec(dbref, crstmt, NULL, NULL,&err)!= SQLITE_OK)
{
}
sqlite3_close(dbref);
}}
// Do any additional setup after loading the view, typically from a nib.
}
-(IBAction)save:(id)sender
{[self validation];
if(flag==0)
{ sqlite3_stmt *statement;
NSString *insertSQL = [NSString stringWithFormat:#"insert into Login(Username,Password) values('%#','%#')",usertxt.text,passtxt.text];
const char *insert_stmt = [insertSQL UTF8String];
const char *dbp=[dbpath UTF8String];
if(sqlite3_open(dbp, &dbref)==SQLITE_OK)
{ sqlite3_prepare_v2(dbref, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
}
else
{
}}
sqlite3_finalize(statement);
sqlite3_close(dbref);
UIAlertView *objalert=[[UIAlertView alloc]initWithTitle:#"Inserted Successfully" message:nil delegate:nil cancelButtonTitle:#"cancel" otherButtonTitles:#"ok", nil];
[objalert show];
}}
-(IBAction)update:(id)sender
{ NSString *querySQL = [NSString stringWithFormat: #"update Login set Username='%#',Password='%#' where Login_id==1",usertxt.text,passtxt.text];
[self updateQuery:querySQL];}
-(BOOL)updateQuery:(NSString *)querySQL
{ sqlite3_stmt *statement;
const char *dbp=[dbpath UTF8String];
if(sqlite3_open(dbp, &dbref)==SQLITE_OK)
{ const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(dbref, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{ if (sqlite3_step(statement) == SQLITE_ROW)
{ sqlite3_reset(statement);
return YES;
} }
sqlite3_finalize(statement);
sqlite3_close(dbref)}
else
{ return NO;
}
return YES}
-(void)validation
{ NSString *valida;
// usertxt.text = [usertxt.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// passtxt.text = [passtxt.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([usertxt.text length]<2)
{flag=1;
valida=#"user Name : Minimum 2 Character req*\n";
UIAlertView *objalert=[[UIAlertView alloc]initWithTitle:nil message:valida delegate:nil cancelButtonTitle:nil otherButtonTitles:#"ok", nil];
[objalert show];
}
}
#imp flipsideviewcont
#syn entries
-(void)viewdidload
{
entries=[[nsmutablarray alloc]onit];
[self opendb];
nsstring *sql=[nsstring stringwithormat:#"select * from summery"];
sqlite_state *stat;
if(sqlite_prepare_v2(db,[sql utf8string],-1,&stat,nil)==sqlite_ok)
{while(sqlite_step(stat==sqlite_row))
{
char *field1=(char*)sqlite_column_text(stat,0);
nsstring *field1str=[[nsstring alloc]initwithutf8string:feild1];
char *field2=(char*)sqlite_column_text(stat,1);
nsstring *field2str=[[nsstring alloc]initwithutf8string:feild2];
nsstring *str=[[nsstring alloc]initwithformat:#"%#/%#-%#",field2str,field3str,field4str];
[entries addobjects:str];
}
-(nsstring*)filepath
{
nsarray *path=nssearchpathfordocumentry(nsdocumentdic,nsdomainmask,yes);
return([path objectAtindex:0]stringbyappingpathcomp:#"ss.sql");
}
-(void)opendb
{
if(sqlite_open([self filepath]utf8string,&db)!=sqlite_ok)
{sqlite_close(db);
nsasser(0,#"problem");
else
{
nslog(#"db open");
}
}
-(ibaction)done
{
[self.delegate flipsideviewcontrollerdidfinish :self];
}
cellforindex
{
cell.textlabel.text=[self.entries objectAtindex:indexpath:row];
}
===========================interface flipsideviewcont======
#import "sqlite3.h"
#class flipsideviewcontroller;
-(void)flipsideviewcontdidfinish:(flipsideviewcontroller*)controller;
#end
#interface flipsideviewcont:viewcont
{
sqlite *db;
}
#property()id<flipsideviewcontrollerdelegate>delegate;
#property()nsmutablearray *entries;
-(void)opendb;
-(nsstring*)filepath;
}
======================
#interface mainviewcontroller:viewcontroller<flipsideviewcontrollerdelegate>
{sqlite3 *db;}
#property()iboutlet nstextfiled *systext,*diatext,*commenttxt;
#property(readpnly,non)nsdate *currentdate;
-(void)createTable:(nsstring*)tablename
withfield1:(nsstring*)field1 withfield2:(nsstring*)field2 withfield3:(nsstring*)field3 withfield4:(nsstring*)field4;
-(ibaction)saveentry;
#implement mainview
-(void)createTable:(nsstring*)tablename
withfield1:(nsstring*)field1 withfield2:(nsstring*)field2 withfield3:(nsstring*)field3 withfield4:(nsstring*)field4
{
char *err;
nastring *sql=[nsstring stringwithformat:#"crete table if nat exist '%#'('%#'""text primary key,'%#' int,'%#' int,'%#'text);",tablename,field1,field2,field3,field4);
if(sqlite_exe(db,[sql utf*string],null,null,&err)!=sqlite_ok)
{sqlite_close(db);
}}
-(void)opendb;
{}
-(nsstring*)filepath()
-(void)viewdidload
{[self opendb];
[self createtable:#"summery" withfield:#"thedate withfield2:#"systonic"];}
-(ibaction)saveenrty
{
int sys=[systext.text intvalue];
int dia=[diatext.text intvalue];
nsstring *comm=comtext.tex;
nsdate *thedate=[nsdate date];
nsstring *sql=[nsstring stringwithformat:#"insert into summery('sys','thedate','dia',''com')values('%#','%d','%d','%#')",thedate,sys,dia,comm];
{sqlite_close(db);
}
systext.text="";
didtext.text="";
commtext.text="";
}
}
-(void)prepareforsegue
{if([[segue identifier]isequalto string:#"showwale");
{[[segue destinationviewcont]setdelegate:self];
}
}
-(void)flipsideviewcontdidfinish
{[self dismissviewcontroller:yes];
}
}
}