Novice Programmer - do this for fun and learning..
I am trying to populate 2 UIPickerView's with data from a SQLite query
Every time I run this, I get this error:
-[__NSArrayI length]: unrecognized selector sent to instance
What I'm trying to do is simple, and shouldn't be this painful a problem. Can you please review, and tell me what may be causing the error?
Please note, I have stripped a lot of the "fluffy" code out for the display elements - I am aware that none of this code is causing any of the issues..
FuelEdit.m
#import "FuelEdit.h"
#import "DBManager.h"
#interface FuelEdit ()
#property (nonatomic, strong) DBManager *dbManager;
#end
#implementation FuelEdit
#synthesize regoPicker;
#synthesize locationPicker;
#synthesize datePicker;
- (void)viewDidLoad
{
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"fuel.sql"];
regoPicker.delegate = self;
regoPicker.dataSource = self;
locationPicker.delegate = self;
locationPicker.dataSource = self;
[regoPicker setShowsSelectionIndicator:YES];
}
- (void)viewWillAppear{
}
- (NSInteger)numberOfComponentsInPickerView: (UIPickerView *)pickerView
{
if (pickerView == regoPicker) {
return 1;
} else if (pickerView == locationPicker) {
return 1;
} else {
return 1;
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView == regoPicker) {
NSString *query = [NSString stringWithFormat:#"SELECT * FROM aircraft"];
// Load the relevant data.
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
return results.count;
} else if (pickerView == locationPicker) {
NSString *query = [NSString stringWithFormat:#"SELECT * FROM location"];
// Load the relevant data.
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
return results.count;
} else {
return 1;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerView == regoPicker) {
NSString *query = [NSString stringWithFormat:#"SELECT acrego FROM aircraft"];
// Load the relevant data.
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
if (results !=nil) {
return [results objectAtIndex:row];
} else {
return nil;
}
} else if (pickerView == locationPicker) {
NSString *query = [NSString stringWithFormat:#"SELECT locname FROM location"];
// Load the relevant data.
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
if (results != nil) {
return [results objectAtIndex:row];
} else {
return nil;
}
} else {
return 0;
}
}
FuelEdit.h
#import <UIKit/UIKit.h>
#protocol FuelEditDelegate
#end
#interface FuelEdit : UITableViewController <UITableViewDelegate, UITableViewDataSource, UIPickerViewDataSource, UIPickerViewDelegate>
#property (nonatomic, strong) id<FuelEditDelegate> delegate;
#property (weak, nonatomic) IBOutlet UIPickerView *regoPicker;
#property (weak, nonatomic) IBOutlet UIDatePicker *datePicker;
#property (weak, nonatomic) IBOutlet UIPickerView *locationPicker;
#end
DBManager.m:
#import <Foundation/Foundation.h>
#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
-(instancetype)initWithDatabaseFilename:(NSString *)system{
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 = system;
// Copy the database file into the documents directory if necessary.
[self copyDatabaseIntoDocumentsDirectory];
}
return self;
}
-(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(#"Copy Database Error: %#", [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) {
if (sqlite3_step(compiledStatement)) {
// 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);
}
-(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
Make sure your results contain only one array it must not be list of array. I am feeling like when you are doing this
return [results objectAtIndex:row];
it is returning a array instead of returning a string. May be your results contain list of arrays. Please verify this thing.
Error is for the unrecognized selector. It means you are calling length function for an array or returning Array instead of string in any of the method.
I have checked your code.Please check in following section:
NSArray *results = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];
if (results !=nil) {
return [results objectAtIndex:row];
}
I think [results objectAtIndex:row] is returning a array instead of the string.
Please let me know the results...
Related
I have an ordinary Database manager class. Here is the code:
#import "DatabaseManager.h"
#import "Tolo.h"
#import "Action.h"
#import "ActionCreatorConstants.h"
#import <sqlite3.h>
#import "DatabaseConstants.h"
#import "KGKSignal.h"
#interface DatabaseManager ()
#property (nonatomic, strong) NSString *documentsDirectory;
#property (nonatomic, strong) NSString *databaseFilename;
#property (nonatomic, strong) NSMutableArray *arrayResults;
#property (nonatomic, strong) NSMutableArray *arrayColumnNames;
#property (nonatomic) int affectedRows;
#property (nonatomic) long long lastInsertedRowID;
#end
#implementation DatabaseManager
static DatabaseManager *instance = nil;
+ (instancetype)getInstance {
if (instance == nil) {
instance = [[DatabaseManager alloc] initWithDatabaseFilename:DATABASE_NAME];
}
return instance;
}
- (instancetype)initWithDatabaseFilename:(NSString *)databaseFilename {
self = [super init];
if (self) {
REGISTER();
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [paths objectAtIndex:0];
self.databaseFilename = databaseFilename;
// [self copyDatabaseIntoDocumentsDirectory];
}
return self;
}
- (void)copyDatabaseIntoDocumentsDirectory {
NSString *destinationPath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];
if (![[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseFilename];
NSError *error;
[[NSFileManager defaultManager] copyItemAtPath:sourcePath
toPath:destinationPath
error:&error];
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}
}
- (void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable {
sqlite3 *sqlite3Database;
// NSString *databasePath = [self.documentsDirectory
// stringByAppendingPathComponent:self.databaseFilename];
NSString *databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DATABASE_NAME];
if (self.arrayResults != nil) {
[self.arrayResults removeAllObjects];
self.arrayResults = nil;
}
self.arrayResults = [[NSMutableArray alloc] init];
if (self.arrayColumnNames != nil) {
[self.arrayColumnNames removeAllObjects];
self.arrayColumnNames = nil;
}
self.arrayColumnNames = [[NSMutableArray alloc] init];
BOOL openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
if (openDatabaseResult == SQLITE_OK) {
sqlite3_stmt *compiledStatement;
BOOL preparedStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1,
&compiledStatement, NULL);
if (preparedStatementResult == SQLITE_OK) {
if (!queryExecutable) {
NSMutableArray *arrayDataRow;
while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
arrayDataRow = [[NSMutableArray alloc] init];
int totalColumns = sqlite3_column_count(compiledStatement);
for (int i = 0; i < totalColumns; i++) {
char *dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);
if (dbDataAsChars != NULL) {
[arrayDataRow addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
if (self.arrayColumnNames.count != totalColumns) {
dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i);
[self.arrayColumnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]];
}
}
if (arrayDataRow.count > 0) {
[self.arrayResults addObject:arrayDataRow];
}
}
} else {
BOOL executeQueryResult = sqlite3_step(compiledStatement);
if (executeQueryResult) {
self.affectedRows = sqlite3_changes(sqlite3Database);
self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database);
} else {
NSLog(#"Database error: %s", sqlite3_errmsg(sqlite3Database));
}
}
} else {
NSLog(#"%s", sqlite3_errmsg(sqlite3Database));
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(sqlite3Database);
}
- (NSArray *)loadDataFromDatabase:(NSString *)query {
[self runQuery:[query UTF8String] isQueryExecutable:NO];
return (NSArray *)self.arrayResults;
}
- (void)executeQuery:(NSString *)query {
[self runQuery:[query UTF8String] isQueryExecutable:YES];
}
SUBSCRIBE(Action) {
if ([event.type isEqualToString:GET_LAST_SIGNAL_DATE_FROM_DATABASE]) {
NSLog(#"Lal");
}
}
- (void)insertSignal:(KGKSignal *)signal {
NSString *insertSignalQuery = [NSString stringWithFormat:#"INSERT INTO %# (%#,%#,%#,%#,%#,%#,%#,%#,%#,%#,%#,%#) VALUES (%ld,%ld,%f,%f,%ld,%f,%f,%ld,%ld,%ld,%ld,%ld);", TABLE_SIGNAL, COLUMN_DEVICE_ID, COLUMN_MODE, COLUMN_LATITUDE, COLUMN_LONGITUDE, COLUMN_DATE, COLUMN_VOLTAGE, COLUMN_BALANCE, COLUMN_SATELLITES, COLUMN_SPEED, COLUMN_CHARGE, COLUMN_DIRECTION, COLUMN_TEMPERATURE, (long)signal.deviceId, (long)signal.mode, signal.latitude, signal.longitude, (long)signal.date, signal.voltage, signal.balance, (long)signal.satellites, (long)signal.speed, (long)signal.charge, (long)signal.direction, (long)signal.temperature];
[self executeQuery:insertSignalQuery];
}
- (NSInteger)getLastSignalDate {
NSInteger lastSignalDate = 1441065600;
return lastSignalDate;
}
#end
The problem lurks in the last method - getLastSignalDate. When i set return value to 0 - app works ok. When method returns any non-null number - app craches in runtime (build successful). Error occurs in Tolo object - it can not register (Via REGISTER() macro) Database Manager object - EXC_BAD_ACCESS error in publish method of Tolo.m. Did someone face with same wierd behavior???
I've overriden dealloc method of Database Manager and it didn't log before error occured - so object exists in memory.
so I've got a barcode scanning app that is supposed to read the barcode, match it up with an entry in a database, and display all other information about the entry.
I'm using a single file DB called trackeddb.sqlite, which was created using terminal and sqlite3 commands. It houses two tables, one for static information about products (each part number is unique and has its own entry) for filling out a 'first scan' entry, and a second table which will house the same product information, but also barcodes. The second table allows the user to store multiple products of the same part number and specs, but using a barcode to create unique entries.
My issue is, when the barcode scans, it's supposed to display information stored in the second table (if the barcode matches). The code is sound, but when I run my barcode through (after an entry is in the second table) it displays no data other than preset text. I've racked my brain over this and I can't figure it out, but I think it may have to do with how I'm referencing my database.
Thanks for your time!
What I am greeted with when I scan the barcodes
This is the sqlite DB
PasteBin link to sqlite db and schema
The database is called from this method
- (id)init {
if ((self = [super init])) {
NSString* sqLiteDb = [[NSBundle mainBundle] pathForResource:#"trackeddb" ofType:#"sqlite"];
if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) {
NSLog(#"Failed to open database");
}
}
return self;
}
Here are the main portions of my code, the barcode scanner works perfectly so I won't bother posting that bit. This is just for the database.
TrackerDatabase.m
//TrackerDatabase.m
#import "TrackerDatabase.h"
#import "TrackedItems.h"
#import "Barcode.h"
#interface TrackerDatabase()
#end
#implementation TrackerDatabase
static TrackerDatabase *_database;
+ (TrackerDatabase*)database {
if (_database == nil) {
_database = [[TrackerDatabase alloc] init];
}
return _database;
}
- (id)init {
if ((self = [super init])) {
NSString* sqLiteDb = [[NSBundle mainBundle] pathForResource:#"trackeddb" ofType:#"sqlite"];
if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) {
NSLog(#"Failed to open database");
}
}
return self;
}
- (void)dealloc {
sqlite3_close(_database);
}
- (NSArray *)trackedItems:(NSString *)barcode {
NSMutableArray *retval = [[NSMutableArray alloc] init];
NSString *query = #"SELECT * from Tracked WHERE barcode=";
query = [query stringByAppendingString:barcode];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char *barcodeChars = (char *) sqlite3_column_text(statement, 0);
char *partNumChars = (char *) sqlite3_column_text(statement, 1);
char *descChars = (char *) sqlite3_column_text(statement, 2);
char *colorChars = (char *) sqlite3_column_text(statement, 3);
char *sizeChars = (char *) sqlite3_column_text(statement, 4);
char *leadChars = (char *) sqlite3_column_text(statement, 5);
char *manufacturerChars = (char *) sqlite3_column_text(statement, 6);
NSString *barcode = [[NSString alloc] initWithUTF8String:barcodeChars];
NSString *partNum = [[NSString alloc] initWithUTF8String:partNumChars];
NSString *desc = [[NSString alloc] initWithUTF8String:descChars];
NSString *color = [[NSString alloc] initWithUTF8String:colorChars];
NSString *size = [[NSString alloc] initWithUTF8String:sizeChars];
NSString *lead = [[NSString alloc] initWithUTF8String:leadChars];
NSString *manufacturer = [[NSString alloc] initWithUTF8String:manufacturerChars];
TrackedItems *items = [[TrackedItems alloc] initWithBarcode:barcode partNum:partNum desc:desc
color:color size:size lead:lead manufacturer:manufacturer];
[retval addObject:items];
}
sqlite3_finalize(statement);
}
return retval;
}
#end
TrackerDatabase.h
//TrackerDatabase.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface TrackerDatabase : NSObject {
sqlite3 *_database;
}
+ (TrackerDatabase*)database;
- (NSArray *)trackedItems:(NSString*)barcode;
#end
TrackedItems.m
#import "TrackedItems.h"
#implementation TrackedItems
#synthesize barcode = _barcode;
#synthesize partNum = _partNum;
#synthesize desc = _desc;
#synthesize color = _color;
#synthesize size = _size;
#synthesize lead = _lead;
#synthesize manufacturer = _manufacturer;
- (id)initWithBarcode:(NSString *)barcode partNum:(NSString *)partNum desc:(NSString *)desc
color:(NSString *)color size:(NSString *)size lead:(NSString *)lead
manufacturer:(NSString *)manufacturer {
if ((self = [super init])) {
self.barcode = barcode;
self.partNum = partNum;
self.desc = desc;
self.color = color;
self.size = size;
self.lead = lead;
self.manufacturer = manufacturer;
}
return self;
}
- (void) dealloc {
self.barcode = nil;
self.partNum = nil;
self.desc = nil;
self.color = nil;
self.size = nil;
self.lead = nil;
self.manufacturer = nil;
}
#end
TrackedItems.h
#import <Foundation/Foundation.h>
#interface TrackedItems : NSObject {
NSString *_barcode;
NSString *_partNum;
NSString *_desc;
NSString *_color;
NSString *_size;
NSString *_lead;
NSString *_manufacturer;
}
#property (nonatomic, copy) NSString *barcode;
#property (nonatomic, copy) NSString *partNum;
#property (nonatomic, copy) NSString *desc;
#property (nonatomic, copy) NSString *color;
#property (nonatomic, copy) NSString *size;
#property (nonatomic, copy) NSString *lead;
#property (nonatomic, copy) NSString *manufacturer;
- (id)initWithBarcode:(NSString *)barcode partNum:(NSString *)partNum desc:(NSString *)desc
color:(NSString *)color size:(NSString *)size lead:(NSString *)lead
manufacturer:(NSString *)manufacturer;
#end
After a quick look it seems the problem might lie in:
NSString *query = #"SELECT * from Tracked WHERE barcode=";
query = [query stringByAppendingString:barcode];
In your table, barcode is declared as TEXT. So you need to use LIKE instead of =.
What your query string looks like:
SELECT * from Tracked WHERE barcode=123123123123
What it should look like:
SELECT * from Tracked WHERE barcode LIKE '123123123'
If you're sure that you get information from sqlite, check if your tableview is correctly.
I suggest use Core Data, is easy to do and its better than sqlite for iOS
I am trying to load a csv file in core data when the application is ran for the first time. On another post on stackoverflow found here (What is the fastest way to load a large CSV file into core data), I found out how to do that.
I am using the same code form the provided function: populateDB, in my controller and calling the function if the data has never been loaded before (first run). However, xcode is giving me an error:
No visible #interface for ...Controller declares the selector persistentStoreCoordinator.
The function is:
-(void)populateDB{
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
NSManagedObjectContext *context;
if (coordinator != nil) {
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];
}
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"input" ofType:#"txt"];
if (filePath) {
NSString * myText = [[NSString alloc]
initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
if (myText) {
__block int count = 0;
[myText enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) {
line=[line stringByReplacingOccurrencesOfString:#"\t" withString:#" "];
NSArray *lineComponents=[line componentsSeparatedByString:#" "];
if(lineComponents){
if([lineComponents count]==3){
float f=[[lineComponents objectAtIndex:0] floatValue];
NSNumber *number=[NSNumber numberWithFloat:f];
NSString *string1=[lineComponents objectAtIndex:1];
NSString *string2=[lineComponents objectAtIndex:2];
NSManagedObject *object=[NSEntityDescription insertNewObjectForEntityForName:#"Bigram" inManagedObjectContext:context];
[object setValue:number forKey:#"number"];
[object setValue:string1 forKey:#"string1"];
[object setValue:string2 forKey:#"string2"];
NSError *error;
count++;
if(count>=1000){
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
count=0;
}
}
}
}];
NSLog(#"done importing");
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
}
}
}
I am picking up iOS again after 3 years of absence and I have never dived into this part of the SDK before. I would greatly appreciate any help with this issue...
The code below shows you an example to load csv file in Core Data using the class CSVParser.hof Matt Gallagher and supposing an entity MyEntity
// CSV File input.csv and not input.txt separate by space #" "
CSVParser *csvParser = [[CSVParser alloc] initWithContentOfFile:[NSBundle mainBundle] pathForResource:#"input" ofType:#"csv" separator:#" "];
// Array with all your data from CSV
NSArray *data = [csvParser parseFile];
// Your entity from Core Data
MyEntity *myEntity = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
for (NSDictionary *dic in data)
{
fetchRequest.entity = [NSEntityDescription entityForName:#"MyEntity" inManagedObjectContext:context];
if (!entity)
entity = [NSEntityDescription insertNewObjectForEntityForName:#"MyEntity"
inManagedObjectContext:context];
[entity setValue:number forKey:#"number"];
[entity setValue:string1 forKey:#"string1"];
[entity setValue:string2 forKey:#"string2"];
}
// Save the context
[managedObjectContext save:nil];
CVSParser.h using ARC :
//
// CSVParser.h
// CSVImporter
//
// Created by Matt Gallagher on 2009/11/30.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
// Source : http://cocoawithlove.com/2009/11/writing-parser-using-nsscanner-csv.html
#interface CSVParser : NSObject
{
NSString *csvString;
NSString *separator;
NSScanner *scanner;
BOOL hasHeader;
NSMutableArray *fieldNames;
id receiver;
SEL receiverSelector;
NSCharacterSet *endTextCharacterSet;
BOOL separatorIsSingleChar;
}
- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString;
- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString;
- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names;
- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names;
- (NSArray *)arrayOfParsedRows;
- (void)parseRowsForReceiver:(id)aReceiver selector:(SEL)aSelector;
- (NSArray *)parseFile;
- (NSMutableArray *)parseHeader;
- (NSDictionary *)parseRecord;
- (NSString *)parseName;
- (NSString *)parseField;
- (NSString *)parseEscaped;
- (NSString *)parseNonEscaped;
- (NSString *)parseDoubleQuote;
- (NSString *)parseSeparator;
- (NSString *)parseLineSeparator;
- (NSString *)parseTwoDoubleQuotes;
- (NSString *)parseTextData;
#end
CVSParser.m using ARC :
//
// CSVParser.m
// CSVImporter
//
// Created by Matt Gallagher on 2009/11/30.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
#import "CSVParser.h"
#implementation CSVParser
//
// initWithString:separator:hasHeader:fieldNames:
//
// Parameters:
// aCSVString - the string that will be parsed
// aSeparatorString - the separator (normally "," or "\t")
// header - if YES, treats the first row as a list of field names
// names - a list of field names (will have no effect if header is YES)
//
// returns the initialized object (nil on failure)
//
- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names
{
self = [super init];
if (self)
{
csvString = [aCSVString retain];
separator = [aSeparatorString retain];
NSAssert([separator length] > 0 &&
[separator rangeOfString:#"\""].location == NSNotFound &&
[separator rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound,
#"CSV separator string must not be empty and must not contain the double quote character or newline characters.");
NSMutableCharacterSet *endTextMutableCharacterSet =
[[NSCharacterSet newlineCharacterSet] mutableCopy];
[endTextMutableCharacterSet addCharactersInString:#"\""];
[endTextMutableCharacterSet addCharactersInString:[separator substringToIndex:1]];
endTextCharacterSet = endTextMutableCharacterSet;
if ([separator length] == 1)
{
separatorIsSingleChar = YES;
}
hasHeader = header;
fieldNames = [names mutableCopy];
}
return self;
}
- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
{
return [self initWithString:aCSVString
separator:aSeparatorString
hasHeader:YES
fieldNames:nil];
}
- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
{
return [self initWithString:[NSString stringWithContentsOfFile:aPath
encoding:NSUTF8StringEncoding
error:nil]
separator:aSeparatorString];
}
- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names
{
return [self initWithString:[NSString stringWithContentsOfFile:aPath
encoding:NSUTF8StringEncoding
error:nil]
separator:aSeparatorString
hasHeader:header
fieldNames:names];
}
//
// dealloc
//
// Releases instance memory.
//
- (void)dealloc
{
[csvString release];
[separator release];
[fieldNames release];
[endTextCharacterSet release];
[super dealloc];
}
//
// arrayOfParsedRows
//
// Performs a parsing of the csvString, returning the entire result.
//
// returns the array of all parsed row records
//
- (NSArray *)arrayOfParsedRows
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];
NSArray *result = [self parseFile];
[scanner release];
scanner = nil;
return result;
}
//
// parseRowsForReceiver:selector:
//
// Performs a parsing of the csvString, sending the entries, 1 row at a time,
// to the receiver.
//
// Parameters:
// aReceiver - the target that will receive each row as it is parsed
// aSelector - the selector that will receive each row as it is parsed
// (should be a method that takes a single NSDictionary argument)
//
- (void)parseRowsForReceiver:(id)aReceiver selector:(SEL)aSelector
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];
receiver = [aReceiver retain];
receiverSelector = aSelector;
[self parseFile];
[scanner release];
scanner = nil;
[receiver release];
receiver = nil;
}
//
// parseFile
//
// Attempts to parse a file from the current scan location.
//
// returns the parsed results if successful and receiver is nil, otherwise
// returns nil when done or on failure.
//
- (NSArray *)parseFile
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];
if (hasHeader)
{
if (fieldNames)
{
[fieldNames release];
}
fieldNames = [[self parseHeader] retain];
if (!fieldNames || ![self parseLineSeparator])
{
return nil;
}
}
NSMutableArray *records = nil;
if (!receiver)
{
records = [NSMutableArray array];
}
NSDictionary *record = [[self parseRecord] retain];
if (!record)
{
return nil;
}
while (record)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (receiver)
{
[receiver performSelector:receiverSelector withObject:record];
}
else
{
[records addObject:record];
}
[record release];
if (![self parseLineSeparator])
{
break;
}
record = [[self parseRecord] retain];
[pool drain];
}
[scanner release];
scanner = nil;
return records;
}
//
// parseHeader
//
// Attempts to parse a header row from the current scan location.
//
// returns the array of parsed field names or nil on parse failure.
//
- (NSMutableArray *)parseHeader
{
NSString *name = [self parseName];
if (!name)
{
return nil;
}
NSMutableArray *names = [NSMutableArray array];
while (name)
{
[names addObject:name];
if (![self parseSeparator])
{
break;
}
name = [self parseName];
}
return names;
}
//
// parseRecord
//
// Attempts to parse a record from the current scan location. The record
// dictionary will use the fieldNames as keys, or FIELD_X for each column
// X-1 if no fieldName exists for a given column.
//
// returns the parsed record as a dictionary, or nil on failure.
//
- (NSDictionary *)parseRecord
{
//
// Special case: return nil if the line is blank. Without this special case,
// it would parse as a single blank field.
//
if ([self parseLineSeparator] || [scanner isAtEnd])
{
return nil;
}
NSString *field = [self parseField];
if (!field)
{
return nil;
}
NSInteger fieldNamesCount = [fieldNames count];
NSInteger fieldCount = 0;
NSMutableDictionary *record =
[NSMutableDictionary dictionaryWithCapacity:[fieldNames count]];
while (field)
{
NSString *fieldName;
if (fieldNamesCount > fieldCount)
{
fieldName = [fieldNames objectAtIndex:fieldCount];
}
else
{
fieldName = [NSString stringWithFormat:#"FIELD_%d", fieldCount + 1];
[fieldNames addObject:fieldName];
fieldNamesCount++;
}
[record setObject:field forKey:fieldName];
fieldCount++;
if (![self parseSeparator])
{
break;
}
field = [self parseField];
}
return record;
}
//
// parseName
//
// Attempts to parse a name from the current scan location.
//
// returns the name or nil.
//
- (NSString *)parseName
{
return [self parseField];
}
//
// parseField
//
// Attempts to parse a field from the current scan location.
//
// returns the field or nil
//
- (NSString *)parseField
{
NSString *escapedString = [self parseEscaped];
if (escapedString)
{
return escapedString;
}
NSString *nonEscapedString = [self parseNonEscaped];
if (nonEscapedString)
{
return nonEscapedString;
}
//
// Special case: if the current location is immediately
// followed by a separator, then the field is a valid, empty string.
//
NSInteger currentLocation = [scanner scanLocation];
if ([self parseSeparator] || [self parseLineSeparator] || [scanner isAtEnd])
{
[scanner setScanLocation:currentLocation];
return #"";
}
return nil;
}
//
// parseEscaped
//
// Attempts to parse an escaped field value from the current scan location.
//
// returns the field value or nil.
//
- (NSString *)parseEscaped
{
if (![self parseDoubleQuote])
{
return nil;
}
NSString *accumulatedData = [NSString string];
while (YES)
{
NSString *fragment = [self parseTextData];
if (!fragment)
{
fragment = [self parseSeparator];
if (!fragment)
{
fragment = [self parseLineSeparator];
if (!fragment)
{
if ([self parseTwoDoubleQuotes])
{
fragment = #"\"";
}
else
{
break;
}
}
}
}
accumulatedData = [accumulatedData stringByAppendingString:fragment];
}
if (![self parseDoubleQuote])
{
return nil;
}
return accumulatedData;
}
//
// parseNonEscaped
//
// Attempts to parse a non-escaped field value from the current scan location.
//
// returns the field value or nil.
//
- (NSString *)parseNonEscaped
{
return [self parseTextData];
}
//
// parseTwoDoubleQuotes
//
// Attempts to parse two double quotes from the current scan location.
//
// returns a string containing two double quotes or nil.
//
- (NSString *)parseTwoDoubleQuotes
{
if ([scanner scanString:#"\"\"" intoString:NULL])
{
return #"\"\"";
}
return nil;
}
//
// parseDoubleQuote
//
// Attempts to parse a double quote from the current scan location.
//
// returns #"\"" or nil.
//
- (NSString *)parseDoubleQuote
{
if ([scanner scanString:#"\"" intoString:NULL])
{
return #"\"";
}
return nil;
}
//
// parseSeparator
//
// Attempts to parse the separator string from the current scan location.
//
// returns the separator string or nil.
//
- (NSString *)parseSeparator
{
if ([scanner scanString:separator intoString:NULL])
{
return separator;
}
return nil;
}
//
// parseLineSeparator
//
// Attempts to parse newline characters from the current scan location.
//
// returns a string containing one or more newline characters or nil.
//
- (NSString *)parseLineSeparator
{
NSString *matchedNewlines = nil;
[scanner
scanCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:&matchedNewlines];
return matchedNewlines;
}
//
// parseTextData
//
// Attempts to parse text data from the current scan location.
//
// returns a non-zero length string or nil.
//
- (NSString *)parseTextData
{
NSString *accumulatedData = [NSString string];
while (YES)
{
NSString *fragment;
if ([scanner scanUpToCharactersFromSet:endTextCharacterSet intoString:&fragment])
{
accumulatedData = [accumulatedData stringByAppendingString:fragment];
}
//
// If the separator is just a single character (common case) then
// we know we've reached the end of parseable text
//
if (separatorIsSingleChar)
{
break;
}
//
// Otherwise, we need to consider the case where the first character
// of the separator is matched but we don't have the full separator.
//
NSUInteger location = [scanner scanLocation];
NSString *firstCharOfSeparator;
if ([scanner scanString:[separator substringToIndex:1] intoString:&firstCharOfSeparator])
{
if ([scanner scanString:[separator substringFromIndex:1] intoString:NULL])
{
[scanner setScanLocation:location];
break;
}
//
// We have the first char of the separator but not the whole
// separator, so just append the char and continue
//
accumulatedData = [accumulatedData stringByAppendingString:firstCharOfSeparator];
continue;
}
else
{
break;
}
}
if ([accumulatedData length] > 0)
{
return accumulatedData;
}
return nil;
}
#end
Thanks for everyone's assistance. I found the answer on stackoverflow, a 2-3 years old forum (Adding Core Data to existing iPhone project)...
So the issue it seems is that when I first created the project I didn't request using core data and only did that later on. Following the post I posted above:
Add the following to supporting files/projectName-Prefix.pch
#import <CoreData/CoreData.h>
Once I did, the persistenceCoordinator error disappeared...
WOW, big lesson learned there...
-(void)populateDB {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
NSManagedObjectContext *context;
[....]
}
The Problem might be [self persistentStoreCoordinator]... Do you have a function called "persistentStoreCoordinator" ? If not, you have to write the function.
[EDIT]
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
#synchronized (self)
{
if (__persistentStoreCoordinator != nil)
return __persistentStoreCoordinator;
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:#"myProject" ofType:#"sqlite"];
NSString *storePath = [[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent: #"myProject.sqlite"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:storePath])
{
if ([[NSFileManager defaultManager] copyItemAtPath:defaultStorePath toPath:storePath error:&error])
NSLog(#"Copied starting data to %#", storePath);
else
NSLog(#"Error copying default DB to %# (%#)", storePath, error);
}
NSURL *storeURL = [NSURL fileURLWithPath:storePath];
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
}
Is this Code in another File ? Maybe you forgot to import the .h-file, where persistentStoreCoordinator is declared in.
How to display an integer value in a UILabel in ViewDidLoad? I did for text and date and image but how to convert int to string. I was trying with following code
NSString* label=[aa stringWithFormat:#"%d",((Comments *) [self.list objectAtIndex:0]).noofcomm]];
[self.comments2 setText:label];
but didn't work.Please help me.How to set with the Integer with UILabel?
This is my comments.h
#interface Comments : NSObject
{
NSInteger iD;
UIImage *photo;
NSString *name;
NSString *descrp;
NSDate *date;
NSString *msg;
NSInteger noofcomm;
NSInteger nooflikes;
}
#property(nonatomic,assign)NSInteger iD;
#property(nonatomic,retain)UIImage *photo;
#property(nonatomic,retain)NSString *name;
#property(nonatomic,retain)NSString *descrp;
#property(nonatomic,strong)NSDate *date;
#property(nonatomic,retain)NSString *msg;
#property(nonatomic,assign)NSInteger noofcomm;
#property(nonatomic,assign)NSInteger nooflikes;
#end
DBClass.m
#import "DBClass.h"
#import "Comments.h"
#implementation DBClass
- (NSMutableArray *) getMyComments{
NSMutableArray *wineArray = [[NSMutableArray alloc] init];
#try {
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"ComntDB.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.", dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"An error has occured.");
}
const char *sql = "SELECT id, photo,name,descrp, time,msg,comments,likes FROM Com";
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement");
}
//
while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
Comments *MyWine = [[Comments alloc]init];
MyWine.iD = sqlite3_column_int(sqlStatement, 0);
const char *raw = sqlite3_column_blob(sqlStatement, 1);
int rawLen = sqlite3_column_bytes(sqlStatement, 1);
NSData *data = [NSData dataWithBytes:raw length:rawLen];
MyWine.photo = [[UIImage alloc] initWithData:data];
MyWine.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
MyWine.descrp = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 3)];
MyWine.date=[NSDate dateWithTimeIntervalSince1970:sqlite3_column_double(sqlStatement,4)];
MyWine.msg = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,5)];
MyWine.noofcomm = sqlite3_column_int(sqlStatement, 6);
MyWine.nooflikes = sqlite3_column_int(sqlStatement, 7);
[wineArray addObject:MyWine];
}
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
#finally {
return wineArray;
}
}
#end
RootViewController.m
#import "RootViewController.h"
#import "Comments.h"
#import "DBClass.h"
#interface RootViewController ()
#end
#implementation RootViewController
#synthesize list;
#synthesize image2;
#synthesize name2;
#synthesize descrp2;
#synthesize msg2;
#synthesize date2;
#synthesize comments2;
#synthesize likes2;
- (void)viewDidLoad
{
DBClass * mywines =[[DBClass alloc] init];
self.list = [mywines getMyComments];
[self.image2 setImage:((Comments *) [self.list objectAtIndex:0]).photo];
[self.name2 setText:((Comments *) [self.list objectAtIndex:0]).name];
[self.descrp2 setText:((Comments *) [self.list objectAtIndex:0]).descrp];
NSDateFormatter* fmtr = [[NSDateFormatter alloc] init];
[fmtr setDateFormat:#"MM/dd/yy"];
NSString* label_str = [fmtr stringFromDate:((Comments *) [self.list objectAtIndex:0]).date];
[self.date2 setText:label_str];
[self.msg2 setText:((Comments *) [self.list objectAtIndex:0]).msg];
//[self.comments2 setText:((Comments *) [self.list objectAtIndex:0]).noofcomm];
// int solution = 1;
// [self.comments2 setText:[NSString stringWithFormat:#"%d", solution]];
// int solution2 = 1;
// [self.likes2 setText:[NSString stringWithFormat:#"%d", solution2]];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setImage2:nil];
[self setName2:nil];
[self setMsg2:nil];
[self setDescrp2:nil];
[self setComments2:nil];
[self setLikes2:nil];
[self setDate2:nil];
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NSInteger someInteger = myInteger;
NSString *someString = [NSString stringWithFormat:#"%d", someInteger];
myLabel.text = someString;
or
NSNumber *someNumber = #(myInteger);
NSString *someString = [someNumber stringValue];
myLabel.text = someString;
Both will work.
EDIT:
In your case, it will be something like this:
NSInteger someInteger = ((Comments *) [self.list objectAtIndex:0]).noofcomm;
NSString someString = [NSString stringWithFormat:#"%d", someInteger];
self.comments2.text = someString;
If it's still not working, FOR SURE the problem is somewhere else, and not with the conversion. Check with property noofcomm has a valid value, check if your label reference is ok (test with a random value before the conversion), and somethings like that.
You need to build an NSString
int someInteger = 10;
NSString *someString = [[NSString alloc] initWithFormat:#"%d", someInteger];
You can use something like [NSString string_from_int:42] in LCategory since 0.1.3: https://github.com/superarts/LCategory
_lbl_yourLabel.text=[NSString stringWithFormat:#"%d",[[dic valueForKey:#"your integer value"] intValue]];
On the top left is your label named "yourLabel" , "dic" is your json response dictionary where all the data is coming in key value terms, "your integer value" is the key for which the value will be assign to the label "yourLabel", we have taken intValue because we cannot assign integer value directly to the label.
or you also can try below:
int anyInteger = 13;
NSString *yourString = [[NSString alloc] initWithFormat:#"%d", anyInteger];
self.yourLabel.text = yourString;
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];
}
}
}