Related
I'm trying to open a file 'd.mp3' that I added to my Xcode 8.0 project.
If I double-click Xcode > project > 'd.mp3' the file plays just fine.
But, when Xcode runs my app on my iPhone6+ (iOS 10.0.1) then fopen() returns 0 for the file handle.
Code and output below...
bool read_next_chunk( char* relative_file_pathname, unsigned char* chunk_buffer, int chunk_size_bytes, FILE* file_handle )
{
const bool dbg = true;
// Get absolute file pathname:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *program_directory = [paths objectAtIndex:0];
NSString* absolute_pathname = [NSString stringWithFormat: #"%#/%s", program_directory, relative_file_pathname ];
if( dbg ) printf("\n%s: file '%s'. Path '%s'.", __FUNCTION__, relative_file_pathname, [absolute_pathname UTF8String] );
// Open file if not already open:
if( file_handle == NULL )
{
if( dbg ) printf("\n%s Open file %s.", __FUNCTION__, relative_file_pathname );
file_handle = fopen( [absolute_pathname UTF8String], "rb" ); // open for binary reading
if( dbg ) printf("\n%s file_handle %d.", __FUNCTION__, file_handle);
}
if( file_handle )
{
// Read next chunk of file into file_content_string:
int total_read_bytes = (int)fread( chunk_buffer, 1, chunk_size_bytes, file_handle );
if( total_read_bytes != chunk_size_bytes )
{
printf("\n %s: %d total_read_bytes != %d chunk_size_bytes -- FAULT!! <<<<<<<<<<<",__FUNCTION__, total_read_bytes, chunk_size_bytes);
return false;
}
return true;
}
else
{
printf("\ %s: Cannot open '%s' FAULT!! <<<<<<<<<<<", __FUNCTION__, relative_file_pathname );
return false;
}
}
read_next_chunk: file 'd.mp3'. Path '/var/mobile/Containers/Data/Application/C8B87C49-C6CF-4677-B775-6B3DF6EFD908/Documents/d.mp3'.
read_next_chunk Open file d.mp3.
read_next_chunk file_handle 0. read_next_chunk: Cannot open 'd.mp3' FAULT!! <<<<<<<<<<<
As rmaddy said, it is likely not in your documents directory. Try something like this:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"d" ofType:#"mp3"];
I learnt about the below piece of code, which is claimed to prevent Method Swizzling to some extent.
#ifndef DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif
But while including in my project for testing, I get an error.
Implicit declaration of function 'SEC_IS_BEING_DEBUGGED_RETURN_NIL' is
invalid in C99
Can someone help me out on this error, if I need to include any library header for the same.
I didn't intend to answer my own question. From the comment above, I did a search for any such implementation. And Found this In a GitHub Project. Which is a category of NSObject
Perhaps, it would help anyone in future.
#define SEC_IS_BEING_DEBUGGED_RETURN_NIL() size_t size = sizeof(struct kinfo_proc); \
struct kinfo_proc info; \
int ret, name[4]; \
memset(&info, 0, sizeof(struct kinfo_proc)); \
name[0] = CTL_KERN; \
name[1] = KERN_PROC; \
name[2] = KERN_PROC_PID; \
name[3] = getpid(); \
if ((ret = (sysctl(name, 4, &info, &size, NULL, 0)))) { \
if (ret) return nil; \
} \
if (info.kp_proc.p_flag & P_TRACED) return nil
Credits to maker of this
// Created by Derek Selander on a happy day. //
// Copyright (c)
// 2013 Derek Selander. All rights reserved. //
I wrote macro that defines log level and prints out TAG + method name:
#define NSLogDebug(topic, frmt, ...) \
do{ if(LOG_LEVEL >= 4) \
NSLog( (topic #" : " #"%#" #" : " frmt), \
NSStringFromSelector(_cmd), ##__VA_ARGS__); } while(0)
Usage:
#define TAG #"agent_magr"
/* ... */
-(void)registerforDeviceLockNotif
{
NSLogDebug(TAG, #"init");
The output is:
Agent[741:907] agent_magr : registerforDeviceLockNotif : init
However it works only for non-static methods.
Into the method like:
static void displayStatusChanged(/* */)
{}
I get error:
Use of undeclared identifier '_cmd' Did you mean 'rcmd'?
I thought to use __PRETTY_FUNCTION__:
#define NSLogDebug(topic, frmt, ...) \
do{ if(LOG_LEVEL >= 4) \
NSLog( (topic #" : " #"%s" #" : " frmt), \
__PRETTY_FUNCTION__ , ##__VA_ARGS__); } while(0)
but this one prints out full function with parameters:
Agent[773:907] agent_magr : void displayStatusChanged(CFNotificationCenterRef, void *, CFStringRef, const void *, CFDictionaryRef) : init
How can I make it work in static method?
Thanks,
That isn't a static method; it's a function. The _cmd variable only exists in methods (since only methods are called by selectors). If you want this to work in both functions and methods, you'll have to use either __FUNCTION__ or __PRETTY_FUNCTION__, which are both C strings.
You'll want to solve this the same way NSAssert does. Namely, there's a NSCAssert that avoids using _cmd or self. Then you'll use NSLogDebug in Objective-C functions, and NSCLogDebug in C functions. I'd also advising not using the NS namespace here; you'll confuse yourself (or someone else reading the code) later.
Look in NSException.h:
#if !defined(_NSAssertBody)
#define NSAssert(condition, desc, ...) \
do { \
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
if (!(condition)) { \
[[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
object:self file:[NSString stringWithUTF8String:__FILE__] \
lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
} \
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
} while(0)
#endif
#if !defined(_NSCAssertBody)
#define NSCAssert(condition, desc, ...) \
do { \
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
if (!(condition)) { \
[[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
file:[NSString stringWithUTF8String:__FILE__] \
lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
} \
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
} while(0)
#endif
Currently I am building two apps for my project one in release & another in debug (the only thing that changes are provisioning profiles used to sign and the endpoints) . Because of some policies, I shouldn't be creating ipa files locally. So I use maven to build these two versions (release & debug), based on a script. Because of the same policies, output should be complete removed from the application (NSLog, printf...). I am aware of the preprocessor macros, but I don't want to rely on them, since someone (without knowing) might change them and jeopardise what I want to achieve. So what I want is:
Be able to logout anything I want when I am using my simulator or when I run directly on a real device
When I use maven to build my applications, it will make sure the NSLogs are stripped or disabled.
Maven relies on what's in a remote repository to actually make the build, so if there is a way of disabling this logs during the remote repo commit, it's a solution as well..
Use this macro it will automatically off log on release mode.
Just replace all NSLog with DLog and in future use DLog for logging.
Example : DLog(#"Text : %#",sometext);
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DLog(...)
#endif
It's an interesting request, but feasible if you're willing to accept a bit of function-call overhead for each log that gets skipped. There is a nice feature inside of the EtPanKit framework that checks if the files that are trying to call the log function match an array of pre-defined classes in your Info.plist file. In addition to being a great debug filter, all you'd have to do at Release time is remove all the keys from the plist or specify a different one in your Release build with no values associated with the LEPLogEnabledFilenames key.
In the interest of preventing link-rot, here's the function itself and the associated macros that make it a bit prettier to call:
#define LEPLogStack(...) LEPLogInternal(__FILE__, __LINE__, 1, __VA_ARGS__)
#define LEPLog(...) LEPLogInternal(__FILE__, __LINE__, 0, __VA_ARGS__)
#import <Foundation/Foundation.h>
#import <libgen.h>
#import <time.h>
#import <sys/time.h>
#include <execinfo.h>
#include <pthread.h>
static NSSet * enabledFilesSet = nil;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void LEPLogInternal(const char * filename, unsigned int line, int dumpStack, NSString * format, ...)
{
va_list argp;
NSString * str;
NSAutoreleasePool * pool;
char * filenameCopy;
char * lastPathComponent;
struct timeval tv;
struct tm tm_value;
//NSDictionary * enabledFilenames;
pool = [[NSAutoreleasePool alloc] init];
pthread_mutex_lock(&lock);
if (enabledFilesSet == nil) {
enabledFilesSet = [[NSSet alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:LEPLogEnabledFilenames]];
}
pthread_mutex_unlock(&lock);
NSString * fn;
fn = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:filename length:strlen(filename)];
fn = [fn lastPathComponent];
if (![enabledFilesSet containsObject:fn]) {
[pool release];
return;
}
va_start(argp, format);
str = [[NSString alloc] initWithFormat:format arguments:argp];
va_end(argp);
NSString * outputFileName = [[NSUserDefaults standardUserDefaults] stringForKey:LEPLogOutputFilename];
static FILE * outputfileStream = NULL;
if ( ( NULL == outputfileStream ) && outputFileName )
{
outputfileStream = fopen( [outputFileName UTF8String], "w+" );
}
if ( NULL == outputfileStream )
outputfileStream = stderr;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm_value);
fprintf(outputfileStream, "%04u-%02u-%02u %02u:%02u:%02u.%03u ", tm_value.tm_year + 1900, tm_value.tm_mon + 1, tm_value.tm_mday, tm_value.tm_hour, tm_value.tm_min, tm_value.tm_sec, tv.tv_usec / 1000);
//fprintf(stderr, "%10s ", [[[NSDate date] description] UTF8String]);
fprintf(outputfileStream, "[%s:%u] ", [[[NSProcessInfo processInfo] processName] UTF8String], [[NSProcessInfo processInfo] processIdentifier]);
filenameCopy = strdup(filename);
lastPathComponent = basename(filenameCopy);
fprintf(outputfileStream, "(%s:%u) ", lastPathComponent, line);
free(filenameCopy);
fprintf(outputfileStream, "%s\n", [str UTF8String]);
[str release];
if (dumpStack) {
void * frame[128];
int frameCount;
int i;
frameCount = backtrace(frame, 128);
for(i = 0 ; i < frameCount ; i ++) {
fprintf(outputfileStream, " %p\n", frame[i]);
}
}
if ( outputFileName )
{
fflush(outputfileStream);
}
[pool release];
}
I understand you don't want to rely pre-processor macros, but there is a simple way to remove any NSLog statements using the pre-processor:
Add to your prefix header the following:
#ifndef DEBUG
#define NSLog(...)
#endif
If DEBUG is not defined, then all NSLog statements will removed by the pre-processor throughout the app code.
If DEBUG is not added automatically in your build settings, you can simply add a #define DEBUG statement and comment it out when your build for release.
The same can be done for printf() statements.
I've used this successfully in an app I've released for getting rid of NSLog for release.
You can add a complete log system like this:
#ifndef Logs_h
#define Logs_h
/* Log levels */
#define LOG_LEVEL_NO_LOG 0
#define LOG_LEVEL_ONLY_ERRORS 1
#define LOG_LEVEL_ERROS_AND_WARNINGS 2
#define LOG_LEVEL_LOG_ALL 3
/* Log levels */
#ifdef DEBUG
#define LOG_LEVEL LOG_LEVEL_LOG_ALL /* <-- Change The Log Level here */
#else
#define LOG_LEVEL LOG_LEVEL_NO_LOG /* No logs on release now */
#endif
/* Logs Macros */
#if LOG_LEVEL >= LOG_LEVEL_LOG_ALL
#define DebugLog(fmt, ...) NSLog(#"[Debug] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define DebugLog(...) /* */
#endif
#if LOG_LEVEL >= LOG_LEVEL_ERROS_AND_WARNINGS
#define WarnLog(fmt, ...) NSLog(#"[Warning] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define WarnLog(...) /* */
#endif
#if LOG_LEVEL >= LOG_LEVEL_ONLY_ERRORS
#define ErrorLog(fmt, ...) NSLog(#"[Error] %s [Line %d]: " fmt, __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__)
#else
#define ErrorLog(...) /* */
#endif
#endif
I am working on iphone application in which i have to insert multiples values in table.
I am using the following code but getting the syntax error. Where is my syntax wrong?
INSERT INTO `ark1` (`A`, `B`, `C`) VALUES
('IKE', 'BEFÄLHAVARE OCH MILITÄRER', ' USA'),
('LEE', 'BEFÄLHAVARE OCH MILITÄRER', ' USA'),
('NEY', 'BEFÄLHAVARE OCH MILITÄRER', ' FRAN'),
('ALBA', 'BEFÄLHAVARE OCH MILITÄRER', ' SPAN'),
('FOCH', 'BEFÄLHAVARE OCH MILITÄRER', ' FRAN'),
('GIAP', 'BEFÄLHAVARE OCH MILITÄRER', ' VIET'),
('HAIG', 'BEFÄLHAVARE OCH MILITÄRER', ' USA')
Thanks
That's possible, but not with the usual comma-separated insert values.
Try this...
insert into myTable (col1,col2)
select aValue as col1,anotherValue as col2
union select moreValue,evenMoreValue
union...
Yes, it's a little ugly but easy enough to automate the generation of the statement from a set of values. Also, it appears you only need to declare the column names in the first select.
Following code is use to insert data into the Database
initialization of the database
-(id)init{
if(self=[super init]) {
documentsDirectory_Statement;
documentsDirectory=[documentsDirectory stringByAppendingPathComponent:#"yourApplication.sqlite"];
self.dbPath=documentsDirectory;
NSFileManager *fm=[NSFileManager defaultManager];
if(![fm fileExistsAtPath:self.dbPath]) {
NSString *localDB=[[NSBundle mainBundle] pathForResource:#"yourApplication" ofType:#"sqlite"];
NSError *err;
if(![fm copyItemAtPath:localDB toPath:self.dbPath error:&err]){
NSLog(#"Error in creating DB -> %#",err);
}
}
if(sqlite3_open([self.dbPath UTF8String], &database) !=SQLITE_OK){
NSLog(#"error while opening database.");
} else {
sqlite3_close(database);
}
}
return self;
}
Numbers of Constants
#define PUT_Value(_TO_,_FROM_) { \
NSString *str=[dObj valueForKey:_FROM_]; \
if(!str) str=#" "; \
sqlite3_bind_text(compiledStmt,_TO_,[str UTF8String],-1,SQLITE_TRANSIENT); \
}
#define PUT_Blob(_TO_,_FROM_) { \
sqlite3_bind_blob(compiledStmt,_TO_,[[dObj valueForKey:_FROM_] bytes],[[dObj valueForKey:_FROM_] length],NULL);\
}
#define PUT_Integer(_TO_,_FROM_) { \
NSInteger numbr=[[dObj valueForKey:_FROM_] intValue]; \
sqlite3_bind_int(compiledStmt,_TO_,numbr); \
}
#define PUT_Double(_TO_,_FROM_) { \
CGFloat doubleX=[[dObj valueForKey:_FROM_] floatValue]; \
sqlite3_bind_double(compiledStmt,_TO_,doubleX); \
}
#define PUT_Date(_TO_,_FROM_) { \
sqlite3_bind_text(compiledStmt,_TO_, [[[dObj valueForKey:_FROM_] description] UTF8String], -1, SQLITE_TRANSIENT);\
}
#define GET_Value(_TO_,_FROM_) NSString *_TO_; { \
const unsigned char *c=sqlite3_column_text(compiledStmt,_FROM_); \
_TO_= c ? [NSString stringWithUTF8String:(char*)c] : #"" ; \
}
#define GET_Double(_TO_,_FROM_) double _TO_;{ \
_TO_=sqlite3_column_double(compiledStmt,_FROM_); \
}
#define GET_Integer(_TO_,_FROM_) NSUInteger _TO_; { \
_TO_ = sqlite3_column_int(compiledStmt,_FROM_); \
}
#define GET_Date(_TO_,_FROM_) { \
_TO_=sqlite3_column_double(compiledStmt, _FROM_)];\
}
#define GET_Blob(_TO_,_FROM_) { \
_TO_=sqlite3_column_blob(compiledStmt, _FROM_) length:sqlite3_column_bytes(compiledStmt, _FROM_)];\
}
Insert Funcation
-(void)insertItem:(NSArray*)arItem{
sqlite3_stmt *compiledStmt;
if(sqlite3_open([self.dbPath UTF8String], &database) ==SQLITE_OK) {
sqlite3_prepare_v2(database, "BEGIN TRANSACTION", -1, &compiledStmt, NULL);
sqlite3_step(compiledStmt);
sqlite3_finalize(compiledStmt);
const char *sqlInsertQry="insert into alarm (id,years,months,days,hours,minutes,seconds,body) values(?,?,?,?,?,?,?,?)";
if(sqlite3_prepare_v2(database, sqlInsertQry, -1, &compiledStmt, NULL) == SQLITE_OK ){
for (NSDictionary *dObj in arItem) {
PUT_Integer(1,#"id");
PUT_Integer(2,#"years");
PUT_Integer(3,#"months");
PUT_Integer(4,#"days");
PUT_Integer(5,#"hours");
PUT_Integer(6,#"minutes");
PUT_Integer(7,#"seconds");
PUT_Value(8,#"body");
NSUInteger err = sqlite3_step(compiledStmt);
if (err != SQLITE_DONE){
NSLog(#"error while binding %d %s",err, sqlite3_errmsg(database));
}
sqlite3_reset(compiledStmt);
}
sqlite3_finalize(compiledStmt);
} else {
NSLog(#"Invalid Query");
}
sqlite3_prepare_v2(database, "END TRANSACTION", -1, &compiledStmt, NULL);
sqlite3_step(compiledStmt);
sqlite3_finalize(compiledStmt);
sqlite3_close(database);
} else {
NSLog(#"error while opening database.");
}
}
Hope this code is helping to implement the database connectivity.
#Samuel
For your above query you have to create array and insert in to sqlite.