sqlite3_stmt gives Exc_Bad_Access - sqlite

This is the code I use AFSQLManager in here any help how to solve this:
this is where I get the Thread and note when I do not comment the if condition it dose not inter the inside the if condition I also try to NSLog the statement before inter the if condition and give me the same thread any help
-(void)performQuery:(NSString *)query withBlock:(completionBlock)completion {
NSString *fixedQuery = [query stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSLog(#"HERE 100d : %#",fixedQuery);
sqlite3_stmt *statement;
// if (sqlite3_prepare_v2(_database, [fixedQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
// NSLog(#"HERE 100a : %#", statement);
while (sqlite3_step(statement) == SQLITE_ROW) { //HERE WHERE I GOT THE THREAD.
NSMutableArray *row = [NSMutableArray array];
NSLog(#"HERE 100b");
for (int i = 0; i < sqlite3_column_count(statement); i++) {
NSLog(#"HERE 100c");
[row addObject:((char *)sqlite3_column_text(statement, i)) ? [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, i)] : [NSNull null]];
}
if (completion) {
NSLog(#"HERE 100e");
completion(row, nil, NO);
}
}
NSLog(#"HERE 100f");
sqlite3_finalize(statement);
completion(nil, nil, YES);
NSLog(#"HERE 100g");
// }
NSLog(#"HERE 100h");
}

sqlite3_step() crashes because statement never got initialized because you commented out the call to sqlite3_prepare_v2().
If a function such as sqlite3_prepare_v2() fails, you can call sqlite3_errmsg() to get a useful error message.

Related

Sometimes PHAsset fetchAssetsWithLocalIdentifiers:options method return a empty fetch result

Has anyone encountered this problem? Any advice will be appreciated.
Code as below:
Sometimes the resultAsset is empty. Maybe happened on iOS9.3 occasionally.
- (PHAsset*)retrievePHAssetFromLocalIdentifier:(NSString*)localIdentifier {
if (!localIdentifier) {
return nil;
}
NSArray *localIdentifiers = #[localIdentifier];
PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:localIdentifiers options:nil];
PHAsset *resultAsset = [result firstObject]; //Sometimes the resultAsset is empty. Maybe happened on iOS9.3 occasionally.
if (!resultAsset) {
NSLog(#"can't retrieve PHAsset from localIdentifier:%#",localIdentifier);
}
return resultAsset;
}
This issue happened when choosing photos from "my photo stream". Finally, I got this workaround to solve it. I hope it helps you.
-(PHAsset*)workAroundWhenAssetNotFound:(NSString*)localIdentifier{
__block PHAsset *result = nil;
PHFetchOptions *userAlbumsOptions = [PHFetchOptions new];
userAlbumsOptions.predicate = [NSPredicate predicateWithFormat:#"estimatedAssetCount > 0"];
PHFetchResult *userAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:userAlbumsOptions];
if(!userAlbums || [userAlbums count] <= 0) {
return nil;
}
[userAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx1, BOOL *stop) {
PHFetchOptions *fetchOptions = [PHFetchOptions new];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"self.localIdentifier CONTAINS %#",localIdentifier];
PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
[assetsFetchResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop1) {
if(asset){
result = asset;
*stop1 = YES;
*stop = YES;
}
}];
}];
return result;
}
Reference link:How to get photo from My Photo Stream Album

Xcode - sql Select a single value does not work

In my app, I trying to get the single id from data base using the query:
SELECT _id FROM rules where codigo_rest = 2345
I am passing that query to the following function:
-(NSString *)selectIDrest:(NSString *)query{
NSString * retval;
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil)
== SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
int uniqueId = sqlite3_column_int(statement, 0);
NSLog(#"int %i",uniqueId);
retval = [NSString stringWithFormat:#"%d",uniqueId];
}
sqlite3_finalize(statement);
}
NSLog(#"%#",retval);
return retval;
}
but the retval is alway 0., while table content id is different (1,2,3,4 ...etc).
By NSlogs, I realize that while (sqlite3_step(statement) == SQLITE_ROW) is never executed.
What is my fault?
You are never executing the query, you only prepared it to be executed. You need to call sqllite3_step to read the first row. The you can call sqllit3_column_int.
You can see how to call it in this tutorial: http://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app

SQLite Where Field Like Text Query

I am trying to run a query on my database in xcode, and it keeps returning 0, even though there are 5 entries. The code to call the database is shown below:
-(int)CountWins
{
int count = 0;
if (sqlite3_open([[self filepath] UTF8String], &_db) == SQLITE_OK) {
const char* query1= "SELECT COUNT(*) FROM Wins WHERE (Action LIKE 'Win');";
sqlite3_stmt *statement;
if( sqlite3_prepare_v2(_db, query1, -1, &statement, NULL) == SQLITE_OK )
{
//Loop through all the returned rows (should be just one)
while( sqlite3_step(statement) == SQLITE_ROW )
{
count = sqlite3_column_int(statement, 0);
}
}
else
{
NSLog( #"Failed from sqlite3_prepare_v2. Error is: %s", sqlite3_errmsg(_db) );
}
// Finalize and close database.
sqlite3_finalize(statement);
//sqlite3_close(articlesDB);
}
[self closeDB];
return count;
}
Basically when the user Wins a game, Win is stored in the action in the database with a timestamp. All i need to know is why my query isnt working, if i do a simple count i get the right number of rows.
Here is my code that inserts the win to the database:
-(void) addwin
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *TimestampVal = [NSDate date];
NSString *actionVal = [NSString stringWithFormat:#"Win"];
NSString *sqlstr = [NSString stringWithFormat:#"INSERT INTO 'Wins' ('Timestamp','Action') VALUES (?,?);"];
sqlite3_stmt *statement;
const char *str = [sqlstr UTF8String];
if (sqlite3_prepare_v2(db, str, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, [ [dateFormatter stringFromDate:TimestampVal] UTF8String],-1, NULL);
sqlite3_bind_text(statement, 1, [actionVal UTF8String],-1, NULL);
}
if (sqlite3_step(statement) != SQLITE_DONE){
NSAssert(0,#"Error Updating Table.");
}
sqlite3_finalize(statement);
}
I have also tried to store this query as a string and convert to UTF8String, however that doesnt seem to matter as more simple queries still work.
Any help would be great, thanks.
Cheers
I get it:
SELECT COUNT(*) FROM Wins WHERE (Action LIKE 'Win')
is actually same as SELECT COUNT(*) FROM Wins WHERE Action='Win'.
If your criteria is "contain word win", then
SELECT COUNT(*) FROM Wins WHERE Action LIKE '%Win%'
is what you are looking for!

UITableView: cell.textLabel.text error: [__NSArrayI isEqualToString:]

I'm downloading an NSManagedObject. Assigning an NSString to valueForKey#"username" of that object. Next, I assign that string to a cell.textLabel.text in UITableView and I'm getting an exception.
The following is the code thats throwing an exception:
-(NSString *)fetchUserName
{
if ([fetchedUserNameObject objectAtIndex:0]!= NULL)
{
recipientUser = (User*)(fetchedUserNameObject);
NSString *userName = (NSString*)[recipientUser valueForKey:#"username"];
return userName;
}
}
.....
NSString *recipientUserName = [self fetchUserName]
......
- (IBAction)reviewButtonPressed:(UIBarButtonItem *)sender
{
NSLog(#"Recipient UserName from Review Button %#", recipientUserName);
PDReviewVC *modalVC = [self.storyboard instantiateViewControllerWithIdentifier:#"pdReview"];
UINavigationController *navBar=[[UINavigationController alloc]initWithRootViewController:modalVC];
modalVC.recipientUserName= self.recipientUserName;
[self presentViewController:navBar animated:YES completion:NULL];
}
Log
2013-08-30 11:51:49.393 Time[1188:c07] Recipient UserName from Review Button (
iphone3gs
)
Now in PDReviewVC:
.h
#property (nonatomic, retain) NSString * recipientUserName;
.m
#synthesize recipientUserName;
...
//cellForRowAtIndexPath
if (indexPath.section == 0)
{
cell.textLabel.text = recipientUserName;
}
I get the following error on cell.textLabel.text = recipientUserName;:
2013-08-30 11:51:54.679 Time[1188:c07] -[__NSArrayI isEqualToString:]: unrecognized selector sent to instance 0xb889390
2013-08-30 11:53:53.303 Time[1188:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI isEqualToString:]: unrecognized selector sent to instance 0xb889390'
*** First throw call stack:
UPDATE
NSLog for the following code:
if ([fetchedUserNameObject objectAtIndex:0]!= NULL)
{
recipientUser = (User*)(fetchedUserNameObject);
NSLog(#"User %#", recipientUser);
NSString *userName = (NSString*)[recipientUser valueForKey:#"username"];
NSLog (#"userName from fetchUserName: %#", userName);
NSLog(#"%#", userName);
return userName;
}
else return NULL;
NSLog:
2013-08-30 12:36:29.495 Time[1341:c07] User (
"<User: 0xa55cd60> (entity: User; id: 0xa5a0ae0 <x-coredata://3B273CFB-1CAA-4FA0-95DC-BA9420219380-1341-000007F42366B21A/User/piphone3gs> ; data: <fault>)"
)
2013-08-30 12:36:29.496 Time[1341:c07] userName from fetchUserName: (
iphone3gs
)
2013-08-30 12:36:29.496 Time[1341:c07] (
iphone3gs
)
The answer to your question is right in your error message. :-)
It's telling you that the object you think is of type NSString is really NSArray. Thus, NSArray does not respond to any method called isEqualToString.
In your fetchUserName method you are casting an object as NSString and returning it, but apparently you are getting an NSArray here. When you set this object to your label's text property, something goes on behind the scenes to ask if the current string property is equal to the one you're trying to set. Then, error.
Try placing this line before you return in the fetchUserName method:
NSLog(#"%#",username);
return username;
Then modify your question with the console results of this NSLog() and we can help you figure out what is inside the array.
Ok, before you return the username object, do this:
NSString *username;
id object = [recipient valueForKey:#"username"];
if ([object isKindOfClass:[NSString class]]) {
username = (NSString *)object;
return username;
} else if ([object isKindOfClass:[NSArray class]]) {
NSArray *returnedArray = (NSArray *)object;
if (returnedArray.count > 0) {
id arrayMember = [returnedArray objectAtIndex:0];
if ([arrayMember isKindOfClass:[NSString class]]) {
username = (NSString *)arrayMember;
return username;
}
}
}
return nil;
You are casting [recipientUser valueForKey:#"username"] as an NSString to get your code to work, when it is in fact returning an NSArray. Remove the cast (NSString*) and get the code working so you are in fact pulling a string rather than an array from recipientUser.
To debug, I'd suggest changing your logging to:
if ([fetchedUserNameObject objectAtIndex:0]!= NULL)
{
recipientUser = (User*)(fetchedUserNameObject);
NSArray *userNames = [recipientUser valueForKey:#"username"];
for (int i=0; i < [userNames count]; i++) {
NSLog(#"Username %i is %#", i, [userNames objectAtIndex:i]);
}
}

SQLite data insert not reflected in table

I can insert my data, but I can't show them in my table view. I tried [tableview reloadData]
but with no success
Here is my code:
-(void)gButtonTapped:(id)sender
{
NSLog(#"right nav bar button is hit%# ",storePaths);
//[self readAnimalsFromDatabase2];
appDelegate = (DatabaseTestAppDelegate *)[[UIApplication sharedApplication] delegate];
sqlite3 *database;
sqlite3_stmt *compiled_statement1;
if(sqlite3_open([storePaths UTF8String], &database) == SQLITE_OK) {
//const char *sqlStatement =
NSString *newQuery = [NSString stringWithFormat:#"insert into cat_tbl (cat_id,names,imgs) values ('12','test1','r.png')"];
// NSString *newQuery = [NSString stringWithFormat:#"select * from list_tbl"];
const char *sql = [newQuery cStringUsingEncoding:NSASCIIStringEncoding];
NSLog(#"update query is %#",newQuery);
if(sqlite3_prepare_v2(database, sql, -1, &compiled_statement1, NULL) == SQLITE_OK)
{
int result = sqlite3_step(compiled_statement1);
sqlite3_reset(compiled_statement1);
NSLog(#"result %d", result);
if(result != SQLITE_ERROR) {
int lastInsertId = sqlite3_last_insert_rowid(database);
NSLog(#"x %d", lastInsertId);
}
}
}
sqlite3_finalize(compiled_statement1);
sqlite3_close(database);
[tableView reloadData];// this is also not working
}
you need to update your table view data source by calling select query or update your data source by adding new values as they got inserted successfully in the data base.

Resources