#import "TFObjects.h" #import "Actor.h" #import "IntegrationProfile.h" #import "ActorIntegrationProfile.h" #import "TFBrowserAppDelegate.h" #import "ActorIntegrationProfileOption.h" @interface TFObjects(mymethods) // these are private methods that outside classes need not use - (void)presortActorInitialLetterIndexes ; - (void)presortActorNamesForInitialLetter:(NSString *)aKey ; - (void)presortProfileInitialLetterIndexes ; - (void)presortProfileNamesForInitialLetter:(NSString *)aKey ; - (void)presortAIPOInitialLetterIndexes ; - (void)presortAIPONamesForInitialLetter:(NSString *)aKey ; - (void)setupTFObjects ; @end @implementation TFObjects @synthesize aipoDictionary , aipoIndexesDictionary , aipoIndexArray , arrayOfAIPO ; @synthesize actorsDictionary , actorIndexesDictionary , arrayOfActors ,actorsIndexArray ; @synthesize profilesDictionary , profileIndexesDictionary , arrayOfIntegrationProfiles , profilesIndexArray ; // we use the singleton approach, one collection for the entire application static TFObjects * tfObjectsInstance = nil; + (TFObjects*)tfObjects { @synchronized(self) { if (tfObjectsInstance == nil) { [[self alloc] init]; // assignment not done here } } return tfObjectsInstance ; // note: Xcode (3.2) static analyzer will report this singleton as a false positive // '(Potential leak of an object allocated') } + (id)allocWithZone:(NSZone *)zone { @synchronized(self) { if (tfObjectsInstance == nil) { tfObjectsInstance = [super allocWithZone:zone]; return tfObjectsInstance ; // assignment and return on first allocation } } return nil; //on subsequent allocation attempts return nil } - (id)copyWithZone:(NSZone *)zone { return self; } - (id)retain { return self; } - (unsigned)retainCount { return UINT_MAX; //denotes an object that cannot be released } - (void)release { //do nothing } - (id)autorelease { return self; } - (void)setupTFObjects { TFBrowserAppDelegate * delegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext * context = [delegate managedObjectContext]; self.actorsDictionary = [NSMutableDictionary dictionary] ; self.actorIndexesDictionary = [NSMutableDictionary dictionary] ; NSMutableDictionary * dictionnaryOfActors = [[NSMutableDictionary alloc] init]; if ( arrayOfActors == nil ) { arrayOfActors = [[NSMutableArray alloc]init]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Actor" inManagedObjectContext:context]; [request setEntity:entity]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"keyword" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [request setSortDescriptors:sortDescriptors]; [sortDescriptors release]; [sortDescriptor release]; NSError *error; NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy]; if (mutableFetchResults == nil) { // Handle the error. } for ( id element in mutableFetchResults ) { Actor * a = (Actor * ) element ; if ( [dictionnaryOfActors objectForKey:[a keyword]] == nil ) { [dictionnaryOfActors setObject:a forKey:[a keyword]] ; } } [mutableFetchResults release]; [request release]; } for ( id eachElement in [dictionnaryOfActors allValues] ) { // create an atomic element instance for each Actor * anActor = [(Actor *)eachElement retain] ; if ( anActor != nil ) { [actorsDictionary setObject:anActor forKey: anActor.keyword]; // get the element's initial letter NSString *firstLetter = [anActor.keyword substringToIndex:1]; NSMutableArray * existingArray ; // if an array already exists in the name index dictionary // simply add the element to it, otherwise create an array // and add it to the name index dictionary with the letter as the key if (existingArray = [actorIndexesDictionary valueForKey:firstLetter]) { [existingArray addObject:anActor]; } else { NSMutableArray *tempArray = [NSMutableArray array]; [actorIndexesDictionary setObject:tempArray forKey:firstLetter]; [tempArray addObject:anActor]; } // release the element, it is held by the various collections [anActor release]; } } [dictionnaryOfActors release] ; [self presortActorInitialLetterIndexes]; self.profilesDictionary = [NSMutableDictionary dictionary] ; self.profileIndexesDictionary = [NSMutableDictionary dictionary] ; NSMutableDictionary * dictionnaryOfProfiles = [[NSMutableDictionary alloc] init]; if ( arrayOfIntegrationProfiles == nil ) { arrayOfActors = [[NSMutableArray alloc]init]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"IntegrationProfile" inManagedObjectContext:context]; [request setEntity:entity]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"keyword" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [request setSortDescriptors:sortDescriptors]; [sortDescriptors release]; [sortDescriptor release]; NSError *error; NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy]; if (mutableFetchResults == nil) { // Handle the error. } for ( id element in mutableFetchResults ) { IntegrationProfile * ip = (IntegrationProfile * ) element ; if ( [dictionnaryOfProfiles objectForKey:[ip keyword]] == nil ) { [dictionnaryOfProfiles setObject:ip forKey:[ip keyword]] ; } } //[request release]; } for ( id eachElement in [dictionnaryOfProfiles allValues] ) { // create an atomic element instance for each IntegrationProfile * aProfile = (IntegrationProfile *)eachElement ; if ( aProfile != nil ) { [profilesDictionary setObject:aProfile forKey: aProfile.keyword]; // get the element's initial letter NSString *firstLetter = [aProfile.keyword substringToIndex:1]; NSMutableArray * existingArray ; // if an array already exists in the name index dictionary // simply add the element to it, otherwise create an array // and add it to the name index dictionary with the letter as the key if (existingArray = [profileIndexesDictionary valueForKey:firstLetter]) { [existingArray addObject:aProfile]; } else { NSMutableArray *tempArray = [NSMutableArray array]; [profileIndexesDictionary setObject:tempArray forKey:firstLetter]; [tempArray addObject:aProfile]; } // release the element, it is held by the various collections [aProfile release]; } } [dictionnaryOfProfiles release]; [self presortProfileInitialLetterIndexes]; self.aipoDictionary = [NSMutableDictionary dictionary] ; self.aipoIndexesDictionary = [NSMutableDictionary dictionary] ; if ( arrayOfAIPO == nil ) { arrayOfAIPO = [[NSMutableArray alloc]init]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"ActorIntegrationProfileOption" inManagedObjectContext:context]; [request setEntity:entity]; NSSortDescriptor *sortDescriptorIP = [[NSSortDescriptor alloc] initWithKey:@"actorIntegrationProfile.integrationProfile.keyword" ascending:NO]; NSSortDescriptor *sortDescriptorActor = [[NSSortDescriptor alloc] initWithKey:@"actorIntegrationProfile.actor.keyword" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptorIP,sortDescriptorActor, nil]; [request setSortDescriptors:sortDescriptors]; [sortDescriptors release]; [sortDescriptorIP release]; [sortDescriptorActor release]; NSError *error; NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy]; if (mutableFetchResults == nil) { // Handle the error. } for ( id eachElement in mutableFetchResults ) { // create an atomic element instance for each ActorIntegrationProfileOption * aipo = [(ActorIntegrationProfileOption *)eachElement retain] ; if ( aipo != nil ) { [aipoDictionary setObject:aipo forKey: [[NSString alloc] initWithFormat:@"%@-%@-%@",aipo.actorIntegrationProfile.integrationProfile.keyword,aipo.actorIntegrationProfile.actor.keyword,aipo.actorIntegrationProfile.integrationProfile.keyword]] ; // get the element's initial letter NSString *firstLetter = [[NSString alloc] initWithFormat:@"%@-%@",[aipo.actorIntegrationProfile.integrationProfile.keyword substringToIndex:1],[aipo.actorIntegrationProfile.actor.keyword substringToIndex:1]] ; NSMutableArray * existingArray ; // if an array already exists in the name index dictionary // simply add the element to it, otherwise create an array // and add it to the name index dictionary with the letter as the key NSLog(@"firstLetter %@" , firstLetter ) ; if (existingArray = [aipoIndexesDictionary valueForKey:firstLetter]) { [existingArray addObject:aipo]; } else { NSMutableArray *tempArray = [NSMutableArray array]; [aipoIndexesDictionary setObject:tempArray forKey:firstLetter]; [tempArray addObject:aipo]; } // release the element, it is held by the various collections [aipo release]; } } } //[dictionnaryOfActors release] ; [self presortAIPOInitialLetterIndexes]; } // return an array of elements for an initial letter (ie A, B, C, ...) - (NSArray *)actorsWithInitialLetter:(NSString*)aKey { return [actorIndexesDictionary objectForKey:aKey]; } // presort the name index arrays so the elements are in the correct order - (void)presortActorInitialLetterIndexes { self.actorsIndexArray = [[actorIndexesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; for (NSString *eachNameIndex in actorsIndexArray) { [self presortActorNamesForInitialLetter:eachNameIndex]; } } - (void)presortActorNamesForInitialLetter:(NSString *)aKey { NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] ; NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; [[actorIndexesDictionary objectForKey:aKey] sortUsingDescriptors:descriptors]; [nameDescriptor release]; } ////IP // return an array of elements for an initial letter (ie A, B, C, ...) - (NSArray *)profilesWithInitialLetter:(NSString*)aKey { return [profileIndexesDictionary objectForKey:aKey]; } // presort the name index arrays so the elements are in the correct order - (void)presortProfileInitialLetterIndexes { self.profilesIndexArray = [[profileIndexesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; for (NSString *eachNameIndex in actorsIndexArray) { [self presortProfileNamesForInitialLetter:eachNameIndex]; } } - (void)presortProfileNamesForInitialLetter:(NSString *)aKey { NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] ; NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; [[profileIndexesDictionary objectForKey:aKey] sortUsingDescriptors:descriptors]; [nameDescriptor release]; } //AIPO // return an array of elements for an initial letter (ie A, B, C, ...) - (NSArray *)aipoWithInitialLetter:(NSString*)aKey { return [aipoIndexesDictionary objectForKey:aKey]; } // presort the name index arrays so the elements are in the correct order - (void)presortAIPOInitialLetterIndexes { self.aipoIndexArray = [[aipoIndexesDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; //for (NSString *eachNameIndex in aipoIndexArray) { // [self presortAIPONamesForInitialLetter:eachNameIndex]; //} } - (void)presortAIPONamesForInitialLetter:(NSString *)aKey { NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"actorIntegrationProfile.integrationProfile.keyword" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] ; NSArray *descriptors = [NSArray arrayWithObject:nameDescriptor]; [[aipoIndexesDictionary objectForKey:aKey] sortUsingDescriptors:descriptors]; [nameDescriptor release]; } @end