How to Add Multiple Placemarks and Annotations to Map - objective-c

I have a class that loads a map, get my current location, then does a search on my database for companies in an area based on a zip code radius. I am doing a for loop to loop through each address, forward geocode, now I want to put a placemark and annotation for each location. How can I accomplish this. Here is my code:
- (void)locationUpdate:(CLLocation *)location {
locationLabel.text = [location description];
NSNumber *lat = [[NSString alloc] initWithFormat:#"%g", location.coordinate.latitude];
float latValue = [lat floatValue];
NSNumber *lng = [[NSString alloc] initWithFormat:#"%g", location.coordinate.longitude];
float lngValue = [lng floatValue];
mapView=[[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.showsUserLocation=TRUE;
mapView.mapType=MKMapTypeStandard;
mapView.delegate=self;
/*Region and Zoom*/
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
CLLocationCoordinate2D location1=mapView.userLocation.coordinate;
location1.latitude=latValue;
location1.longitude=lngValue;
region.span=span;
region.center=location1;
/*Geocoder Stuff*/
geoCoder=[[MKReverseGeocoder alloc] initWithCoordinate:location1];
geoCoder.delegate=self;
[geoCoder start];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
[self.view insertSubview:mapView atIndex:0];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geoCoder didFindPlacemark:(MKPlacemark *)placemark
{
NSDictionary *zipDic = [placemark addressDictionary];
NSString *zipCode = [zipDic objectForKey:#"ZIP"];
NSString *post = [NSString stringWithFormat:#"zip=%#", zipCode];
NSString *hostString = #"https://www.mysite.com/searchzip.php?";
// Append string and add percent escapes
hostString = [[hostString stringByAppendingString:post] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostString];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
self.zipArray = [jsonString JSONValue];
NSLog(#"%#", zipArray);
for (NSString *sZip in zipArray) {
NSString *lblAddress = [sZip objectForKey:#"address"];
NSString *hostStr = [[#"http://maps.google.com/maps/geo?q=" stringByAppendingString:lblAddress]stringByAppendingString:#"&key=ABQIAAAA1KqXKe5yJPkX6ii6Ud K-0RSIvIZDM4KnjydqrehqKK56hFf_fxQc0uyCKoh-4i77-5B0Qfc8Gs223Q&sensor=false&output=json"];
hostStr = [hostStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostStr];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming json_string is a NSString of JSON data
NSArray *object = [parser objectWithString:jsonString error:nil];
NSArray *placemarks = [object objectForKey:#"Placemark"];
NSDictionary *mark = [placemarks objectAtIndex:0];
NSDictionary *point = [mark objectForKey:#"Point"];
NSArray *coordinates = [point objectForKey:#"coordinates"];
NSNumber *lat = (NSNumber*)[coordinates objectAtIndex:0];
float latValue = [lat floatValue];
NSNumber *lon = (NSNumber*)[coordinates objectAtIndex:1];
float lonValue = [lon floatValue];
//Here is where I would put placemarks and annotations
}
}
- (void)locationError:(NSError *)error {
locationLabel.text = [error description];
}
#end
I tried...
CLLocationCoordinate2D location = {latitude: latValue, longitude: lonValue};
return location;
But obviously its wrong.
I tried creating a seperate MapAnnotation class to handle the annotations like so:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import "AgencyViewController.h"
#interface MapAnnotation : NSObject<MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *subtitletext;
NSString *titletext;
}
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (readwrite, retain) NSString *titletext;
#property (readwrite, retain) NSString *subtitletext;
-(id)initWithCoordinate:(CLLocationCoordinate2D) coordinate;
- (NSString *)subtitle;
- (NSString *)title;
-(void)setTitle:(NSString*)strTitle;
-(void)setSubTitle:(NSString*)strSubTitle;
and implement it like so:
CLLocationCoordinate2D newCoord = {latitude: latValue, longitude: lonValue};
MapAnnotation *addAnnotation = [[MapAnnotation alloc] initWithCoordinate:newCoord];
[addAnnotation setTitle:#"The Pin Title"];
[addAnnotation setSubTitle:#"The pin subtitle goes here"];
[mapView addAnnotation:addAnnotation];
And that didnt work either...

Figured it out, needed to add
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"Prospects"];
if(pinView == nil) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"Prospects"];
pinView.pinColor = MKPinAnnotationColorGreen;
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
} else {
pinView.annotation = annotation;
}
return pinView;
}
Now I need to figure out how to change the color of my location pin.

Related

two PickerViews of a single Sqlite3 Database

I must be doing something wrong here. My SQLite database is working. However, I cannot seem to populate the tname into a picker view while the picked populates three text fields tname, latitude, and longitude.
Info: Two picker views that are independent from each other, they both read the same sqlite db.
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *array1;
sqlite3 *towerDB;
NSString *dbPathString;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//UIPickerView *pickerview1;
//array1 = [[NSMutableArray alloc]init];
[[self pickerview1]setDelegate:self];
[[self pickerview1]setDataSource:self];
[self displayTower];
}
- (void)displayTower
{
array1 = [[NSMutableArray alloc] init];
sqlite3_stmt *statement;
if (sqlite3_open([dbPathString UTF8String], &towerDB)==SQLITE_OK) {
[array1 removeAllObjects];
NSString *querySql = [NSString stringWithFormat:#"SELECT * FROM TOWERS"];
const char* query_sql = [querySql UTF8String];
// sqlite3_clear_bindings(statement);
// sqlite3_reset(statement);
if (sqlite3_prepare(towerDB, query_sql, -1, &statement, NULL)==SQLITE_OK) // NOT OK
//This Code works in a TableView!!
//Will NOT work in a PickerView
{
while (sqlite3_step(statement)==SQLITE_ROW)
{
NSString *tname = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
NSString *latitude = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
NSString *longitude = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
// NSString *ds2 = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 4)];
NSString *PickerTower = [[NSString alloc] initWithFormat:#"%#", tname];
NSString *lat1 = [[NSString alloc] initWithFormat:#"%#", latitude];
NSString *long1 = [[NSString alloc] initWithFormat:#"%#", longitude];
NSArray *array = [[NSArray alloc] initWithObjects:PickerTower, nil];
[array1 addObject:array];
NSLog(#"Lat/Long %# / %#", lat1, long1);
}
}
}
}
#pragma mark Picker Data Source Methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
//ONE Colume
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
//data view how many items?
return [array1 count];
// return [_array2 count];
}
#pragma mark Picker Delegate Methods
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [array1 objectAtIndex:row];
//return [self->array1 objectAtIndex:row];
// array1 = [[NSMutableArray alloc] init];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
long select = row;
NSLog(#"PickerView %ld", select);
}
#end
You have to changed this code in the method name displayTower and code lines -
[array1 addObject:array];
NSLog(#"Lat/Long %# / %#", lat1, long1);
with -
[array1 addObject:array];
NSLog(#"Lat/Long %# / %#", lat1, long1);
[[self pickerview1] reloadAllComponents];
may be it will help you, or feel free.

How to save AVAudioFile to document directory?

I want to save AVAudioFile to document directory with NSDictionary. Can anyone help me?
AVAudioFile *audiofile=[[AVAudioFile alloc] initForWriting:destinationURL settings:settings error:&error];
save this audio file to document directory...
Path to the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
Saving the audio file to the documents directory:
BOOL status = [NSDictionary writeToFile:filePath atomically:YES];
if(status){
NSLog(#"File write successfully");
}
- (NSString *) dateString
{
// return a formatted string for a file name
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"ddMMMYY_hhmmssa";
return [[formatter stringFromDate:[NSDate date]]stringByAppendingString:#".aif"];
}
It saves below as in Documents
23Aug16_044104PM.aif
Why we save above like is we can differenciate the previous one next one by time.So we can't confuse now.
ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController<AVAudioSessionDelegate,AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
NSURL *temporaryRecFile;
AVAudioRecorder *recorder;
AVAudioPlayer *player;
}
- (IBAction)actionRecordAudion:(id)sender;
- (IBAction)actionPlayAudio:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
[recorder setDelegate:self];
}
- (IBAction)actionRecordAudion:(id)sender
{
NSError *error;
// Recording settings
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setValue: [NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[settings setValue: [NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
[settings setValue: [NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];
[settings setValue: [NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
[settings setValue: [NSNumber numberWithInt: AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
NSArray *searchPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
NSLog(#"the path is %#",pathToSave);
// File URL
NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];
//Save recording path to preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setURL:url forKey:#"Test1"];
[prefs synchronize];
// Create recorder
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
[recorder prepareToRecord];
[recorder record];
}
- (IBAction)actionPlayAudio:(id)sender
{
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
//Load recording path from preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
temporaryRecFile = [prefs URLForKey:#"Test1"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
player.delegate = self;
[player setNumberOfLoops:0];
player.volume = 1;
[player prepareToPlay];
[player play];
}
Record and Save Audio Permanently
Record Audio File and save Locally
Just now I tried the below code with iPhone 4s and it works perfectly.
AudioViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface AudioViewController : UIViewController<AVAudioSessionDelegate,AVAudioRecorderDelegate,AVAudioPlayerDelegate>
- (IBAction)actionRecordAudio:(id)sender;
- (IBAction)actionPlayAudio:(id)sender;
- (IBAction)actionStopAudio:(id)sender;
#property (strong, nonatomic) AVAudioRecorder *audioRecorder;
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
#end
AudioViewController.m
#import "AudioViewController.h"
#interface AudioViewController ()
#end
#implementation AudioViewController
#synthesize audioPlayer,audioRecorder;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:#"sound.caf"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSError *error = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
audioRecorder = [[AVAudioRecorder alloc]initWithURL:soundFileURL settings:recordSettings error:&error];
if (error)
{
NSLog(#"error: %#", [error localizedDescription]);
}
else {
[audioRecorder prepareToRecord];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionRecordAudio:(id)sender
{
if (!audioRecorder.recording)
{
[audioRecorder record];
}
}
- (IBAction)actionPlayAudio:(id)sender
{
if (audioRecorder.recording)
{
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];
audioPlayer.delegate = self;
if (error)
NSLog(#"Error: %#",
[error localizedDescription]);
else
[audioPlayer play];
}
}
- (IBAction)actionStopAudio:(id)sender
{
if (audioRecorder.recording)
{
[audioRecorder stop];
}
else if (audioPlayer.playing) {
[audioPlayer stop];
}
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
NSLog(#"Decode Error occurred");
}
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
}
-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error
{
NSLog(#"Encode Error occurred");
}
#end
Here is source

Load and save NSMutableArray won't work

first of all, I have a class which mamages an NSMutableArray.
When the class is instantiated, it should look if there is already a saved array and load it, or otherwise made a new one.
everytime an item is added it should be saved. but: nothing happens.
#import "NEList.h"
#interface NEList()
#end
#implementation NEList
#synthesize theInternArray;
-(id) initWithArray {
self = [super init];
if(self != nil) {
NSLog(#"build");
theInternArray = [[NSMutableArray alloc] initWithCapacity:20];
return self;
}
return nil;
}
-(id) initWithContent {
self = [super init];
if(self != nil) {
NSLog(#"load");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theFiles"];
theInternArray = [NSMutableArray arrayWithContentsOfFile:filePath];
if(theInternArray == nil) {
theInternArray = [[NSMutableArray alloc] initWithCapacity:200];
}
NSLog(#"second %#", theInternArray);
return self;
}
return nil;
}
-(BOOL) save {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theFiles"];
return [self.theInternArray writeToFile:filePath atomically:NO];
}
-(BOOL) addObject:(NEListItem *)theItem {
[theInternArray addObject:theItem]; [self save];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = theItem.theBestBeforeDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [theItem.theName stringByAppendingString:#" expires!"];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
return true;
}
-(NEListItem *) getElementAtIndex:(NSUInteger)theIndex {
return [theInternArray objectAtIndex:theIndex];
}
-(BOOL)removeObjectByName:(NSString *)theName {
for (NEListItem *tempItem in theInternArray) {
if([tempItem.theName isEqualToString:theName]) {
[theInternArray removeObject:tempItem];
break;
return true;
}
}
NSLog(#"Nicht gefunden");
return false;
}
#end
the save method is called in another class which owns an instance of NEList
Ok, all I changed was the "initWithContent" Method and the save method. I've commented out your code and under it made the changes to use NSUserDefaults. NSUserDefaults should save a binary file of your Array and later get it back and convert it back to a NSArray. If this doesn't work just let me know what error your getting.
-(id) initWithContent {
self = [super init];
if(self != nil) {
NSLog(#"load");
/*
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theFiles"];
theInternArray = [NSMutableArray arrayWithContentsOfFile:filePath];
if(theInternArray == nil) {
theInternArray = [[NSMutableArray alloc] initWithCapacity:200];
}
NSLog(#"second %#", theInternArray);*/
NSUserDefaults *uDefaults = [NSUserDefaults standardUserDefaults];
theInternArray = [uDefaults objectForKey:#"internArray"];
if (!theInternArray)
{
theInternArray = [[NSMutableArray alloc] initWithCapacity:200];
}
NSLog(#"%#", theInternArray);
return self;
}
return nil;
}
-(BOOL) save {
/*NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theFiles"];*/
NSUserDefaults *uDefaults = [NSUserDefaults standardUserDefaults];
[uDefaults setObject:theInternArray forKey:#"internArray"];
//return [self.theInternArray writeToFile:filePath atomically:NO];
return [uDefaults objectForKey:#"internArray"];
}
Oh, and the reason why your way didn't work is because it's not that simple to save a file then get it back. You would need to print out your data from the array (like "item1,item2,item3, etc." to the file, then parse it and create a NSArray with that data later.
So, this is the solution worked for me.
First of all, this is my custom class which is stored in the arrays:
#import <Foundation/Foundation.h>
#interface NEListItem : NSObject <NSCoding>
#property (nonatomic, strong) NSString *theName;
#property (nonatomic, strong) NSString *theBestBeforeDate;
#property (nonatomic, strong) NSDate *theInternDate;
-(id) initWithName:(NSString *) theInitName;
#end
and the implementation
#import "NEListItem.h"
#implementation NEListItem
#synthesize theName = _theName;
#synthesize theBestBeforeDate = _theBestBeforeDate;
#synthesize theInternDate = _theInternDate;
-(id)initWithName:(NSString *)theInitName {
self = [super init];
if(self != nil) {
self.theName = theInitName;
return self;
}
return nil;
}
- (void)encodeWithCoder:(NSCoder *)coder;
{
[coder encodeObject:self.theName forKey:#"theName"];
[coder encodeObject:self.theBestBeforeDate forKey:#"theBBDate"];
[coder encodeObject:self.theInternDate forKey:#"theInternDate"];
}
- (id)initWithCoder:(NSCoder *)coder;
{
self = [[NEListItem alloc] init];
if (self != nil)
{
self.theName = [coder decodeObjectForKey:#"theName"];
self.theInternDate = [coder decodeObjectForKey:#"theInternDate"];
self.theBestBeforeDate = [coder decodeObjectForKey:#"theBBDate"];
}
return self;
}
#end
so, this is needed for saving custom values.
the save method:
-(BOOL) save {
NSLog(#"save called");
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theInternArray] forKey:#"savedArray"];
return true;
}
and the loading which is part of a init method
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:#"savedArray"];
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil) {
theInternArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
return self;
}
else
theInternArray = [[NSMutableArray alloc] initWithCapacity:200];
return self;
}
many thanks to ManOx which helped me a lot

annotations - NSArray - How to do this?

I would like to annotations in a Mapview, using data fetched Json via a URL.
As might do?
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://example.com/LData.php"]];
//Data: Longitud/Latitud/Country;.....
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(str);
[foo removeAllObjects];
NSArray *foo2 =[str componentsSeparatedByString: #";"];
int i=0;
for(i=0;i<[foo2 count]; i++){
[foo insertObject:[foo2 objectAtIndex:i] atIndex:i];
NSArray *foo3 =[foo2 componentsSeparatedByString: #"/"];
So far so good
¿As I Lay to introduce the variables [i]?
CLLocationCoordinate2D theCoordinate[i];
theCoordinate1.latitude[i] = [foo3 objectAtIndex:1]);//Longitud
theCoordinate1.longitude[i] = [foo3 objectAtIndex:2]);//Latitud
MyAnnotation* myAnnotation[i]=[[MyAnnotation alloc] init];
myAnnotation[i].coordinate=theCoordinate[i];
myAnnotation[i].title=#""+[foo3 objectAtIndex:3];
myAnnotation[i].subtitle=#"in the city";
[mapView addAnnotation:myAnnotation[i]];
[annotations addObject:myAnnotation[i]];
}
how I can solve this problem?
Why you are using different CLLocationCoordinate2D variables?
theCoordinate1.latitude[i] = [foo3 objectAtIndex:1]);//Longitud
theCoordinate1.longitude[i] = [foo3 objectAtIndex:2]);//Latitud
and then
myAnnotation[i].coordinate=theCoordinate[i];
I think you need to adjust you code and some problems can resolved by themselves.
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://example.com/LData.php"]];
//Data: Longitud/Latitud/Country;.....
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(str);
[foo removeAllObjects];
NSArray *foo2 =[str componentsSeparatedByString: #";"];
int i=0;
for(i=0;i<[foo2 count]; i++){
[foo insertObject:[foo2 objectAtIndex:i] atIndex:i];
NSArray *foo3 =[foo2 componentsSeparatedByString: #"/"];
float realLatitude = [[foo3 objectAtIndex:1] floatValue];//Longitud
float realLongitude = [[foo3 objectAtIndex:0] floatValue];//Latitud
MyAnnotation* myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate = theCoordinate;
myAnnotation.title = [foo3 objectAtIndex:3];
//myAnnotation.subtitle = [note objectForKey:#"stationAddressKey"];
[_mapView setDelegate:self];
[_mapView addAnnotation:myAnnotation];
[myAnnotation release];
}
-(MKAnnotationView *)_mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MyAnnotation class]])
{
static NSString *reuseId = #"customAnn";
MKAnnotationView *customAnnotationView = [aMapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (customAnnotationView == nil)
{
customAnnotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId] autorelease];
UIImage *pinImage = [UIImage imageNamed:#"pin-green.png"];
[customAnnotationView setImage:pinImage];
customAnnotationView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
customAnnotationView.rightCalloutAccessoryView = rightButton;
}
// NSString *iconFilename = #"";
// MyAnnotation *myAnn = (MyAnnotation *)annotation;
// if ([myAnn.stationIdKey isEqualToString:#"BP"])
iconFilename = #"bp-logo.png";
// else
// if ([myAnn.stationIdKey isEqualToString:#"Caltex"])
// iconFilename = #"caltex.png";
// else
// if ([myAnn.stationIdKey isEqualToString:#"Shell"])
// iconFilename = #"shell.png";
// UIImageView *leftIconView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:iconFilename]] autorelease];
customAnnotationView.leftCalloutAccessoryView = leftIconView;
customAnnotationView.annotation = annotation;
return customAnnotationView;
}
return nil;
}
-(void)_mapView:(MKMapView *)_mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{ if ([view.annotation isKindOfClass:[MyAnnotation class]])
{
MyAnnotation *myAnn = (MyAnnotation *)view.annotation;
NSLog(#"callout button tapped for station id %#", myAnn.stationIdKey);
}
else
{
NSLog(#"callout button tapped for annotation %#", view.annotation);
} }
Is correct this?

objective-c cant find memory leak

im mapping an xml on a custom nsobject.
when the user hits reload the function is called again.
i get several memory leaks on all strings:
UPDATE this is the current code.
- (void)mapDataOnModel
{
if(mixesArr != nil)
{
//[mixesArr release];
[mixesArr removeAllObjects];
[playListArr removeAllObjects];
}
else
{
mixesArr = [[NSMutableArray alloc]init];
playListArr = [[NSMutableArray alloc] init];
}
MixVO *tmpMix;
AudioVO *tmpAudio;
for (DDXMLElement *node in nodes)
{
tmpMix = [[MixVO alloc] init];
tmpMix.uuid = [[node attributeForName:#"uuid"] stringValue];
tmpMix.name = [[[node elementsForName:#"name"] objectAtIndex:0] stringValue];
tmpMix.artist = [[[node elementsForName:#"artist"] objectAtIndex:0] stringValue];
tmpMix.path = [[[node elementsForName:#"file"] objectAtIndex:0] stringValue];
tmpMix.headline = [[[node elementsForName:#"headline"] objectAtIndex:0] stringValue];
tmpMix.teaser = [[[node elementsForName:#"teaser"] objectAtIndex:0] stringValue];
tmpMix.copy = [[[node elementsForName:#"copy"] objectAtIndex:0] stringValue];
tmpMix.isHighlight = NO;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"HH:mm:ss"];
tmpMix.duration = [dateFormat dateFromString:[[[node elementsForName:#"duration"] objectAtIndex:0] stringValue]] ;
[dateFormat release];
// CHECK IF IT IS A HIGHLIGHT MIX
for (int i = 0; i < [[highlightsNode elementsForName:#"member"] count]; i++)
{
NSString *highlightID;
highlightID = [[[highlightsNode elementsForName:#"member"] objectAtIndex:i] stringValue] ;
if([tmpMix.uuid isEqualToString:highlightID])
{
tmpMix.isHighlight = YES;
}
}
if([[node elementsForName:#"image_standard"] count] > 0)
tmpMix.image_standard = [[[node elementsForName:#"image_standard"] objectAtIndex:0] stringValue] ;
if([[node elementsForName:#"image_artist"] count] > 0)
tmpMix.image_artist = [[[node elementsForName:#"image_artist"] objectAtIndex:0] stringValue] ;
if([[node elementsForName:#"image_teaser"] count] > 0)
tmpMix.image_teaser = [[[node elementsForName:#"image_teaser"] objectAtIndex:0] stringValue] ;
if([[node elementsForName:#"image_player"] count] > 0)
tmpMix.image_player = [[[node elementsForName:#"image_player"] objectAtIndex:0] stringValue] ;
/*
tmpAudio = [[AudioVO alloc] init];
tmpAudio.file = tmpMix.path;
NSString *tmpDuration;
tmpDuration = [[[node elementsForName:#"duration"] objectAtIndex:0] stringValue];
tmpAudio.duration = tmpDuration;
// PARSE TRACKS
NSArray *track = NULL;
track = [node elementsForName:#"tracks"];
DDXMLElement *trackElems = [track objectAtIndex:0];
NSArray *tracks = NULL;
tracks = [trackElems elementsForName:#"track"];
NSMutableArray *tracksArray;
tracksArray = [[NSMutableArray alloc]init];
TrackVO *tmpTrack;
for (DDXMLElement *node2 in tracks)
{
tmpTrack = [[TrackVO alloc] init];
tmpTrack.timecode = [[node2 attributeForName:#"timecode"] stringValue];
tmpTrack.name = [node2 stringValue];
[tracksArray addObject:tmpTrack];
[tmpTrack release];
}
tmpAudio.tracksArr = tracksArray;
[tracksArray release];
tmpMix.audioVO = tmpAudio;
[tmpAudio release];
*/
[mixesArr addObject:tmpMix];
[tmpMix release];
}
// SORT PROGRAMM
/*
NSSortDescriptor *lastDescriptor =
[[[NSSortDescriptor alloc]
initWithKey:#"artist"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray * descriptors =
[NSArray arrayWithObjects:lastDescriptor, nil];
NSArray * sortedArray = [mixesArr sortedArrayUsingDescriptors:descriptors];
//[mixesArr release];
mixesArr = [[NSMutableArray alloc]initWithArray:sortedArray];
// PARSE PLAYLIST
for (DDXMLElement *node in nodesPl)
{
SchedVO *tmpSched;
tmpSched = [[SchedVO alloc] init];
NSString *timeStr;
timeStr = [[node attributeForName:#"timestamp"] stringValue];
tmpSched.date = [NSDate dateWithTimeIntervalSince1970:timeStr.intValue];
tmpSched.uid = [node stringValue];
[playListArr addObject:tmpSched];
//[tmpSched release];
}
*/
[self updateDone];
}
MixVO:
#interface MixVO : NSObject
{
NSString *uuid;
NSString *name;
NSString *artist;
NSString *path;
NSString *headline;
NSString *teaser;
NSString *copy;
NSString *image_standard;
NSString *image_artist;
NSString *image_teaser;
NSString *image_player;
NSDate *duration;
AudioVO *audioVO;
BOOL isHighlight;
}
#property (nonatomic,retain) NSString *uuid;
#property (nonatomic,retain) NSString *name;
#property (nonatomic,retain) NSString *artist;
#property (nonatomic,retain) NSString *path;
#property (nonatomic,retain) NSString *headline;
#property (nonatomic,retain) NSString *teaser;
#property (nonatomic,retain) NSString *copy;
#property (nonatomic,retain) NSString *image_standard;
#property (nonatomic,retain) NSString *image_artist;
#property (nonatomic,retain) NSString *image_teaser;
#property (nonatomic,retain) NSString *image_player;
#property (nonatomic,retain) NSDate *duration;
#property (nonatomic,retain) AudioVO *audioVO;
#property BOOL isHighlight;
#end
maybe someone can help me with this.
thanks in advance
alex
if(mixesArr != nil)
{
[mixesArr removeAllObjects];
[playListArr removeAllObjects];
}
mixesArr = [[NSMutableArray alloc]init];
This suggest mixesArr could already be allocated, and you simply allocate a new instance, making the original mixesArr a dangling pointer.
Shouldn't you write something like:
if(mixesArr != nil)
{
[mixesArr removeAllObjects];
[playListArr removeAllObjects];
}
else {
mixesArr = [[NSMutableArray alloc]init];
}
Or something similar?
Where are you releasing mixesArr?
You'll also want to release all the strings you're retaining.