I'm working on an iOS application and I have some issues since migrating to Xcode 5 and IOS7.
I am unable to write into database when testing on ios7 device.
In simulator works fine (iOS 7) . On iOS 6 devices works fine.
Here is my code for writing into sqlite3 database.
After that I am reading from same database but the values are not change.
Tested on multiple devices.
Thanks in advance.
sqlite3 *db9;
#try {
NSFileManager *fileMgr9 = [NSFileManager defaultManager];
NSString *dbPath9 = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"db.sqlite3"];
BOOL success9 = [fileMgr9 fileExistsAtPath:dbPath9];
if (!success9) {
NSLog(#"Cannot locate database file '%#'.", dbPath9);
}
else NSLog(#"Database file located at: '%#'.", dbPath9);
if (!(sqlite3_open([dbPath9 UTF8String], &db9) == SQLITE_OK)) {
NSLog(#"An error has occured");
}
NSString *strSQL9 = [NSString stringWithFormat:#"UPDATE teste SET scor = ?, timp = ? WHERE id = ?"];
const char *sql9 = [strSQL9 UTF8String];
sqlite3_stmt *sqlStatement9;
if (sqlite3_prepare(db9, sql9, -1, &sqlStatement9, NULL) != SQLITE_OK) {
NSLog(#"Problem with prepare statement");
}else
{
NSLog(#"middle of it - scrie");
if (scordb1 == 0) {
sqlite3_bind_int(sqlStatement9, 1, scorTestTotal);
}else
sqlite3_bind_int(sqlStatement9, 1, ((scorTestTotal+scordb1)/2));
sqlite3_bind_int(sqlStatement9, 2, timeInterval);
sqlite3_bind_int(sqlStatement9, 3, vasile);
sqlite3_step(sqlStatement9);
int success = sqlite3_step(sqlStatement9);
sqlite3_reset(sqlStatement9);
if (success == SQLITE_ERROR){ NSLog(#"error write");}
else {NSLog(#"success write");}
}
sqlite3_finalize(sqlStatement9);
sqlite3_close(db9);
NSLog(#"Close db SCRIE db9");
}
#catch (NSException *exception) {
NSLog(#"An exception occured: %#", [exception reason]);
}
Related
This is my code use AVAudioEngine for change voice in my app.
Can anyone point out what's wrong in this code of mine and help me get rid of the error message?
extension AudioPlayer {
func setupAudio(){
// initialize (recording) audio file
do{
audioFile = try AVAudioFile(forReading: recordedAudioURL as URL)
}catch{
print("Audio File Error ")
}
}
func playSound(rate: Float? = nil, pitch: Float? = nil, echo: Bool = false,reverb:Bool = false){
// initialize audio engine components
audioFile = AVAudioFile()
audioEngine = AVAudioEngine()
// node for playing audio
audioPlayerNode = AVAudioPlayerNode()
audioEngine.attach(audioPlayerNode)//attach the player node to the audio engine
audioMixer = AVAudioMixerNode()
audioEngine.attach(audioMixer)// attach a single output to the audio engine
//node for the adjusting rate/pitch
let changeRatePitchNode = AVAudioUnitTimePitch()
if let pitch = pitch {
changeRatePitchNode.pitch = pitch
}
if let rate = rate {
changeRatePitchNode.rate = rate
}
audioEngine.attach(changeRatePitchNode)
//node for the echo
let echoNode = AVAudioUnitDistortion()
echoNode.loadFactoryPreset(.multiEcho1)
audioEngine.attach(echoNode)
//node for the reverb
let reverbNode = AVAudioUnitReverb()
reverbNode.loadFactoryPreset(.cathedral)
reverbNode.wetDryMix = 50
audioEngine.attach(reverbNode)
//connect the player node to the output node
if echo == true && reverb == true{
connectAudioNode(audioPlayerNode,changeRatePitchNode,echoNode,reverbNode,audioMixer,audioEngine.outputNode)
}else if echo == true{
connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode,audioMixer,audioEngine.outputNode)
}else if reverb == true{
connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode, audioMixer, audioEngine.outputNode)
}else{
connectAudioNode(audioPlayerNode, changeRatePitchNode,audioMixer,audioEngine.outputNode)
}
//schedule to replay the entire audio file- phat lai toan bo tep am thanh
audioPlayerNode.stop()
audioPlayerNode.scheduleFile(audioFile, at: nil)
do{
try audioEngine.start()
}catch{
print("Not OutPut")
}
//generate media resource modeling assets at the specified URL
let audioAsset = AVURLAsset.init(url: recordedAudioURL)
// returns the representation t/g = (s)
let durationInSeconds = CMTimeGetSeconds(audioAsset.duration)
let length = 4000
let buffer = AVAudioPCMBuffer(pcmFormat: audioPlayerNode.outputFormat(forBus: 0), frameCapacity: AVAudioFrameCount(length))
buffer!.frameLength = AVAudioFrameCount(durationInSeconds)//bộ đêmj âm thanh cho định dạng PCM
// MARK: Create a new path after adding effects to the file
let dirPath: AnyObject = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask, true)[0] as AnyObject
let tmpFileURL : NSURL = NSURL.fileURL(withPath: dirPath.appendingPathComponent("NewVoice.m4a")) as NSURL
filteredOutputURL = tmpFileURL
//setting for new file
do{
print(dirPath)
let settings = [AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 1]
self.newAudio = try AVAudioFile(forWriting: tmpFileURL as URL, settings: settings)
//setting for output
self.audioMixer.installTap(onBus: 0, bufferSize: (AVAudioFrameCount(durationInSeconds)), format: self.audioPlayerNode.outputFormat(forBus: 0)) { [self](buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in
print(self.newAudio!.length)
print(self.audioFile.length)
if (self.newAudio!.length) < (self.audioFile.length){
do{
try self.newAudio!.write(from: buffer)
}catch {
print("error writing")
}
}else{
audioPlayerNode.removeTap(onBus: 0)
}
}
}catch _{
print("problem")
}
// MARK: Play Sound Effect
audioPlayerNode.play()
}
func connectAudioNode(_ nodes:AVAudioNode...){
for i in 0..<nodes.count-1{
audioEngine.connect(nodes[i], to: nodes[i + 1], format: audioFile.processingFormat)
}//*error here "processingFormat"*
}
}
error: "processingFormat"
I don't know if it's because the link to read the file is wrong or what's wrong with my settings
Is there any way to add address book contacts on your mac to iOS 8.1 simulator. All the answers found on google are old and no longer works. Only one link I found was Importing AddressBook data into the iPhone Simulator
Please provide an updated answer if some one has done this. The old solution don't work because Apple have changed all the structure in iOS 8
Tested on iOS 8.1 and iPhone6+ Simulator with XCode 6.1.
I made two methods addSampleContacts and removeSampleContacts which you can add in your project to add (or remove) contacts in your simulator.
For that,
You need to add AddressBook.framework and AddressBookUI.framework in your project.
Import #import <AddressBook/AddressBook.h> in the class (or controller) where you want to add/remove sample contacts
You need a contact file (of .vcf format). You can use your phone's contact file for this test to have large number of actual (real) contacts. Add that file in your project.
if you've setup this then, add below functions for the same.
-(void)addSampleContacts
{
NSError *error;
CFErrorRef castError = (__bridge CFErrorRef)error;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &castError);
__block BOOL accessAllowed = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 or above
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessAllowed = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
if(accessAllowed)
{
NSString *vFilePath = [[NSBundle mainBundle] pathForResource:#"YourContactFile" ofType:#"vcf"];
NSData *myData = [NSData dataWithContentsOfFile:vFilePath];
CFDataRef vCardData = (__bridge CFDataRef)myData;
NSError *error;
CFErrorRef castError = (__bridge CFErrorRef)error;
ABAddressBookRef ContactBook = ABAddressBookCreateWithOptions(NULL, &castError);
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(ContactBook);
CFArrayRef vCardContact = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
NSArray *arrayContacts = (__bridge_transfer NSArray *)vCardContact;
NSInteger totalVCFContactCount = arrayContacts.count;
for (CFIndex index = 0; index < totalVCFContactCount; index++)
{
ABRecordRef contact = CFArrayGetValueAtIndex(vCardContact, index);
ABAddressBookAddRecord(ContactBook, contact, NULL);
ABAddressBookSave(ContactBook, nil);
CFRelease(contact);
}
CFRelease(vCardContact);
CFRelease(defaultSource);
}
NSLog(#"Contacts added.");
}
-(void)removeSampleContacts
{
NSError *error;
CFErrorRef castError = (__bridge CFErrorRef)error;
ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, &castError);
__block BOOL accessAllowed = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 or above
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(contactBook, ^(bool granted, CFErrorRef error) {
accessAllowed = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
if(accessAllowed)
{
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople( contactBook );
NSArray *arrayContacts = (__bridge_transfer NSArray *)allContacts;
for ( int i = 0; i < arrayContacts.count; i++ )
{
ABRecordRef ref = CFArrayGetValueAtIndex(allContacts, i);
ABAddressBookRemoveRecord(contactBook, ref, nil);
ABAddressBookSave(contactBook, nil);
}
}
NSLog(#"Contacts removed.");
}
You may not need to ask (or check) for permission if you're already doing this before.
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
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!
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.