顯示包含「Objective-C」標籤的文章。顯示所有文章
顯示包含「Objective-C」標籤的文章。顯示所有文章

2012年7月20日星期五

Installing SqlCipher, a Sqlite Encryption Tool, on Mac


Sqlite database file can be encrypted with the sqlite extension - SqlCipher
(Official encryption extension cost USD$2000)

SqlCipher is an open source project, could be cloned on git.
It is cross-platform and could be built on Unix/Linux/iOS/Android (and Windows?) since it is written by C.
Used some time to figure out what is going on, since I am not familiar with building terminal shell library. Writing it down should help me a lot in future.

The official iOS/Xcode tutorial is good enough for making it works, but it suggests to add sub-projects to the project which need its features that I think is not really necessary in my case, since this would need a much larger compile time when I clean-build my project.
After building the library files, just add them to my own project is fine.

However, I need command line support for convenience purpose.
It took me some time to install the command line sqlite3 with sqlcipher.

The description in the README of the git directory stated that:


This directory contains source code to 

    SQLite: An Embeddable SQL Database Engine

To compile the project, first create a directory in which to place
the build products.  It is recommended, but not required, that the
build directory be separate from the source directory.  Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree.  Then run "make".

For example:

    tar xzf sqlite.tar.gz    ;#  Unpack the source tree into "sqlite"
    mkdir bld                ;#  Build will occur in a sibling directory
    cd bld                   ;#  Change to the build directory
    ../sqlite/configure      ;#  Run the configure script
    make                     ;#  Run the makefile.
    make install             ;#  (Optional) Install the build products




My method is making a new folder named "bld ".
and type
"../sqlcipher-sqlcipher/configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto""
"make"
"sudo make install"

 in Terminal.

And then go to /usr/local/bin, there would hv a newly built "sqlite3" file.
To use it directly in the Terminal, copy it to usr/bin (for safety, backup ur old version of sqlite3)


After that, you should see the version of sqlite version is updated and the sqlciper_export() function is supported.

2012年6月26日星期二

Protocol in Extension in Objective C

For cases that a class should implement a Protocol (Interface in some other languages), but may not favorable to be seen by all the class.
A solution could be implementing the protocol at the Category declaration.

For example, I wanna implement the NSXMLParserDelegate in a class but just want the selectors to be
called as delegate.

at .h declaration:
@interface ClassName : NSObject
{
    //sth.....
}
@end

at .m file (or other .h file in some cases) declaring the extension:
@interface ClassName(NSXMLParserDelegate) <NSXMLParserDelegate>
    //some function in the NSXMLParserDelegate protocol.....
@end

@implementation ClassName(NSXMLParserDelegate)
    //do sth...
@end

@implementation ClassName
    //.......
@end

Reference: Stackoverflow

2012年3月1日星期四

differiate iPhone and iPad programmatically

Used the old-skool method for more than a year to find out what the device is.

size_t size;
 // Set 'oldp' parameter to NULL to get the size of the data
 // returned so we can allocate appropriate amount of space
 sysctlbyname("hw.machine", NULL, &size, NULL, 0); 
 
 // Allocate the space to store name
 char *name = malloc(size);
 
 // Get the platform name
 sysctlbyname("hw.machine", name, &size, NULL, 0);
 
 // Place name into a string
 NSString *machine = [NSString stringWithCString:name encoding:NSUnicodeStringEncoding];
 
 // Done with this
 free(name);
 
 return machine;

but iOS App Programming Guide in fact got a more decent way to do this.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad running iOS 3.2 or later.
}
else {
// The device is an iPhone or iPod touch.
}

2012年2月8日星期三

Objective-c MD5 file checksum

Can match with PHP "md5_file" function.

#import <CommonCrypto/CommonDigest.h>
@implementation NSData (MyExtensions)
- (NSString*)md5
{
    unsigned char result[16];
    CC_MD5( self.bytes, self.length, result );
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3], 
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];  
}
@end

Reference: StackOverFlow

For large files:
+(NSString*)fileMD5:(NSString*)path
{
 NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
 if( handle== nil ) return @"ERROR GETTING FILE MD5"; // file didnt exist
 
 CC_MD5_CTX md5;

 CC_MD5_Init(&md5);
 
 BOOL done = NO;
 while(!done)
 {
  NSData* fileData = [handle readDataOfLength: CHUNK_SIZE ];
  CC_MD5_Update(&md5, [fileData bytes], [fileData length]);
  if( [fileData length] == 0 ) done = YES;
 }
 unsigned char digest[CC_MD5_DIGEST_LENGTH];
 CC_MD5_Final(digest, &md5);
 NSString* s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
       digest[0], digest[1], 
       digest[2], digest[3],
       digest[4], digest[5],
       digest[6], digest[7],
       digest[8], digest[9],
       digest[10], digest[11],
       digest[12], digest[13],
       digest[14], digest[15]];
 return s;
}
Reference: iPhone Dev SDK

2011年7月7日星期四

Adding nil object to NSDictionary

NSDictionary and NSArray do not allow adding nil object to them.
But [NSNull null] can solve this problem in case you really want to have a "Null Object"


if(anObject!=nil)
{
[self setObject:anObject forKey:aKey];
return YES;
}
else
{
[self setObject:[NSNull null] forKey:aKey];
return NO;
}


reference: https://gist.github.com/307568

2010年12月8日星期三

Export NSView to PNG

The following code is for exporting a NSView to PNG file.


And you can change the NSPNGFileType for other format, of course.

KVC for BOOL type not working

Recently I tried to read xml files by KVC in order to get rid of the frustrating hard-coded name matching.

However, by using the  -setValue:forKeyPath: function, I got a "-[NSCFString charValue]: unrecognized selector sent to instance XXXXXX" error when it comes to setting value of any property of BOOL type.

I could only found a few reference on Stackoverflow.

@try
    {
        [(NSObject*)retObj setValue:[[obj keyValuePairs] objectForKey:key]
                         forKeyPath:key];
    }
    @catch (NSException * e)
    {
        if ([[e name] isEqualToString:NSInvalidArgumentException])
        {
            NSNumber* boolVal = [NSNumber numberWithBool:[[[obj keyValuePairs] objectForKey:key] boolValue]];
            [(NSObject*)retObj setValue:boolVal
                             forKeyPath:key];
        }
    }

Since I am not knowing the type until runtime, I need to catch the exception before converting the data type. But I am not sure whether any other type would cause the same exception and lead to an incorrect casting.

I haven't met any problem yet, and hopefully it is safe

2010年11月22日星期一

Few little technique on Objective-C

To test an object's type in runtime in Obj-C:

[myObject isKindOfClass:[NSString class]]

To get the mouse position on the screen:

NSPoint mouseLoc;
mouseLoc = [NSEvent mouseLocation];


To get the mouse position wrt local window:

NSPoint  point   = [self convertPoint:[theEvent locationInWindow] fromView:nil];

2010年11月18日星期四

Strong Type NSArray?

Is there any way to make NSArray become strong typed? The answer is no. (except subclassing it)

From Stackoverflow

Some ppl say it is not necessary, provided having good practice and good testing coverage.
After that I start to think of: why should I need a complier? why should I need VS or Xcode or Eclipse?
Maybe it really takes some time for me to indulge in the embrace of Apple.

2010年11月17日星期三