Our application uses the GPUImage Framework to process images. We're utilizing just about every filter and blend mode within the framework. We're allocating and releasing memory as we should. But, in spite of the fact that our "Live" memory stays at about 2.5MB sometimes spiking to 10MB but dropping back to 2.5MB, the app, will without a doubt, crash after saving about 13 images out that use overlays or borders. So, in digging into the issue and being completely dumb founded by it, I saw something that said "check out the activity monitor for your "REAL" memory use". So I did only to find that the "Real" memory was climbing up and up until at around 250MB real and 480MB virtual the app will crash. I am releasing my mem as I should be. How can I determine what is consuming all of this memory and crashing my app when the "Live" memory stays perfect and I can drill into it, but, the "REAL" memory in the activity monitor climbs out of control and has no way of drilling into it?
Here is the code we're using to process the images. This will take the image, send it to the first filter, allocate the filter, process the image, release the allocated filter then send the processed image to the next filter for processing depending upon what filters are enabled or not. If I'm doing something wrong here I welcome all criticism and suggestions! I am no Pro! As far as I'm concerned, processing 13 images of the size 1536 x 2048 should not crash the app, ever, if you're handling your memory properly. Thank you so much in advance for saving what's left of my hair.
Jim
-(id)processFilters{
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
self.previewView.image = [UIImage imageWithContentsOfFile:[self.documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"thumb_%#", self.file]]];
if (sephiaFilterEnabled){
sephiaFilter = [[GPUImageSepiaFilter alloc] init];
[(GPUImageSepiaFilter *)sephiaFilter setIntensity:[_filterSephiaSlider value]];
self.previewView.image = [sephiaFilter imageByFilteringImage:previewView.image];
[sephiaFilter release];
}
if (saturationFilterEnabled){
saturationFilter = [[GPUImageSaturationFilter alloc] init];
[(GPUImageSaturationFilter *)saturationFilter setSaturation:[_filterSaturationSlider value]];
self.previewView.image = [saturationFilter imageByFilteringImage:previewView.image];
[saturationFilter release];
}
if (contrastFilterEnabled){
contrastFilter = [[GPUImageContrastFilter alloc] init];
[(GPUImageContrastFilter *)contrastFilter setContrast:[_filterContrastSlider value]];
self.previewView.image = [contrastFilter imageByFilteringImage:previewView.image];
[contrastFilter release];
}
if (brightnessFilterEnabled){
brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
[(GPUImageBrightnessFilter *)brightnessFilter setBrightness:[_filterBrightnessSlider value]];
self.previewView.image = [brightnessFilter imageByFilteringImage:previewView.image];
[brightnessFilter release];
}
if (exposureFilterEnabled){
exposureFilter = [[GPUImageExposureFilter alloc] init];
[(GPUImageExposureFilter *)exposureFilter setExposure:[_filterExposureSlider value]];
self.previewView.image = [exposureFilter imageByFilteringImage:previewView.image];
[exposureFilter release];
}
if (sharpenFilterEnabled){
sharpenFilter = [[GPUImageSharpenFilter alloc] init];
[(GPUImageSharpenFilter *)sharpenFilter setSharpness:[_filterSharpenSlider value]];
self.previewView.image = [sharpenFilter imageByFilteringImage:previewView.image];
[sharpenFilter release];
}
if (vignetteFilterEnabled){
vignetteFilter = [[GPUImageVignetteFilter alloc] init];
[(GPUImageVignetteFilter *)vignetteFilter setVignetteEnd:[_filterVignetteSlider value]];
self.previewView.image = [vignetteFilter imageByFilteringImage:previewView.image];
[vignetteFilter release];
}
if (gBlurFilterEnabled){
if(blurRadialEnabled){
gBlurFilter = [[GPUImageGaussianSelectiveBlurFilter alloc] init];
float yy;
float xx;
yy = blurToPoint.y / 320;
xx = blurToPoint.x / 240;
//NSLog (#"%f %f", xx, yy);
if(blurToPoint.x == 0 && blurToPoint.y == 0){
xx = 0.5;
yy = 0.5;
}
[(GPUImageGaussianSelectiveBlurFilter *)gBlurFilter setExcludeCirclePoint:CGPointMake(xx, yy)];
[(GPUImageGaussianSelectiveBlurFilter *)gBlurFilter setExcludeCircleRadius:[_filterGBlurSlider value]];
[(GPUImageGaussianSelectiveBlurFilter *)gBlurFilter setExcludeBlurSize:0.6];
self.previewView.image = [gBlurFilter imageByFilteringImage:previewView.image];
[gBlurFilter release];
}else if(blurBoxEnabled){
gBlurBoxFilter = [[GPUImageBoxBlurFilter alloc] init];
self.previewView.image = [gBlurBoxFilter imageByFilteringImage:previewView.image];
[gBlurBoxFilter release];
}else if(blurTiltEnabled){
gBlurTiltFilter = [[GPUImageTiltShiftFilter alloc] init];
float yy;
yy = blurToPoint.y / 320;
if(blurToPoint.y == 0){
yy = 0.5;
}
[(GPUImageTiltShiftFilter *)gBlurTiltFilter setTopFocusLevel:yy - [_filterTiltBlurSlider value]];
[(GPUImageTiltShiftFilter *)gBlurTiltFilter setBottomFocusLevel:yy + [_filterTiltBlurSlider value]];
self.previewView.image = [gBlurTiltFilter imageByFilteringImage:previewView.image];
[gBlurTiltFilter release];
}
}
if (cropFilterEnabled){
cropFilter = [[GPUImageCropFilter alloc] init];
float wBuff = [_filterCropSlider value] * cropToPoint.x;
float hBuff = [_filterCropSlider value] * cropToPoint.y;
float xp = cropToPoint.x - wBuff;
float yp = cropToPoint.y - hBuff;
float t1 = xp * [_filterCropSlider value];
float t2 = yp * [_filterCropSlider value];
xp = xp + (t1 * 4);
yp = yp + (t2 * 3.5);
xp = xp / 1000;
yp = yp / 1000;
//NSLog(#"%f, x: %f y: %f wB: %f hB: %f", [_filterCropSlider value], xp, yp, wBuff, hBuff);
[(GPUImageCropFilter *)cropFilter setCropRegion:CGRectMake(xp, yp, [_filterCropSlider value], [_filterCropSlider value])];
self.previewView.image = [cropFilter imageByFilteringImage:previewView.image];
[cropFilter release];
}
if (kuwaharaFilterEnabled){
kuwaharaFilter = [[GPUImageKuwaharaFilter alloc] init];
[(GPUImageKuwaharaFilter *)kuwaharaFilter setRadius:round([_filterKuwaharaSlider value])];
self.previewView.image = [kuwaharaFilter imageByFilteringImage:previewView.image];
[kuwaharaFilter release];
}
if (toonFilterEnabled){
toonFilter = [[GPUImageToonFilter alloc] init];
self.previewView.image = [toonFilter imageByFilteringImage:previewView.image];
[toonFilter release];
}
if (invertFilterEnabled){
invertFilter = [[GPUImageColorInvertFilter alloc] init];
self.previewView.image = [invertFilter imageByFilteringImage:previewView.image];
[invertFilter release];
}
if (pixelFilterEnabled){
pixelFilter = [[GPUImagePixellateFilter alloc] init];
[(GPUImagePixellateFilter *)pixelFilter setFractionalWidthOfAPixel:[_filterPixelSlider value]];
self.previewView.image = [pixelFilter imageByFilteringImage:previewView.image];
[pixelFilter release];
}
if (gammaFilterEnabled){
gammaFilter = [[GPUImageGammaFilter alloc] init];
[(GPUImageGammaFilter *)gammaFilter setGamma:[_filterGammaSlider value]];
self.previewView.image = [gammaFilter imageByFilteringImage:previewView.image];
[gammaFilter release];
}
if (sketchFilterEnabled){
sketchFilter = [[GPUImageSketchFilter alloc] init];
self.previewView.image = [sketchFilter imageByFilteringImage:previewView.image];
[sketchFilter release];
}
if (swirlFilterEnabled){
swirlFilter = [[GPUImageSwirlFilter alloc] init];
[(GPUImageSwirlFilter *)swirlFilter setAngle:[_filterSwirlSlider value]];
self.previewView.image = [swirlFilter imageByFilteringImage:previewView.image];
[swirlFilter release];
}
if (overlayFilterEnabled){
if (![self.overlayImage compare:#""] == NSOrderedSame){
GPUImageOutput<GPUImageInput> *overlayFilter;
if(multiplyBlendEnabled){
overlayFilter = [[GPUImageMultiplyBlendFilter alloc] init];
}else if(overlayBlendEnabled){
overlayFilter = [[GPUImageOverlayBlendFilter alloc] init];
}else if(lightenBlendEnabled){
overlayFilter = [[GPUImageLightenBlendFilter alloc] init];
}else if(darkenBlendEnabled){
overlayFilter = [[GPUImageDarkenBlendFilter alloc] init];
}else if(burnBlendEnabled){
overlayFilter = [[GPUImageColorBurnBlendFilter alloc] init];
}else if(dodgeBlendEnabled){
overlayFilter = [[GPUImageColorDodgeBlendFilter alloc] init];
}else if(screenBlendEnabled){
overlayFilter = [[GPUImageScreenBlendFilter alloc] init];
}else if(differenceBlendEnabled){
overlayFilter = [[GPUImageDifferenceBlendFilter alloc] init];
}else if(subtractBlendEnabled){
overlayFilter = [[GPUImageSubtractBlendFilter alloc] init];
}else if(exclusionBlendEnabled){
overlayFilter = [[GPUImageExclusionBlendFilter alloc] init];
}else if(hardLightBlendEnabled){
overlayFilter = [[GPUImageHardLightBlendFilter alloc] init];
}else if(softLightBlendEnabled){
overlayFilter = [[GPUImageSoftLightBlendFilter alloc] init];
}else{
overlayFilter = [[GPUImageMultiplyBlendFilter alloc] init];
}
UIImage *inputImage = [[[UIImage alloc]init]autorelease];
// The picture is only used for two-image blend filters
inputImage = [UIImage imageNamed:[NSString stringWithFormat:#"preview_%#.jpg", self.overlayImage]];
GPUImagePicture *sourcePreviewPicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];
[sourcePreviewPicture addTarget:overlayFilter];
inputImage = [overlayFilter imageByFilteringImage:self.previewView.image];
if(overlayOpacityFilterEnabled){
GPUImageOutput<GPUImageInput> *overlayOpacityFilter = [[GPUImageAlphaBlendFilter alloc] init];
sourcePreviewPicture = [[GPUImagePicture alloc] initWithImage:self.previewView.image smoothlyScaleOutput:YES];
[sourcePreviewPicture addTarget:overlayOpacityFilter];
[(GPUImageAlphaBlendFilter *)overlayOpacityFilter setMix:[_filterOverlayOpacitySlider value]];
inputImage = [overlayOpacityFilter imageByFilteringImage:inputImage];
[overlayOpacityFilter release];
}
self.previewView.image = inputImage;
[overlayFilter release];
[sourcePreviewPicture release];
}
}
if (borderFilterEnabled){
if (![self.borderImage compare:#""] == NSOrderedSame){
GPUImageOutput<GPUImageInput> *borderFilter;
if ([self.borderImage rangeOfString:#"black"].location == NSNotFound) {
borderFilter = [[GPUImageLightenBlendFilter alloc] init];
} else {
borderFilter = [[GPUImageMultiplyBlendFilter alloc] init];
}
UIImage *inputImage = [[[UIImage alloc]init]autorelease];
// The picture is only used for two-image blend filters
inputImage = [UIImage imageNamed:[NSString stringWithFormat:#"preview_%#.jpg", self.borderImage]];
GPUImagePicture *sourcePreviewPicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];
[sourcePreviewPicture addTarget:borderFilter];
self.previewView.image = [borderFilter imageByFilteringImage:self.previewView.image];
[borderFilter release];
[sourcePreviewPicture release];
}
}
[loopPool drain];
return self.previewView.image;
}
Related
Application get crashed for barcode scanning using AVFoundation.
following is my code.
_session = [[AVCaptureSession alloc] init];
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
_input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
if (_input) {
[_session addInput:_input];
} else {
NSLog(#"Error: %#", error);
}
_output = [[AVCaptureMetadataOutput alloc] init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_output];
_output.metadataObjectTypes = [_output availableMetadataObjectTypes];
_prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_prevLayer.frame = _previewView.bounds;
_prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//[self.view.layer addSublayer:_prevLayer];
[_previewView.layer addSublayer:_prevLayer];
//[self.view];
//[_session startRunning];
[_previewView bringSubviewToFront:_highlightView];
/* code Ends*/
Showing Bad Access.
[_previewView.layer addSublayer:_prevLayer];
This line occurs after the frame is set. Try adding the layer and then setting the frame. I'm sure you've moved on, but this answer could benefit someone else.
I have wrote this code for creating room. Using this i had created room in openfire.
-(void)createGroup:(NSString*)groupName
{
XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] init];
xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:rosterstorage jid:[XMPPJID jidWithString:[NSString stringWithFormat:#"%##conference.%#/%#",groupName,#"server",self.strUsername]] dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:[self xmppStream]];
[xmppRoom joinRoomUsingNickname:#"nickname" history:nil];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[self performSelector:#selector(ConfigureNewRoom) withObject:nil afterDelay:5];
}
-(void)ConfigureNewRoom
{
[xmppRoom fetchConfigurationForm];
[xmppRoom configureRoomUsingOptions:nil];
}
Now I want to add buddy/users in the group. so how can i do this ? Thanks in advance.
// Using this it is done
XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];
NSString *strJid = [NSString stringWithFormat:#"%##conference.%#/%#",groupname,strHostname,self.strUsername];
self.xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage jid:[XMPPJID jidWithString:strJid] dispatchQueue:dispatch_get_main_queue()];
[self.xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[self.xmppRoom activate:self.xmppStream];
[self.xmppRoom joinRoomUsingNickname:self.strUsername history:nil];
//inviting
NSString *strInvitedUserName = [NSString stringWithFormat:#"%##%#",personName,strHostname];
[self.xmppRoom inviteUser:[XMPPJID jidWithString:strInvitedUserName] withMessage:message];
You can add it to your roster in this way:
[[[self appDelegate] xmppRoster] addUser:[XMPPJID jidWithString:#"userName"] withNickname:[NSString stringWithFormat:#"%# %#", firstName, lastName] groups:[NSArray arrayWithObjects:#"general", nil]];
and check it:
XMPPRosterCoreDataStorage *xmppRosterStorage = [[self appDelegate] xmppRosterStorage];
BOOL knownUser = [xmppRosterStorage userExistsWithJID:[XMPPJID jidWithString:#"userName"] xmppStream:[self xmppStream]];
I have an NSMutableArray with 9 objects. Those objects have many properties, like questionName, questionWhatRow, etc.
I want to be able to change one of those properties for All of the objects in the NSMutableArray.
Here is my NSMutableArray Class.
-(id) init
{
self = [super init];
if (self)
{
self.questionsArray = [[NSMutableArray alloc] init];
Question *newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is the name of the girl who has to fetch water for her family every day?";
newQuestion.questionRowName = #"Question 1";
newQuestion.questionAnswer = #"Nya";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is Nya's sister's name?";
newQuestion.questionRowName = #"Question 2";
newQuestion.questionAnswer = #"Akeer";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What people is Nya's mother scared of when her father and sons go hunting?";
newQuestion.questionRowName = #"Question 3";
newQuestion.questionAnswer = #"Dinka";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is Salva scared of when he is in the Akobo desert?";
newQuestion.questionRowName = #"Question 4";
newQuestion.questionAnswer = #"Lions";
newQuestion.questionHint = #"He is scared of an animal because it ate his friend Marial";
newQuestion = nil;
}
return self;
}
-(NSUInteger)count
{
return questionsArray.count;
}
- (Question *)questionAtIndex:(NSUInteger)index
{
return [questionsArray objectAtIndex:index];
}
Now, I have another class called ScoreViewController, and I want to be able to change the property, questionCompleteOrNot of the NSMutableArray questionsArray for all objects/questions to #"No".
My ScoreView has a button to Reset, but I don't know what to put in it to change all questionCompleteOrNot properties of the questionsArray to #"No".
Sorry for the long question, I was trying to be very specific.
Edit
Here is my DetailView for a tableView.
if ([[selectedQuestion questionCompleteOrNot] isEqualToString:#"No"])
{
if ([[selectedQuestion questionAnswer] caseInsensitiveCompare:answerField.text] == NSOrderedSame)
{
// Show the correct label
[correctLabel setHidden:NO];
correctLabel.text = #"Correct!";
correctLabel.textColor = [UIColor greenColor];
}
else
{
// Show the incorrect label
[correctLabel setHidden:NO];
correctLabel.text = #"Incorrect";
correctLabel.textColor = [UIColor redColor];
[incorrectPlayer play];
[[selectedQuestion questionCompleteOrNot] isEqualToString:#"Yes"];
}
// Erase the text in the answerField
answerField.text = #"";
}
if ([[selectedQuestion questionCompleteOrNot] isEqualToString:#"Yes"])
{
UIAlertView *error = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"You already answered this question. Please click the reset button on the score view to restart."
delegate:self
cancelButtonTitle:#"Okay!"
otherButtonTitles:nil];
[error show];
answerField.text = #"";
}
selectedQuestion.questionCompleteOrNot = #"Yes";
correctLabel.text = #"";
NSLog(#"Selected question's questionCompleteOrNot is %#", [selectedQuestion questionCompleteOrNot]);
You can use NSArray's makeObjectsPerformSelector:withObject:, like so:
[questionsArray makeObjectsPerformSelector:#selector(setQuestionCompleteOrNot:) withObject:#"No"];
-(void)processImage:(NSString*)inputPath:(int)imageWidth:(int)imageHeight:(NSString*)outputPath {
// NSImage * img = [NSImage imageNamed:inputPath];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:inputPath];
[image setSize: NSMakeSize(imageWidth,imageHeight)];
[[image TIFFRepresentation] writeToFile:outputPath atomically:NO];
NSLog(#"image file created");
}
- (IBAction)processImage:(id)sender {
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
// NSTimeInterval is defined as double
NSNumber *timeStampObj = [NSNumber numberWithInt:timeStamp];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterNoStyle];
NSString *convertNumber = [formatter stringForObjectValue:timeStampObj];
NSLog(#"timeStampObj:: %#", convertNumber);
fileNameNumber = [[convertNumber stringByAppendingString:[self genRandStringLength:8]] retain];
int i; // Loop counter.
// Loop through all the files and process them.
for( i = 0; i < [files count]; i++ )
{
inputFilePath = [[files objectAtIndex:i] retain];
NSLog(#"filename::: %#", inputFilePath);
// Do something with the filename.
[selectedFile setStringValue:inputFilePath];
NSLog(#"selectedFile:::: %#", selectedFile);
}
NSLog(#"curdir:::::%#", inputFilePath);
NSString *aString = [[NSString stringWithFormat:#"%#%#%#", thumbnailDirPath , #"/" , fileNameNumber] retain];
fileNameJPG = [[aString stringByAppendingString:#"_small.jpg"] retain];
fileNameJPG1 = [[aString stringByAppendingString:#".jpg"] retain];
fileNameJPG2 = [[aString stringByAppendingString:#"_H.jpg"] retain];
[self processImage:inputFilePath: 66 :55 :fileNameJPG];
[self processImage:inputFilePath: 800 :600 :fileNameJPG1];
[self processImage:inputFilePath: 320 :240 :fileNameJPG2];
}
The issue I am facing is that the above code is generating 3 files with different names(as I have defined the name should be) having the same size of all 3 files but not with the dimensions or width/length I pass to the function.
What can be the issue ?
NSImage objects are immutable. So image is not modified when you change its size.
You should use something like the following code (adapted from here).
-(void)saveImageAtPath:(NSString*)sourcePath toPath:(NSString*)targetPath withWidth:(int)targetWidth andHeight:(int)targetHeight
{
NSImage *sourceImage = [[NSImage alloc] initWithContentsOfFile:sourcePath];
NSImage *targetImage = [[NSImage alloc] initWithSize: NSMakeSize(targetWidth, targetHeight)];
NSSize sourceSize = [sourceImage size];
NSRect sourceRect = NSMakeRect(0, 0, sourceSize.width, sourceSize.height);
NSRect targetRect = NSMakeRect(0, 0, targetWidth, targetWidth);
[targetImage lockFocus];
[sourceImage drawInRect:targetRect fromRect:sourceRect operation: NSCompositeSourceOver fraction: 1.0];
[targetImage unlockFocus];
[[targetImage TIFFRepresentation] writeToFile:targetPath atomically:NO];
NSLog(#"image file created");
[sourceImage release];
[targetImage release];
}
In my app I have a Place entity that contains reviews and featured objects at the minute my app is constantly refreshing these everytime i parse my xml data which is fine however I need to delete the review and featued objects before they are re parsed. My code is as follows and I believe I need to delete the objects in the parseXML method at the top:
-(void)parseXML:(NSString*)xml{
TBXML * tbxml = [TBXML tbxmlWithXMLString:xml];
if(tbxml.rootXMLElement){
[self traverseElement:tbxml.rootXMLElement];
if(self.tempItem){
NSLog(#"Ending Application");
[self configurePlaceChildrenAndSave];
[self startGeoCodingQueue];
}
}
}
-(void)fireGeocoder:(BSForwardGeocoder*)g{
NSLog(#"Begining FGC for %# (%#)",g.searchQuery,g.metaData);
[g findLocation];
}
-(void)startGeoCodingQueue{
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kGeoCoderInProgress];
int i = 0;
BSForwardGeocoder * fgc;
NSArray * a = [CoreDataBasicService fetchResultsForEnity:#"Place" andSortDiscriptor:#"name" Ascending:YES];
for (Place * p in a) {
if(p.latitude && p.longitude)continue;//skip geocoding if location data exists
fgc = [[BSForwardGeocoder alloc] initWithDelegate:self];
fgc.metaData = p.name;
fgc.searchQuery = p.postcode;
NSLog(#"gc:%i-%i",i,[a count]);
if([a count] == i+1){
fgc.last = YES;
}
float delay = (float)i*kGeoCoderDelay;
[self performSelector:#selector(fireGeocoder:) withObject:[fgc autorelease] afterDelay:delay];
fgc = nil;
i++;
}
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:i] forKey:kGeoCoderCompletedKey];
}
-(void)finishedGeocoding{
[[NSUserDefaults standardUserDefaults] setValue:[NSDate date] forKey:kGeoCoderlastRanKey];
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:NO] forKey:kGeoCoderInProgress];
[[NSNotificationCenter defaultCenter] postNotificationName:kGeoCoderNotificationName object:nil];
}
-(void)forwardGeocoderError:(BSForwardGeocoder *)geocoder errorMessage:(NSString *)errorMessage{
NSLog(#"EX ERROR: GEOCODER FAILED - %#",errorMessage);
if(geocoder.last)[self finishedGeocoding];
}
- (void)forwardGeocoderFoundLocation:(BSForwardGeocoder*)geocoder
{
if(geocoder.status == G_GEO_SUCCESS)
{
BSKmlResult *result = [geocoder.results lastObject];
if(!result)return;
//[self.fowardGeocodingQueue setObject:[NSString stringWithString:value] forKey:self.tempItem.name];
Place * p = [CoreDataBasicService fetchPlaceNamed:geocoder.metaData];
p.latitude = [NSNumber numberWithFloat:result.latitude];
p.longitude = [NSNumber numberWithFloat:result.longitude];
[CoreDataBasicService saveChanges];
//NSLog(#"%# - %f,%f",p2.name,p2.latitude,p2.longitude);
NSLog(#"completed Foward geocoding for '%#' (%#) [%f,%f]",geocoder.metaData,geocoder.searchQuery,[p.latitude floatValue],[p.longitude floatValue]);
if(geocoder.last)[self finishedGeocoding];
}
else {
NSString *message = #"";
switch (geocoder.status) {
case G_GEO_BAD_KEY:
message = #"The API key is invalid.";
break;
case G_GEO_UNKNOWN_ADDRESS:
message = [NSString stringWithFormat:#"Could not find %#", geocoder.searchQuery];
break;
case G_GEO_TOO_MANY_QUERIES:
message = #"Too many queries has been made for this API key.";
break;
case G_GEO_SERVER_ERROR:
message = #"Server error, please try again.";
break;
default:
break;
}
NSLog(#"ERROR: GEOCODER FAILED - %#",message);
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Information"
// message:message
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles: nil];
// [alert show];
// [alert release];
}
}
-(void)configurePlaceChildrenAndSave{
if(self.tempReviewArray.count==0 && self.tempReview)[self.tempReviewArray addObject:self.tempReview];
if(self.tempFeatureArray.count==0 && self.tempFeature)[self.tempFeatureArray addObject:self.tempFeature];
[self.tempItem setReviews:self.tempReviewArray];
[self.tempItem setFeatured:self.tempFeatureArray];
self.tempReviewArray = nil;
self.tempReview = nil;
self.tempFeatureArray = nil;
self.tempFeature = nil;
[CoreDataBasicService saveChanges];
self.tempItem = nil;
}
-(NSString*)formatKeyForCoreData:(NSString*)elementKey{
return [elementKey stringByReplacingOccurrencesOfString:#"-" withString:#""];
}
-(NSDate*)convertStringDateToDate:(NSString*)stringDate{
NSDateFormatter * df = [[NSDateFormatter alloc] init];
NSLog(#"DATE:%#",stringDate);
[df setDateFormat:#"y-M-d'T'H:m:s'Z'"];
NSDate * d = [df dateFromString:stringDate];
[df release];
return d;
}
-(Place*)getPlaceForName:(NSString*)name{
NSPredicate * pred = [NSPredicate predicateWithFormat:#"name = %#",name];
NSArray * results = [CoreDataBasicService fetchResultsForEnity:#"Place" WithPredicate:pred andSortDiscriptor:#"identifier" Ascending:YES];
return [results lastObject];
}
-(void)traverseElement:(TBXMLElement *)element {
do {
// Display the name of the element
NSString * value = [TBXML textForElement:element];
NSLog(#"%#-'%#'",[TBXML elementName:element],value);
// Obtain first attribute from element
NSString * ele = [TBXML elementName:element];
if([ele isEqualToString:#"place"]){
if(self.tempItem){
//GEOCODER HERE
[self configurePlaceChildrenAndSave];
}
//CREATE NEW CD ITEM HER
if(dataBaseExits){
TBXMLElement * idElement = [TBXML childElementNamed:#"name" parentElement:element];
Place * p = [self getPlaceForName:[NSString stringWithFormat:#"%#",[TBXML textForElement:idElement]]];
if(p){
[self setTempItem:p];
TBXMLElement * reviewsElement = [TBXML childElementNamed:#"reviews" parentElement:element];
if(reviewsElement){
self.tempItem.reviews = nil;
[CoreDataBasicService saveChanges];
[self traverseElement:reviewsElement];
}
TBXMLElement * promosElement = [TBXML childElementNamed:#"featured-places" parentElement:element];
if(promosElement){
self.tempItem.featured = nil;
[CoreDataBasicService saveChanges];
[self traverseElement:promosElement];
}
[CoreDataBasicService saveChanges];
continue;
}