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

Good UML/Diagram Tools

Just found a handy UML diagram tool on Chrome Web Store - Diagramly.
It is totally free and support syncing with google drive. May not be very professional one but is really amazing for normal use.


Xcode stuck at “Attaching to (app name)”

My project failed to launch after I added a folder reference with the same name as one of the Group of the project.
Xcode didn't prompt me for any errors, but after sometime when I run my app on the simulator the console showed "error: failed to attach to process id 0" to me.

This drove me crazy.
Becoz remove the folder reference doesn't work, and even I opened a new blank project with the same Product Name doesn't work.
I turned to restart my computer and Xcode, used a new Product Name for my new project, and added that folder reference with a different name.

This used almost 3 hours to fix that.......

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

2011年4月8日星期五

Error launching remote program

Sometimes I will meet the error when running the app on the real device, aftering building it successfully.
The app would terminated right after clicking on it.

The console show such a error message: "Error launching remote program: failed to get the task for process"

Found a solution: for target setting, choose the right provisioning profile. for project setting, set the provisioning to "Don't Code re-sign"