Connecting SQlite3 to UITextview - iphone

I am doing an iPad app, were i will have UITabelview and a Button and UiTextview in same screen. My task is that if i select some row in UITableview and press button the text has to be appeared on the UITextview.
I filled few methods but it didn't work can any one let me know what exactly i can do to complete this task successfully.
Please find my code below for your reference...it may help you to explain my problem.
#import <UIKit/UIKit.h>
#import "table1.h"
#import "textView.h"
#interface searchOne : UIViewController
{
IBOutlet UITableView *firstTable;
table1 *tableOne;
textView * text1;
int row;
}
#property(nonatomic,retain)IBOutlet UIButton * search;
#property (nonatomic,retain) IBOutlet UITextView *txt;
#property(nonatomic, assign) int row;
-(IBAction)resPage:(id)sender;
#end
#import "searchOne.h"
#import "textView.h"
#implementation searchOne
#synthesize search;
#synthesize txt, row;
- (void)viewDidLoad {
[super viewDidLoad];
if (tableOne == nil) {
tableOne = [[table1 alloc] init];
}
[firstTable setDataSource:tableOne];
tableOne.view = tableOne.tableView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
row = [indexPath row];
}
-(IBAction)resPage:(id)sender{
NSString *str = txt.text;
row = [str intValue];
NSLog(#"get clicked");
self.view =txt;
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// [self setTxt:nil];
[super viewDidUnload];
}
#end
DB:
#import <Foundation/Foundation.h>
#interface db : NSObject{
NSInteger ID;
NSString * name;
}
#property (nonatomic, retain) NSString * name;
#property(nonatomic, readwrite) NSInteger ID;
-(id)initWithID: (NSInteger)i andName:(NSString *)n;
#end
#implementation db
#synthesize name,ID;
-(id)initWithID: (NSInteger)i andName:(NSString *)n{
self=[super init];
if(self)
{
self.ID = i;
self.name = n;
}
return self;
}
#end
Tabel view:
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#import "db.h"
#interface table1 : UITableViewController<UITableViewDataSource>{
NSString *databaseName;
NSString * databasePath;
NSMutableArray * tableOne;
}
#property(nonatomic, retain) NSMutableArray * tableOne;
-(void)checkAndCreateDatabase;
-(void)readDataFromDatabase;
#end
#import "table1.h"
#import "db.h"
#implementation table1
#synthesize tableTwo;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
databaseName=#"nobel10.db";
NSArray *documentPaths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDir = [documentPaths objectAtIndex:0];
databasePath=[documentDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - TableView Data Source methods
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableTwo count]; }
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell= nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"mycell"];
if (cell == nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"mycell"];}
db * temp =(db *)[self.tableTwo objectAtIndex:indexPath.row];
cell.textLabel.text=temp.name;
return cell;
}
-(void)checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager=[NSFileManager defaultManager];
success=[fileManager fileExistsAtPath:databasePath];
if(success)
return;
NSString *databasePathFromApp = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
-(void)readDataFromDatabase{
sqlite3 *database;
tableTwo=[[NSMutableArray alloc]init];
if(sqlite3_open([databasePath UTF8String], &database)== SQLITE_OK){
const char *sqlStatement = "SELECT * FROM country";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL)==SQLITE_OK){
while (sqlite3_step(compiledStatement)==SQLITE_ROW) {
NSInteger pId = sqlite3_column_int(compiledStatement, 0);
NSString *stringName=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
db *info =[[db alloc]initWithID:pId andName:stringName];
[tableTwo addObject:info];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
#end
UITextView:
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#import "db.h"
#interface textView : UIViewController<UITextViewDelegate>{
NSString *databaseName;
NSString * databasePath;
NSMutableArray *textOne;
NSString *description;
}
#property(nonatomic, retain) NSMutableArray *textOne;
#property (nonatomic, retain) NSString *description;
-(void)checkAndCreateDatabase;
-(void)readDataFromDatabase;
-(id)initWithDescription:(NSString *)d;
#end
#import "textView.h"
#implementation textView
#synthesize textOne, description;;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
databaseName=#"nobel10.db";
NSArray *documentPaths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDir = [documentPaths objectAtIndex:0];
databasePath=[documentDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - TableView Data Source methods
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
-(void)checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager=[NSFileManager defaultManager];
success=[fileManager fileExistsAtPath:databasePath];
if(success)
return;
NSString *databasePathFromApp = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
-(void)readDataFromDatabase{
sqlite3 *database;
textOne=[[NSMutableArray alloc]init];
if(sqlite3_open([databasePath UTF8String], &database)== SQLITE_OK){
const char *sqlStatement = "SELECT name,item_country.id,text.item FROM country,item_country,text WHERE country.name ='India' AND country.id = item_country.id AND text.item =item_country.item ";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL)==SQLITE_OK){
while (sqlite3_step(compiledStatement)==SQLITE_ROW) {
NSInteger pId = sqlite3_column_int(compiledStatement, 0);
NSString *stringName=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
db *info =[[db alloc]initWithID:pId andName:stringName];
[textOne addObject:info];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
-(id)initWithDescription:(NSString *)d{
self.description = d;
return self;
}
#end
PLease help me i am new to iPad development and struck here..

A quick and dirty way is just to remove the UITextView, and add it back in when you select the row. See if that works.

I realize this is not the question you asked, but depending on your needs, you might want to use Core Data instead. It abstracts the .sqlite database from you and does some pretty cool things in terms of memory usage, modelling objects and relationships and so on.

Related

Get Address Book data it's code run on simulator but didn't run iPhone Device.

I have got a address book data into the tableView in my application.This code is running in simulator successfully. i got the data of contacts in the tableView of my app in simulator but when i test this in my device then data of contacts didn't get. I used 6.1 simulator and iPhone device ios 6.1.3. Please suggest me what is the actual problem in this code ?
This code is run in simulator successfully but it's code didn't run in iPhone device iOS 6.1.3
Thanks You
ClsMainPageAppDelegate.h
#import <UIKit/UIKit.h>
#import "Person.h"
#interface ClsMainPageAppDelegate : UIResponder <UIApplicationDelegate>
{
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) Person *objPerson;
#end
ClsMainPageAppDelegate.m
#import "ClsMainPageAppDelegate.h"
#import "ClsMainPageViewController.h"
#implementation ClsMainPageAppDelegate
#synthesize objPerson;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
}
Person.h
#import <Foundation/Foundation.h>
#interface Person : NSObject
#property (nonatomic, strong) NSString *firstName;
#property (nonatomic, strong) NSString *lastName;
#property (nonatomic, strong) NSString *fullName;
#property (nonatomic, strong) NSString *phoneNumber;
#property (nonatomic, strong) NSString *workEmail;
#end
Person.m
#import "Person.h"
#implementation Person
- (id)init
{
self = [super init];
if (self)
{
}
return self;
}
#end
ClsAddressBookViewController.h
#import <UIKit/UIKit.h>
#interface ClsAddressBookViewController : UIViewController
- (IBAction)backcontacts:(id)sender;
#end
ClsAddressBookViewController.m
#import "ClsAddressBookViewController.h"
#import "ClsUpdateNetworkViewController.h"
#import "ClsMainPageAppDelegate.h"
#import "Person.h"
#import <AddressBook/AddressBook.h>
#interface ClsAddressBookViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) NSMutableArray *tableData;
#end
#implementation ClsAddressBookViewController
#synthesize tableData;
- (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.
self.title = #"Contacts";
self.tableData = [[NSMutableArray alloc]init];
[self getPersonOutOfAddressBook];
}
- (void)getPersonOutOfAddressBook
{
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (addressBook != nil)
{
NSLog(#"Succesful.");
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSUInteger i = 0;
for (i = 0; i < [allContacts count]; i++)
{
Person *person = [[Person alloc] init];
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
NSString *fullName = [NSString stringWithFormat:#"%# %#", firstName, lastName];
person.firstName = firstName;
person.lastName = lastName;
person.fullName = fullName;
//Mobile Number
ABMultiValueRef mobilenum = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
NSUInteger k = 0;
for(k = 0; k < ABMultiValueGetCount(mobilenum); k++)
{
NSString *mobile = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(mobilenum, k);
if(k == 0)
{
person.phoneNumber = mobile;
NSLog(#"person.mobilenum = %#", person.phoneNumber);
}
else if (k==1)
person.phoneNumber = mobile;
}
[self.tableData addObject:person];
}
}
CFRelease(addressBook);
}
#pragma mark TableView Delegate
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.tableData count];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
Person *person = [self.tableData objectAtIndex:indexPath.row];
cell.textLabel.text = person.fullName;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Person *person = [self.tableData objectAtIndex:indexPath.row];
ClsMainPageAppDelegate *objdelegate = [[UIApplication sharedApplication]delegate];
objdelegate.objPerson = person;
UIStoryboard *storybrd = self.storyboard;
ClsAddressBookViewController *svc = [storybrd instantiateViewControllerWithIdentifier:#"clsUpdatecontrol"];
[self presentViewController:svc animated:YES completion:nil ];
}
From IOS 6. it need to authorize your apps for to access system datas :
In settings on your IPhone in confidentiality tab and contact section, verify if your app has acces is "on"
To continue TDelepine's suggestion, perhaps in your getPersonOutOfAddressBook method, you can check if your app has AddressBook access. The code below will force the device to ask the user for access if access status has not been determined:
...
NSLog(#"Succesful.");
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if(granted) {
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
etc...
}
});
}
I think you're not sending request for access Address Book. One other thing If you're not using this then It's work properly in simulator but not working in iPhone
Use this code in ViewDidLoad
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// dispatch_release(sema);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted) {
// Do whatever you want here.
}

Save data on form and display using table view using DB

I am creating an email signature, i have made two view's till now "ViewController and "ListView" coding is like this
ViewController.h
#import <UIKit/UIKit.h>
#import "ListView.h"
#import "sqlite3.h"
#interface ViewController:UIViewController<UITextViewDelegate,UIImagePickerControllerDelegate>
{
UIImageView *imageView;
UIImage *signimage;
UIImagePickerController *imagePicker;
NSMutableArray *hello;
NSMutableArray *hellocontent;
ListView *listview;
UITextField *signaturename;
UITextView *textView; // UITextView *scontent;
// IBOutlet UIScrollView *scrollview;
// BOOL keyboardIsShown;
//IBOutlet UITextField *recordTextField;
NSString *databasePath;
sqlite3 *Dummy2;
}
#property(nonatomic,retain) IBOutlet UIImageView *imageView;
#property(nonatomic,retain) UIImage *signimage;
-(IBAction)btnLoadImage:(id) sender;
-(IBAction)clearFields:(id)sender;
-(IBAction)show:(id)sender;
// #property (nonatomic,retain) UITextField *recordsTextField;
//#property(nonatomic,retain) IBOutlet UIScrollView *scrollview;
#property(nonatomic, retain) IBOutlet UITextField *signaturename;
#property(nonatomic, retain) IBOutlet UITextView *textView; // scontent
-(IBAction) btnsave:(id) sender;
-(IBAction) keyboard:(id) sender;
-(IBAction)next:(id)sender;
-(IBAction) bgtouch:(id) sender;
// -(IBAction)show:(id)sender;
// -(IBAction)records:(id)s;
// -(IBAction)updateQuery:(id)sender;
//Static methods.
+ (void) getInitialDataToDisplay:(NSString *)dbPath;
+ (void) finalizeStatements;
//Instance methods.
- (id) initWithPrimaryKey:(NSInteger)pk;
- (void) saveAllData;
#end
ViewController.m
#import "ViewController.h"
#import"ListView.h"
#implementation ViewController
#synthesize signaturename,imageView,textView,signimage; // recordsTextField
// scrollview;
-(IBAction)next:(id)sender{
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
hello = [[NSMutableArray alloc]init];
// hellocontent = [[NSMutableArray alloc]init];
if (sqlite3_open(dbpath, &Dummy2) == SQLITE_OK)
{
NSString *updateSQL = #"SELECT * FROM PROFILE";
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(Dummy2, update_stmt, -1, &statement, NULL);
while(sqlite3_step(statement) == SQLITE_ROW) {
[hello addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]];
// [hellocontent addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)]];
}
sqlite3_finalize(statement);
sqlite3_close(Dummy2);
}
listview = [[ListView alloc]initWithNibName:#"ListView" bundle:nil];
listview.arr=[[NSMutableArray alloc]init];
listview.arr = hello;
[self.view addSubview:listview.view];
}
- (void)setCoffeeImage:(UIImage *)theCoffeeImage {
// self.isDirty = YES;
[signimage release];
signimage = [theCoffeeImage retain];
}
-(IBAction) btnsave:(id) sender
{
if (([self.signaturename.text length] && [self.textView.text length]) != 0) {
// NSData *data = UIImagePNGRepresentation(self.signimage);
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
hello = [[NSMutableArray alloc]init];
if (sqlite3_open(dbpath, &Dummy2) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO profile (sname,scontent) VALUES (\"%#\", \"%#\")", signaturename.text,textView.text];
const char *insert_stmt = [insertSQL UTF8String];
// sqlite3_bind_blob(statement, 3, [data bytes], [data length], NULL);
sqlite3_prepare_v2(Dummy2, insert_stmt, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
// status.text = #"Contact added";
signaturename.text = #""; //address.text = #"";
textView.text = #"";
// imageUrl.text=#"";
} else {
// status.text = #"Failed to add contact";
}
sqlite3_finalize(statement);
sqlite3_close(Dummy2);
}
}
else
{
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Warning" message:#"Signature Name and Content Field Should Not Be Empty" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}
-(IBAction)show:(id)sender{
const char *dbpath = [databasePath UTF8String];
sqlite3_stmt *statement;
if (sqlite3_open(dbpath, &Dummy2) == SQLITE_OK)
{
NSString *querySQL = [NSString stringWithFormat: #"SELECT sname, scontent FROM profile WHERE sname=\"%#\"", signaturename.text];
const char *query_stmt = [querySQL UTF8String];
if (sqlite3_prepare_v2(Dummy2, query_stmt, -1, &statement, NULL) == SQLITE_OK)
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
textView.text = addressField;
// status.text = #"Match found";
[addressField release];
} else {
// status.text = #"Match not found";
textView.text = #"";
}
sqlite3_finalize(statement);
}
sqlite3_close(Dummy2);
}
}
-(IBAction)clearFields:(id)sender
{
signaturename.text=#"";
textView.text=#"";
NSLog(#"clear is working");
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
-(IBAction) bgtouch:(id) sender
{
[signaturename resignFirstResponder];
// [textView resignFirstResponder];
}
-(IBAction) keyboard:(id)sender
{
[sender resignFirstResponder];
// [self.signaturecontent resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
imagePicker =[[UIImagePickerController alloc]init];
[super viewDidLoad];
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: #"Dummy2.sqlite"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &Dummy2) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS profile(ID INTEGER PRIMARY KEY AUTOINCREMENT, SNAME TEXT, SCONTENT TEXT)";
if (sqlite3_exec(Dummy2, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
// status.text = #"Failed to create table";
}
sqlite3_close(Dummy2);
} else {
// status.text = #"Failed to open/create database";
}
}
[filemgr release];
// Do any additional setup after loading the view, typically from a nib.
}
-(IBAction)btnLoadImage:(id)sender
{
imagePicker.delegate =self;
imagePicker.sourceType =UIImagePickerControllerSourceTypePhotoLibrary;
// show the image picker
[self presentModalViewController:imagePicker animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *image;
NSURL *mediaUrl;
mediaUrl =(NSURL *)[info valueForKey:UIImagePickerControllerMediaURL];
if(mediaUrl == nil){
image = (UIImage *)[info valueForKey:UIImagePickerControllerEditedImage];
if(mediaUrl == nil){
// original image selected
image =(UIImage *)[info valueForKey:UIImagePickerControllerOriginalImage];
// display the image
imageView.image = image;
}
else {
// edited image picked
CGRect rect = [[info valueForKey:UIImagePickerControllerCropRect]CGRectValue];
// display the image
imageView.image = image;
}
}
// hide the image picker
[picker dismissModalViewControllerAnimated:YES];
}
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
// user did not select image; hide the image picker
[picker dismissModalViewControllerAnimated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
ListView.h
#import <UIKit/UIKit.h>
#interface ListView : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
NSMutableArray *arr;
}
#property(nonatomic,retain) NSMutableArray *arr;
-(IBAction)back:(id)sender;
#end
ListView.m
#import "ListView.h"
#implementation ListView
#synthesize arr;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(IBAction)back:(id)sender
{
[super.view removeFromSuperview];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return 6;
return [arr count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSString *cellvalue = [arr objectAtIndex:indexPath.row];
cell.textLabel.text=cellvalue;
// Configure the cell.
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Database "Dummy2.sql" is like this
PROFILE = table
id = field = INTEGER PRIMARY KEY
sname = field = TEXT
scontent = field = TEXT
simage = field = BLOB
Schema
CREATE TABLE PROFILE(id INTEGER PRIMARY KEY, sname TEXT, scontent TEXT, simage BLOB)
This is what i have done so far, what should i code in didselectrowAtIndexpath so that when i select any name from table it should appear in textview in "ListView.xib" ... any help also i am not able to save the image in DB i have to show the image also according to the name selected from tableView in "ListView.xib" so that in bottom section i can see the image and content of that name in UIimage and in textview field .. any idea ??
If you want to pass the name to ListView just use the code below:
Create a object class for holding all data about a person like.
#interface Person
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *content;
#property (nonatomic, assign) int profileId;
#end
#implementation Person
#synthesize name,content;
#synthesize profileId;
#end
change the data fetching method like:
Person *person = nil;
NSString *updateSQL = #"SELECT * FROM PROFILE";
const char *update_stmt = [updateSQL UTF8String];
sqlite3_prepare_v2(Dummy2, update_stmt, -1, &statement, NULL);
while(sqlite3_step(statement) == SQLITE_ROW) {
person = [[Person alloc] init];
[person setProfileId:(int)sqlite3_column_int(statement, 0)];
[person setName:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
[person setContent:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 2)];
[hello addObject:person];
}
in the tableView class
Change the cellForRowAtIndexPath like:
Person *cellvalue = [arr objectAtIndex:indexPath.row];
cell.textLabel.text=cellvalue.name;
And the didSelectRowAtIndexPath like:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Person *selected = [arr objectAtIndex:indexPath.row];
txtView.txt = selected.content
}
1 Suggestion.
Don't save image on database, it'll make your database too heavy and database operations too slow.
1 alternative is to save image to document directory and save the path to database.

UITableview in ViewController connected to SQLite

I am doing an iPad app.. in which i want to populate the data in UITabelView from database as it is tabelview in UIViewController not UITableViewController, i don't know how to connect them..Kindly help me.!!!!!
find my code for your reference.
viewController.h:
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#interface ViewController : UIViewController {
NSString *databaseName;
NSString * databasePath;
NSMutableArray *tableOne;
NSString * string1;
IBOutlet UITableView *tabelView;
}
#property(nonatomic, retain) NSMutableArray *tableOne;
#property (strong, nonatomic) IBOutlet UITableView *tabelView;
#property(nonatomic, retain) NSString * string1;
-(void)checkAndCreateDatabase;
-(void)readDataFromDatabase;
#end
#import "ViewController.h"
#import "db.h"
#implementation ViewController
//inserted
#synthesize tabelView;
#synthesize tableOne, string1;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
databaseName=#"register.db";
NSArray *documentPaths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentDir = [documentPaths objectAtIndex:0];
databasePath=[documentDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
[self.tabelView reloadData];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [tableOne count];
NSLog(#"a");}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * CellIdentifier=#"cell";
UITableViewCell *cell= nil;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}
db * temp =(db *)[self.tableOne objectAtIndex:indexPath.row];
cell.textLabel.text=temp.name;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
string1 = cell.textLabel.text;
NSLog(#"%#",string1);
}
-(void)checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager=[NSFileManager defaultManager];
success=[fileManager fileExistsAtPath:databasePath];
if(success)
return;
NSString *databasePathFromApp = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
-(void)readDataFromDatabase{
sqlite3 *database;
tableOne=[[NSMutableArray alloc]init];
if(sqlite3_open([databasePath UTF8String], &database)== SQLITE_OK){
const char *sqlStatement = "SELECT * FROM employee;";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL)==SQLITE_OK){
while (sqlite3_step(compiledStatement)==SQLITE_ROW) {
NSString *stringName=[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
db *info =[[db alloc]initWithText:stringName ];
[tableOne addObject:info];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
- (void)viewDidUnload {
[self setTabelView:nil];
[super viewDidUnload];
}
#end
db.h:
#import <Foundation/Foundation.h>
#interface db : NSObject{
NSString * name;
}
#property (nonatomic, retain) NSString * name;
-(id)initWithText:(NSString *)d ;
#end
#import "db.h"
#implementation db
#synthesize name;
-(id)initWithText:(NSString *)d{
self=[super init];
if(self)
{
self.name = d;
}
return self;
}
#end
Thanks in Advance
Have you set the tableview datasource and delegate to the view in your nib file in interface builder? You must set those there, or in code, in your viewdidload by setting
self.tabelView.datasource = self;
self.tabelView.delegate = self;
Also your tableOne mutable array should be initialized only once in your viewDidLoad and when you reload the data from the database you should just remove all array data by using:
[tableOne removeAllObjects];
I think you should make sure your UITableView works before you pull data out of your database file. Simply create a NSArray as data source and fill in some data in your -ViewDidLoad() and see whether your UITableView can pick up. And after you know it works, you can grab the data from database and use the data to populate your table view.
From your code, I didn't see your specify your view controller as UITableViewDelegate and UITableViewDataSource. I see you implemented those methods but you definitely need to tell your class to inherit UITableViewDelegate and UITableViewDataSource.
Even before that, in your interface builder, after you drag a uitableview control to your view, don't forget to right click on it and set the delegate and data source to the file's owner.
Hope this helps.

How to Display data from SQlite into Table views to iPhone app

I'm working on an iPhone project in Xcode 4.3 with SQlite3, the connection between the SQlite and Xcode is done, now I want to display my data into a table views (three views) and its read only!
so I have the main table view, select raw --> take to 2nd view and load other data from the DB select raw --> take to the details view to display long text and image!
Any help appreciated.
AppDelegate.h
#import "AppDelegate.h"
#import "MasterViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize navigationController = _navigationController;
- (void)dealloc
{
[_window release];
[_navigationController release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"cities.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if (success) {
NSLog(#"we have the database");
} else {
NSLog(#"we have no database");
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"cities.sqlite"];
BOOL moved = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:nil];
if (moved) {
NSLog(#"database copied");
}
}
MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
MasterViewController.h
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#class DetailViewController;
#interface MasterViewController : UITableViewController {
NSMutableArray *cities;
}
#property (strong, nonatomic) DetailViewController *detailViewController;
#end
MasterViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
students = [[NSMutableArray alloc] init];
countries = [[NSMutableArray alloc] init];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"cities.sqlite"];
sqlite3 *database;
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "select * from cities_info";
sqlite3_stmt *compileStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compileStatement, NULL) == SQLITE_OK) {
while (sqlite3_step(compileStatement) == SQLITE_ROW) {
NSLog(#"one record");
NSString *cityName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compileStatement, 1)];
[cities addObject:cityName];
}
NSLog(#"cities: %#",cities);
}
} else {
NSLog(#"error in database");
}
}
Blockquote
I suggest a light wrapper over SQLite - see https://github.com/JohnGoodstadt/EasySQLite
This will allow:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _personTable.rows.count;
}
AND
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
NSArray* row= _personTable.rows[indexPath.row];
cell.textLabel.text = row[[_personTable colIndex:#"lastname"]];
...
Set this up by using an iVar representing a SQL Table:
self.personTable = [_db ExecuteQuery:#"SELECT firstname , lastname , age , salary FROM person"];
And a DB Connection iVar passing in your SQL file name:
self.db = [DBController sharedDatabaseController:#"DataTable.sqlite"];
First of all, I suggest using FMDB, which is an Objective-C wrapper around sqlite3. Secondly, I'd create a custom Data Access Object with a shared instance, like so:
#interface MyDatabaseDAO : NSObject
#property (nonatomic, strong) FMDatabase *database;
#end
#implementation MyDatabaseDAO
#synthesize database = _database;
+ (MyDatabaseDAO *)instance {
static MyDatabaseDAO *_instance = nil;
#synchronized (self) {
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
return _instance;
}
- (id)init {
self.database = [FMDatabase databaseWithPath:myDatabasePath];
[self.database open];
}
- (void)dealloc {
[self.database close];
}
#end
This DAO must have 3 access methods: one for each data object in the database. Because you weren't specific, I made these objects without any specific properties.
- (NSArray *)retrieveAllFirstViewItems {
NSMutableArray *items = [NSMutableArray array];
FMResultSet *resultSet = [FMDBDatabase.database executeQuery:#"SELECT * FROM myFirstViewItemTable"];
while ([resultSet next]) {
// extract whatever data you want from the resultset
NSString *name = [resultSet stringForColumn:#"name"]
[items addObject:name];
}
[resultSet close];
return items;
}
- (MySecondViewItem *)retrieveSecondViewItemFromIndexPath:(NSIndexPath *)indexPath {
FMResultSet *resultSet = [FMDBDatabase.database executeQuery:#"SELECT * FROM mySecondViewItemTable WHERE pid = ?", [indexPath indexAtPosition:0]];
if ([resultSet next]) {
// extract whatever data you want from the resultset
NSString *name = [resultSet stringForColumn:#"name"]
MySecondViewItem *mySecondViewItem = [[MySecondViewItem alloc]
initWithName:name withPID:[indexPath indexAtPosition:0]];
[resultSet close];
return mySecondViewItem;
} else {
return nil;
}
}
- (MyThirdViewItem *)retrieveThirdViewItemFromIndexPath:(NSIndexPath *)indexPath {
FMResultSet *resultSet = [FMDBDatabase.database executeQuery:#"SELECT * FROM mySecondViewItemTable WHERE pid = ?", [indexPath indexAtPosition:1]];
if ([resultSet next]) {
// extract whatever data you want from the resultset
NSString *name = [resultSet stringForColumn:#"name"]
MyThirdViewItem *myThirdViewItem = [[MyThirdViewItem alloc]
initWithName:name withPID:[indexPath indexAtPosition:1]];
[resultSet close];
return myThirdViewItem;
} else {
return nil;
}
}
Since it's read-only, these are all the required methods. In your first UITableView, just implement method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MySecondViewItem *mySecondViewItem = [[MyDatabaseDAO instance] retrieveSecondViewItemFromIndexPath:indexPath];
//instantiate a view from this item and use [UINavigationController pushViewController:animated:] to navigate to it
}
All that's left is just to show your data objects in views somehow. I sugget doing as much of the data retrieval as possible in the Data Access Object so that the view controllers can read the properties of the data objects without having to worry about the backend.
That's all there is to it! I hope this helped

iPhone Application Exit when scrolling the UITableView

I have declared a NSMutableArray and I populated it with information from the database. The table displays information well. But when I scroll down, the application exits. Seems like its loosing the pointer to the array.
Here is the code for declaration of the array:
#interface RootViewController : UITableViewController <CLLocationManagerDelegate> {
sqlite3 *database;
NSMutableArray *storeList;
CLLocationManager *locationManager;
CLLocation *startingPoint;
}
#property (nonatomic, retain) NSMutableArray *storeList;
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocation *startingPoint;
- (void) createCopyOfDatabaseIfNeeded;
- (void) initializeStoreList;
- (void) getDistanceFromUserLocation;
Here I am initializing the array with object of type StoreInfo:
- (void) initializeStoreList{
self.storeList = [[NSMutableArray alloc] init];
//database is stored in the application bundle.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:kFileName];
if (sqlite3_open([dbPath UTF8String], &database)== SQLITE_OK) {
const char *sql = "select id, storename, ratings, lattitude, longitude from storeinformation";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSInteger *_pk = (NSInteger *) sqlite3_column_int(statement, 0);
NSString *_storeName = [NSString stringWithUTF8String:(char*) sqlite3_column_text(statement, 1)];
NSString *_ratings = [NSString stringWithUTF8String:(char*) sqlite3_column_text(statement, 2)];
double _lattitude = [[NSString stringWithUTF8String:(char*) sqlite3_column_text(statement, 3)] doubleValue];
double _longitude = [[NSString stringWithUTF8String:(char*) sqlite3_column_text(statement, 4)] doubleValue];
StoreInfo *si = [[StoreInfo alloc] initWithBasicInformation:_pk storeName:_storeName ratings:_ratings lattitude:_lattitude longitude:_longitude];
[self.storeList addObject:si];
[si release];
}
}
sqlite3_finalize(statement);
} else {
sqlite3_close(database);
NSAssert1(0,#"Failed to open the database with message '%s'.", sqlite3_errmsg(database));
}
}
here is the constructor for StoreInfo object
-(id)initWithBasicInformation:(NSInteger *)_pk storeName:(NSString *) _storeName ratings:(NSString *) _ratings lattitude:(double) _lattitude longitude:(double) _longitude;
{
if (self = [super init]) {
self.primaryKey = _pk;
self.storeName = _storeName;
self.ratings = _ratings;
self.lattitude = _lattitude;
self.longitude = _longitude;
}
return self;
}
Here is the code for displaying the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
StoreInfo *si = (StoreInfo *)[self.storeList objectAtIndex:indexPath.row];
cell.textLabel.text = si.storeName;
return cell;
}
The table displays alright first. But when I scroll down, this even gets fired and somehow it is not able to find reference to the si.storeName.
I have spent hours trying to debug the issue. Any help is greatly appreciated.
First of all, how have you defined the property for the problematic field?
Is it retain?
Secondly, Can you access any other property in si?
And finally, I see that there is a memory leak in self.storeList = [[NSMutableArray alloc] init]; - the object is retained twice (in init and in the property setter)...