Tuesday, June 1, 2010

How to create our own delegate for any class in iPhone?

Today I am going to show you how can we create our delegates for class using protocols.It has been always a bit tough for beginners to see how delegation works and how it can be cretaed. I am trying to explain this in a very lucid way. Just follow the steps.







1. Open xcode


2. Create new project with name "MyDelegateForClass"

3. Create new class MYClass

4.Define @protocol MyClassDelegate; at the top in the interface file.

5. Define a delegate in interface
id <myclassdelegate> myDelegate;

6.create a property for myDelegate.
id <myclassdelegate> myDelegate;

we normally do not retain delegates to avoid the retain cycles.
7. create interface for MyClassDelegate

@protocol MyClassDelegate

-(void)myDelegateMethod;

@end

8. @synthesize myDelegate;

9.mydelegate is ready we can pass the message to myDelegate which is going to handle it.
we can pass message -(void)myDelegateMethod to myDelegate any where in @implementation MyClass, after initialization of class is over.
Let we call this in
- (void)viewDidLoad {
[super viewDidLoad];
[myclass.myDelegate myDelegateMethod];
}
10. Now MyClass has a delegate -(void)myDelegateMethod which we can access in any other class.

11. Lets say we need to access this delegate in MyDelegateForClassViewController
what we need to do for that in the interface class of MyDelegateForClassViewController declare protocol MyClassDelegate.
#import"MyClass.h"
@interface MyDelegateForClassViewController : UIViewController<myclassdelegate> {

}

@end

12. Initialize Myclass and set its delegate to MyDelegateForClassViewController
{
//Create instance of MyClass in MyDelegateForClassViewController
MyClass *myclass = [[MyClass alloc] initWithNibName:@"MyClass" bundle:[NSBundle mainBundle]];
myclass.myDelegate = self;
[self presentModalViewController:myclass animated:NO];
[myclass release];
}



13. In @implementation MyDelegateForClassViewController
define the protocol method of MyClass
-(void)myDelegateMethod
{

//here write some code and logic
NSLog(@" This is a delegate method in MyDelegateForClassViewController");
}



This is how delegates can be created for class where we want.


you can download the source code from : source Code

what is the use of delegates hope it would have been clear now.It can be used to communicate between class.

Sunday, April 18, 2010

Folder watcher on Mac

I have written this sample code for keeping watch for files inside the folder.

If you add files or delete files from the folder. The files will be listed out with details.

The contents of file are getting saved into database. This example will also demonstrate use of core data.

#import

@interface FolderWatcher_AppDelegate : NSObject
{
NSWindow *window;

NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;

NSArray *manageDataArr;

IBOutlet NSTextField *folderpathTextField;
IBOutlet NSTableView *tableView;
NSString *folderPath;
NSArray *contents;
NSMutableArray *dataArray;
NSTimer *timer;


}

@property (nonatomic, retain) IBOutlet NSWindow *window;

@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;

- (IBAction)saveAction:sender;
-(IBAction)showStoredVal:(id)sender;
-(IBAction)removeStoredVal:(id)sender;


-(void)folderTracker;
-(IBAction)start:(id)sender;

@end
//
// FolderWatcher_AppDelegate.m
// FolderWatcher
//
// Created by Ashish on 07/03/10.
// Copyright Ashish Kumar Pandita 2010 . All rights reserved.
//

#import "FolderWatcher_AppDelegate.h"
#import "TableAttributes.h"

@implementation FolderWatcher_AppDelegate

@synthesize window;
-(id)init
{
if(self = [super init])
{
folderPath = [folderpathTextField stringValue];
contents = nil;
dataArray=[[NSMutableArray alloc]init];

}
return self;
}
/**
Implementation of dealloc, to release the retained variables.
*/

- (void)dealloc {

[window release];
[managedObjectContext release];
[persistentStoreCoordinator release];
[managedObjectModel release];

[super dealloc];
}


/**
Returns the support directory for the application, used to store the Core Data
store file. This code uses a directory named "FolderWatcher" for
the content, either in the NSApplicationSupportDirectory location or (if the
former cannot be found), the system's temporary directory.
*/

- (NSString *)applicationSupportDirectory {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
return [basePath stringByAppendingPathComponent:@"FolderWatcher"];
}


/**
Creates, retains, and returns the managed object model for the application
by merging all of the models found in the application bundle.
*/

- (NSManagedObjectModel *)managedObjectModel {

if (managedObjectModel) return managedObjectModel;

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}


/**
Returns the persistent store coordinator for the application. This
implementation will create and return a coordinator, having added the
store for the application to it. (The directory for the store is created,
if necessary.)
*/

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator {

if (persistentStoreCoordinator) return persistentStoreCoordinator;

NSManagedObjectModel *mom = [self managedObjectModel];
if (!mom) {
NSAssert(NO, @"Managed object model is nil");
NSLog(@"%@:%s No model to generate a store from", [self class], _cmd);
return nil;
}

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *applicationSupportDirectory = [self applicationSupportDirectory];
NSError *error = nil;

if ( ![fileManager fileExistsAtPath:applicationSupportDirectory isDirectory:NULL] ) {
if (![fileManager createDirectoryAtPath:applicationSupportDirectory withIntermediateDirectories:NO attributes:nil error:&error]) {
NSAssert(NO, ([NSString stringWithFormat:@"Failed to create App Support directory %@ : %@", applicationSupportDirectory,error]));
NSLog(@"Error creating application support directory at %@ : %@",applicationSupportDirectory,error);
return nil;
}
}

NSURL *url = [NSURL fileURLWithPath: [applicationSupportDirectory stringByAppendingPathComponent: @"storedata.sqlite"]];
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: mom];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:nil
error:&error]){
[[NSApplication sharedApplication] presentError:error];
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
return nil;
}

return persistentStoreCoordinator;
}

/**
Returns the managed object context for the application (which is already
bound to the persistent store coordinator for the application.)
*/

- (NSManagedObjectContext *) managedObjectContext {

if (managedObjectContext) return managedObjectContext;

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}

/**
Returns the NSUndoManager for the application. In this case, the manager
returned is that of the managed object context for the application.
*/

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
return [[self managedObjectContext] undoManager];
}


/**
Performs the save action for the application, which is to send the save:
message to the application's managed object context. Any encountered errors
are presented to the user.
*/

- (IBAction) saveAction:(id)sender {

NSError *error = nil;
//NSManagedObject *filedetails = [filedetails valueForKey:@"name"];

if (![[self managedObjectContext] commitEditing]) {
NSLog(@"%@:%s unable to commit editing before saving", [self class], _cmd);
}


if (![[self managedObjectContext] save:&error]) {
[[NSApplication sharedApplication] presentError:error];
}
}


/**
Implementation of the applicationShouldTerminate: method, used here to
handle the saving of changes in the application managed object context
before the application terminates.
*/

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {

if (!managedObjectContext) return NSTerminateNow;

if (![managedObjectContext commitEditing]) {
NSLog(@"%@:%s unable to commit editing to terminate", [self class], _cmd);
return NSTerminateCancel;
}

if (![managedObjectContext hasChanges]) return NSTerminateNow;

NSError *error = nil;
if (![managedObjectContext save:&error]) {

// This error handling simply presents error information in a panel with an
// "Ok" button, which does not include any attempt at error recovery (meaning,
// attempting to fix the error.) As a result, this implementation will
// present the information to the user and then follow up with a panel asking
// if the user wishes to "Quit Anyway", without saving the changes.

// Typically, this process should be altered to include application-specific
// recovery steps.

BOOL result = [sender presentError:error];
if (result) return NSTerminateCancel;

NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");
NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:question];
[alert setInformativeText:info];
[alert addButtonWithTitle:quitButton];
[alert addButtonWithTitle:cancelButton];

NSInteger answer = [alert runModal];
[alert release];
alert = nil;

if (answer == NSAlertAlternateReturn) return NSTerminateCancel;

}

return NSTerminateNow;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

NSLog(@"DIDFINISH LAUNCHING");

}



-(IBAction)start:(id)sender
{
if([sender state]==0)
{
[sender setTitle:@"STOP"];
folderPath = [[folderpathTextField stringValue] copy];
NSLog(@"[folderpathTextField stringValue] : %@",[folderpathTextField stringValue]);
NSLog(@"folder path : %@",folderPath);
[self folderTracker];

}else {
[sender setTitle:@"START"];
[timer invalidate];
}


}

-(void)folderTracker
{
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(checkFolderStatus) userInfo:nil repeats:YES];


}

-(void)checkFolderStatus
{
NSLog(@"Tracker");
contents =[[NSFileManager defaultManager] directoryContentsAtPath:folderPath];

[self performSelectorOnMainThread:@selector(getFileProperties) withObject:contents waitUntilDone:YES];


}

-(void)getFileProperties

{
NSLog(@"contents %@", contents);
NSMutableArray *size = [[NSMutableArray alloc]init]; ///////allocating the arrays for holding the values for size type and icon////////////
NSMutableArray *type = [[NSMutableArray alloc]init];
NSMutableArray *icon1 = [[NSMutableArray alloc]init];
[dataArray removeAllObjects];
for(int i = 0; i<[contents count]; i++)
{
NSString *finalPath = [folderPath stringByAppendingPathComponent:[contents objectAtIndex:i]];
NSDictionary *fileAttributes1 = [[NSFileManager defaultManager] fileAttributesAtPath: finalPath traverseLink:NO];
NSLog(@"i = %d; fileAttributes1 %@",i,fileAttributes1);

NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile: finalPath]; //////////retriving the icon for the particular file ///////////

[icon1 addObject:icon]; //////////adding the icon object to the array of icons///////////
if(fileAttributes1 !=nil)
{
NSNumber *filsiz; /////////////defining the the filsize, fileType///////////////////////
NSNumber *kb=[NSNumber numberWithInt:1024];
NSString *size1;
if(filsiz=[fileAttributes1 objectForKey:NSFileSize])
{

if([filsiz intValue]>[kb intValue])
{
int siz=[filsiz intValue];
int num=(siz/1024);
size1=[NSString stringWithFormat:@"%d KB",num];
if(num>1024)
{
int num1=(num/(1024));
size1=[NSString stringWithFormat:@"%d MB",num1];
[size addObject:size1];

}

[size addObject:size1];
}
/////////////adding the filsiz to the size attribute defined in the tableAttributes class//////////
else
{
int siz=[filsiz intValue];
size1=[NSString stringWithFormat:@"%d Bytes",siz];
[size addObject:size1];
}
}
NSString * kind = [[NSWorkspace sharedWorkspace] typeOfFile:finalPath error:nil];
NSLog(@"file-----%@",kind);
NSString *folder=[NSString stringWithFormat:@"public.folder"];
if(kind==folder)
{
NSString *folderName=[NSString stringWithFormat:@"Folder"];
[type addObject:folderName];
}
else
{
NSString *fileKind= [[NSWorkspace sharedWorkspace] preferredFilenameExtensionForType:kind];
if(fileKind !=nil)
{
NSLog(@"file is %@",fileKind);
[type addObject:fileKind];
}
else{
fileKind=[NSString stringWithFormat:@"null"];
[type addObject:kind];
}
}
}


TableAttributes *tableAttributes = [[TableAttributes alloc]init];
tableAttributes.name = [contents objectAtIndex:i];
tableAttributes.fileSizeInfo= [size objectAtIndex:i];
tableAttributes.type= [type objectAtIndex:i];
tableAttributes.icon= [icon1 objectAtIndex:i];
if([[NSFileManager defaultManager]isReadableFileAtPath:finalPath])
{
//NSFileHandle *fileHandle = [[NSFileHandle alloc]init];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:finalPath];
NSData *data = [fileHandle availableData];
NSLog(@"%@", data);

tableAttributes.fileContents = data;

}
if([tableAttributes.name isEqualToString:@".DS_Store"])
{
//
}
else{
[dataArray addObject:tableAttributes];

}
[tableAttributes release];
}
[size release];
[icon1 release];
[type release];
[tableView reloadData];

//the data base should be updated again and again beacoz if file in the foder is not deleted but only its contents are changed, new contents should be also updated in db.

NSManagedObjectContext * context = [self managedObjectContext];
NSFetchRequest * fetch = [[[NSFetchRequest alloc] init] autorelease];
[fetch setEntity:[NSEntityDescription entityForName:@"fileDetails" inManagedObjectContext:context]];
NSArray * result = [context executeFetchRequest:fetch error:nil];
for (id basket in result)
[context deleteObject:basket];
NSError *saveError;
if (![[self managedObjectContext] save:&saveError]) {
[NSException raise:@"SaveException" format:@"Error while saving", ([saveError description] != nil) ? [saveError description] : @"Unknown Error"];
}


//storing the data

for (int i=0; i<[dataArray count]; i++) {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newobj = [NSEntityDescription insertNewObjectForEntityForName:@"fileDetails" inManagedObjectContext:context];

int fileSizeInfo = [[[dataArray objectAtIndex:i]fileSizeInfo]intValue];

[newobj setValue:[[dataArray objectAtIndex:i]name] forKey:@"name"];
[newobj setValue:[NSNumber numberWithInt:fileSizeInfo] forKey:@"size"];
[newobj setValue:[[dataArray objectAtIndex:i]fileContents] forKey:@"content"];
NSError *saveError;
if (![[self managedObjectContext] save:&saveError]) {
[NSException raise:@"SaveException" format:@"Error while saving", ([saveError description] != nil) ? [saveError description] : @"Unknown Error"];
}


}



}

-(IBAction)showStoredVal:(id)sender
{

NSFetchRequest *dataFetch = [[[NSFetchRequest alloc] init] autorelease];
[dataFetch setEntity:[NSEntityDescription entityForName:@"fileDetails" inManagedObjectContext:managedObjectContext]];
NSSortDescriptor* sortOrdering = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES] autorelease];
[dataFetch setSortDescriptors:[NSArray arrayWithObject:sortOrdering]];

NSError *fetchError;
manageDataArr = [managedObjectContext executeFetchRequest:dataFetch error:&fetchError];
for(int i = 0;i<[manageDataArr count]; i++)
{
NSLog(@"name::, %@", [[manageDataArr objectAtIndex:i] valueForKey:@"name"]);
NSLog(@"size::, %@", [[manageDataArr objectAtIndex:i] valueForKey:@"size"]);
NSLog(@"content::, %@", [[manageDataArr objectAtIndex:i] valueForKey:@"content"]);
}


}
-(IBAction)removeStoredVal:(id)sender{

NSManagedObjectContext * context = [self managedObjectContext];
NSFetchRequest * fetch = [[[NSFetchRequest alloc] init] autorelease];
[fetch setEntity:[NSEntityDescription entityForName:@"fileDetails" inManagedObjectContext:context]];
NSArray * result = [context executeFetchRequest:fetch error:nil];
for (id basket in result)
[context deleteObject:basket];
NSError *saveError;
if (![[self managedObjectContext] save:&saveError]) {
[NSException raise:@"SaveException" format:@"Error while saving", ([saveError description] != nil) ? [saveError description] : @"Unknown Error"];
}


}


///////////////////////////////table view delegate method///////////////////////////////////////////////////
#pragma mark -

-(id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(int)rowIndex
{
NSString *identifier = [aTableColumn identifier];
TableAttributes *obj = [dataArray objectAtIndex:rowIndex];
return [obj valueForKey:identifier];
}


-(int)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [dataArray count];
}

-(void)tableView:(NSTableView *)aTableView
setObjectValue:(id)anObject
forTableColumn:(NSTableColumn *)aTableColumn
row:(int)rowIndex
{
NSString *identifier = [aTableColumn identifier];
TableAttributes *obj = [dataArray objectAtIndex:rowIndex];
[obj setValue:anObject forKey:identifier];
}



Download the source from here: source code