How to point annotation in MKMapView for the large data coming from json? It work fine for around 1000 records - ios5

I have more than 70,000 record. I want to point that all in mapView,I wrote the code as fallow
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSURL* url=[[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#?choice=ALL",REQUEST_URL]];
NSError* error;
NSData* datapart=[[NSData alloc]initWithContentsOfURL:url options:0 error:&error];
NSDictionary* jsonResponce=[NSJSONSerialization JSONObjectWithData:datapart options:0 error:nil];
NSString* success=[NSString stringWithFormat:#"%#",[jsonResponce objectForKey:#"success"]];
if([success isEqualToString:#"1"])
{
dispatch_async(dispatch_get_main_queue(), ^{
CLLocationCoordinate2D location;
for(NSDictionary* element in [jsonResponce objectForKey:#"locations"])
{
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
location.latitude = [[element objectForKey:#"lat"]doubleValue];
location.longitude =[[element objectForKey:#"lon"]doubleValue];
point.coordinate = location;
point.title = [element objectForKey:#"name"];
[mapView addAnnotation:point];
}
});
}
});
It crash due to over memory,How can optimise this code and what is the best solution for this Problem?
I received the error as fallow
malloc: *** mmap(size=204800) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug

Related

how to move in map of iphone simulator ? dynamic Latitude & Longitude getting but not locate in iphone simulator?

-(CLLocationCoordinate2D)getGeoCoding:(NSString *)address
{
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#",address];
NSURL *url = [NSURL URLWithString:req];
NSError *error;
//NSURLResponse *response;
CLLocationCoordinate2D findlocation;
NSData *data = [[NSData alloc]initWithContentsOfURL:url];
NSMutableDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:Nil error:&error];
if(error)
{
NSLog(#"%#",[error localizedDescription]);
findlocation.latitude=0.0;
findlocation.longitude =0.0;
}
else
{
NSArray *results = (NSArray *)responseDictionary[#"results"];
NSDictionary *firstitem = (NSDictionary *)[results objectAtIndex:0];
NSLog(#"%#",firstitem);
NSDictionary *geometry = (NSDictionary *)[firstitem valueForKey:#"geometry"];
NSLog(#"%#",geometry);
NSDictionary *location = (NSDictionary *)[geometry valueForKey:#"location"];
NSLog(#"%#",location);
NSNumber *lat = (NSNumber *)[location valueForKey:#"lat"];
NSLog(#"%#",lat);
NSNumber *lng = (NSNumber *)[location valueForKey:#"lng"];
NSLog(#"%#",lng);
findlocation.latitude = [lat doubleValue];
findlocation.longitude = [lng doubleValue];
}
return findlocation;
}
i getting location from above code.
-(void)getLocation:(id)sender
{
NSString *str = self.textView.text;
CLLocationCoordinate2D location;
location=[self getGeoCoding:str];
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate=self;
self.mapView.showsUserLocation =YES;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(location, 0.3*METERS_PER_MILES, 0.3*METERS_PER_MILES);
[self.locationManager startUpdatingLocation];
[self.mapView reloadInputViews];
[self.mapView setRegion:viewRegion animated:YES];
}
location code is getting after the above function.
function is called but that do not work in iPhone simulator..?
if the set any setting Please tell me what the problem in code because iPhone simulator map not move from current location..
Is it Possible? How?

MKMapkit route is misaligned or not in the centre of road

I am developing an application in which I need to draw a route between two points using lat/long.
I have used apple API to get polylines and drawing it after decoding it.
Problem:
Route is not in the middle of the road (Attached image_1) or route is misaligned
Below is the code:
NSString* saddr = [NSString stringWithFormat:#"%#,%#",self.lat1.text,self.long1.text];
NSString* daddr = [NSString stringWithFormat:#"%#,%#",self.lat2.text,self.long2.text];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.apple.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSError *error;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error];
NSData *responseData = [apiResponse dataUsingEncoding:NSUTF8StringEncoding];
NSError* error1;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error1];
NSLog(#"Error: %#\n%#",[error1 localizedDescription],[error1 localizedFailureReason]);
if([[json objectForKey:#"status"] isEqualToString:#"OK"])
{
NSArray *routes1 = [json objectForKey:#"routes"];
NSDictionary *route = [routes1 lastObject];
if (route)
{
NSString *overviewPolyline = [[route objectForKey: #"overview_polyline"] objectForKey:#"points"];
routes = [self decodePolyLine:overviewPolyline];
//NSLog(#"%#",[routes objectAtIndex:0]);
[self updateRouteView];
[self centerMap];
}
}
-(void) updateRouteView
{
NSInteger numberOfSteps = routes.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [routes objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
decodePolyLine is totally depend n the latitude and longitude you get. So if you get proper latitude and longitude then this case will not happen. Another reason for that tis from iOS6 and above apple is using it's own map so may be they have different latitude and longitude from the Google map.
It's the same problem you described in your other question and it has the same solution. You are using data from two different sources, and the data is different.

CoreData inserting very huge DB exc_bad_access

I have ~60000 values in my DB.
I must to keep them all. But while inserting values I get exc_bad_access.
Here is my code:
if (context == nil)
{
context = [(radioAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", context);
}
[self performSelectorOnMainThread:#selector(deleteAllFromDB) withObject:nil waitUntilDone:YES];
// here is JSON parsing
int i=0;
#synchronized(self)
{
NSLog(#"Start");
NSEntityDescription *entity = [[NSEntityDescription entityForName:#"Station" inManagedObjectContext:context] autorelease];
for (NSString*string in stations)
{
if (![string isEqualToString:#""])
{
Station*station = [[[Station alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] retain];
NSError *err = nil;
id parsedData = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers error:&err];
if (err) {
NSLog(#"error is %#", [err localizedDescription]);
}
[station setName:[parsedData objectForKey:#"nm"]];
[station setBit: [parsedData objectForKey:#"btr"]];
[station setEnabled: [NSNumber numberWithInt:1]];
//encoding id of the station
scanner = [NSScanner scannerWithString:[parsedData objectForKey:#"id"]];
[scanner scanHexInt:&tempInt];
NSNumber *numb = [[NSNumber alloc]initWithInt:i];
[station setNumber: [NSNumber numberWithInt:[numb intValue]]];
//encoding country ID
numb = [NSNumber numberWithInt:i];
[station setCountryID: [NSNumber numberWithInt:[numb intValue]]];
//encoding genre ID
numb = [NSNumber numberWithInt:i];
[station setGenerID:[NSNumber numberWithInt:[numb intValue]]];
[station setOrder:[NSNumber numberWithInt:i]];
[context insertObject:station];
float k = [stations count];
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
i++;
[scanner release];
[numb release];
[station release];
[parsedData release];
}
}
[context save:nil];
[entity release];
NSLog(#"Stop");
NSEntityDescription *entityGen = [NSEntityDescription entityForName:#"Genre" inManagedObjectContext:context];
NSURL* urlForGenre = [NSURL URLWithString:#"xxx.xxx"];
NSData *genres = [[NSData alloc] initWithContentsOfURL:urlForGenre];
NSError *err = nil;
NSArray *parsedGenres = [NSJSONSerialization JSONObjectWithData:genres options:NSJSONReadingMutableContainers error:&err];
if (err)
{
NSLog(#"error is %#", [err localizedDescription]);
}
for (int i =0; i<parsedGenres.count; i++)
{
Genre*gen = [[Genre alloc] initWithEntity:entityGen insertIntoManagedObjectContext:nil];
gen.name = [[parsedGenres objectAtIndex:i] objectForKey:#"nm"];
int tempInt;
NSScanner *scanner= [[NSScanner alloc] init];
scanner = [NSScanner scannerWithString:[[parsedGenres objectAtIndex:i] objectForKey:#"id"]];
[scanner scanInt:&tempInt];
NSNumber *numb = [[NSNumber alloc] init];
numb = [NSNumber numberWithInt:tempInt];
gen.number = [NSNumber numberWithInt:[numb integerValue]];
float k = [parsedGenres count];
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
[context insertObject:gen];
[gen release];
}
[entityGen release];
[context save:nil];
NSEntityDescription *entityCon = [NSEntityDescription entityForName:#"Country" inManagedObjectContext:context];
NSURL* urlForCoun = [NSURL URLWithString:#"yyy.yyy"];
NSData *countr = [[NSData alloc] initWithContentsOfURL:urlForCoun];
err = nil;
NSArray *parsedCountr = [NSJSONSerialization JSONObjectWithData:countr options:NSJSONReadingMutableContainers error:&err];
if (err)
{
NSLog(#"error is %#", [err localizedDescription]);
}
NSMutableArray* temp = [[NSMutableArray alloc] init];
for (int i =0; i<parsedCountr.count; i++)
{
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];
countr.name = [[parsedCountr objectAtIndex:i] objectForKey:#"nm"];
int tempInt;
NSScanner *scanner= [[NSScanner alloc] init];
scanner = [NSScanner scannerWithString:[[parsedCountr objectAtIndex:i] objectForKey:#"id"]];
[scanner scanInt:&tempInt];
NSNumber *numb = [[NSNumber alloc] init];
numb = [NSNumber numberWithInt:tempInt];
countr.number = [NSNumber numberWithInt:[numb integerValue]];
[temp addObject:countr];
float k = [parsedCountr count];
k = (i + 1)/k;
[self performSelectorOnMainThread:#selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
[context insertObject:countr];
[countr release];
}
[context save:nil];
If my app doesn't crash, yes, it happens not by every launch. It crashes on:
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];
Please help! And sorry for my terrible English.
Update:
On:
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];
Thread 7: EXC_BAD_ACCESS (code=1, address=0x3f800008)
Other error is exc_bad_access too. But with code=2 and on other thread.
Update 2:
I enabled zombies mode in scheme of my debug. Nothing happened.
Update 3:
I think I have problems with memory.
GuardMalloc: Failed to VM allocate 4128 bytes
GuardMalloc: Explicitly trapping into debugger!!!
You can't pass nil as managedObjectContext parameter to initWithEntity:insertIntoManagedObjectContext: method. Try changing this:
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];
to this
// pass managed object context parameter
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:context];
Based on the documentation and my experience you can pass nil as managedObjectContext.
I was also getting an EXC_BAD_ACCESS and it came that the reason was that I was not retaining the managed object model(I was only creating a model to get the entity description and then it was released).
In particular, this is what I was doing:
In a test class, in the setUp method:
- (void)setUp
{
[super setUp];
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSURL *modelURL = [bundle URLForResource:#"TestDatamodel" withExtension:#"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
STAssertNotNil(model, nil);
_entity = [[model entitiesByName] objectForKey:NSStringFromClass([MyEntity class])];
STAssertNotNil(_entity, nil);
// ...
}
Then in a test method I was creating a managed object without a context like this:
NSManagedObject *object = [[NSManagedObject alloc] initWithEntity:_entity insertIntoManagedObjectContext:nil];
And I was getting EXC_BAD_ACCESS here.
The solution was to add an ivar to the test class to keep a reference to the managed object model.

I want to get the Location name from the Coordinate value in MapKit for iPhone

I want to get the location name from the coordinate value. Here is code,
- (void)viewWillAppear:(BOOL)animated {
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 39.281516;
zoomLocation.longitude= -76.580806;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
MKCoordinateRegion adjustedRegion = [_mapView regionThatFits:viewRegion];
[_mapView setRegion:adjustedRegion animated:YES];
}
So, From that Latitude and longitude , i want to know that location name.
The Below code shall work in ios5 and above
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:32.00 longitude:21.322]; //insert your coordinates
[ceo reverseGeocodeLocation:loc
completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
if (placemark) {
NSLog(#"placemark %#",placemark);
//String to hold address
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"addressDictionary %#", placemark.addressDictionary);
NSLog(#"placemark %#",placemark.region);
NSLog(#"placemark %#",placemark.country); // Give Country Name
NSLog(#"placemark %#",placemark.locality); // Extract the city name
NSLog(#"location %#",placemark.name);
NSLog(#"location %#",placemark.ocean);
NSLog(#"location %#",placemark.postalCode);
NSLog(#"location %#",placemark.subLocality);
NSLog(#"location %#",placemark.location);
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
}
else {
NSLog(#"Could not locate");
}
}
];
-(NSString *)getAddressFromLatLon:(double)pdblLatitude withLongitude:(double)pdblLongitude
{
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%f,%f&output=csv",pdblLatitude, pdblLongitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
// NSLog(#"%#",locationString);
locationString = [locationString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
return [locationString substringFromIndex:6];
}
Use this method
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation: zoomLocation completionHandler:^(NSArray* placemarks, NSError* error){
}
];
In iOS 5.0 and later, you can use CLGeocoder of Core Location framework, as for iOS lower than 5.0, MKReverseGeocoder of Map Kit Framework. Good luck!
Here is block to get address string from current location
in .h file
typedef void(^addressCompletionBlock)(NSString *);
-(void)getAddressFromLocation:(CLLocation *)location complationBlock:(addressCompletionBlock)completionBlock;
in .m file
#pragma mark - Get Address
-(void)getAddressFromLocation:(CLLocation *)location complationBlock:(addressCompletionBlock)completionBlock
{
//Example URL
//NSString *urlString = #"http://maps.googleapis.com/maps/api/geocode/json?latlng=23.033915,72.524267&sensor=true_or_false";
NSString *urlString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true_or_false",location.coordinate.latitude, location.coordinate.longitude];
NSError* error;
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSASCIIStringEncoding error:&error];
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:[locationString dataUsingEncoding:NSUTF8StringEncoding]
options:0 error:NULL];
NSString *strFormatedAddress = [[[jsonObject valueForKey:#"results"] objectAtIndex:0] valueForKey:#"formatted_address"];
completionBlock(strFormatedAddress);
}
and to call function
CLLocation* currentLocation = [[CLLocation alloc] initWithLatitude:[SharedObj.current_Lat floatValue] longitude:[SharedObj.current_Long floatValue]];
[self getAddressFromLocation:currentLocation complationBlock:^(NSString * address) {
if(address) {
NSLog(#"Address:: %#",address);
}
}];

Core Data Import Failure

I'm trying to import a large data set (~6,000) in to my core data application. I've read the Apple document "Efficiently Importing Data" and I think I set it up correctly. The weird thing is the application isn't crashing in the simulator, although it does if I run it with the Leaks instrument, but it isn't saving all the data. Sometimes it will only save 3-4 hundred other times it will save 3-4 thousand and rarely the whole data set. I think it's probably memory leak related and I'm pretty new to using NSAutoReleasePool, any help would be much appreciated.
NSURL *url = [NSURL URLWithString:#""];
NSString *responseString = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:nil];
if (responseString) {
NSArray *players = [responseString componentsSeparatedByString:#";"];
NSUInteger LOOP_LIMIT = 100, count = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSManagedObjectContext *context = [[AppController sharedAppController] managedObjectContext];
[context setUndoManager:nil];
for (int i=0; i<([players count] - 1); i++) {
NSArray *info = [[players objectAtIndex:i] componentsSeparatedByString:#","];
NSString *dateInfo = [info objectAtIndex:10];
NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] autorelease];
NSDateFormatter *fo = [[[NSDateFormatter alloc] init] autorelease];
[fo setDateFormat:#"MM/dd/yyyy"];
[fo setLocale:usLocale];
[fo setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *dob = [fo dateFromString:dateInfo];
Players *player = [NSEntityDescription insertNewObjectForEntityForName:#"Players"
inManagedObjectContext:context];
NSNumberFormatter *f = [[[NSNumberFormatter alloc] init] autorelease];
[f setNumberStyle:NSNumberFormatterNoStyle];
player.playerID = [f numberFromString:[info objectAtIndex:0]];
player.lastName = [info objectAtIndex:1];
player.firstName = [info objectAtIndex:2];
player.position = [info objectAtIndex:4];
NSString *teamName = [info objectAtIndex:3];
NSFetchRequest *req = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *ent = [NSEntityDescription entityForName:#"Teams" inManagedObjectContext:context];
[req setEntity:ent];
[req setIncludesPropertyValues:NO];
NSPredicate *pre = [NSPredicate predicateWithFormat:#"team=%#", teamName];
[req setPredicate:pre];
NSArray *list = [context executeFetchRequest:req error:nil];
if ([list count]) {
Teams *team = [list objectAtIndex:0];
player.team_Players_Teams = team;
}
count++;
if (count == LOOP_LIMIT) {
[context save:nil];
[context reset];
[pool drain];
pool = [[NSAutoreleasePool alloc] init];
count = 0;
}
}
if (count != 0) {
NSLog(#"In Save Remaining");
[context save:nil];
[context reset];[pool drain];
}
I can't see anything dodgy in the code either. Definitely no errors appearing in the log?
Btw one other optimisation tip covered in the Core Data pdf for importing data is to move the predicate creation outside the loop and use substitution variables.
I can't see any obvious leaks but:
You could minimise the amount of memory used by alloc init retain-ing the NSLocale, NSDateFormatter, NSNumberFormatter and then release-ing them after the loop is complete. These don't seem to change between runs of the loop.
I don't know Core Data but where does the NSManagedObject/Player *player object get released? Is this autoreleased through Core Data?
As an aside, you can use [list lastObject] rather than [list count] and [list objectAtIndex:0] as the last two will crash if list is nil
Update based on response:
If nothing appears to make a difference then the next step is to simplify the code so as to remove any error sources.
Carry out my suggestions in #1 above to minimise the amount of code in the loop.
Check you're releasing the list object somewhere or that it is allocated as autorelease.
Remove the intermediate saving (all that code inside count == LOOP_LIMIT) and only save and drain the pool once all the arrays have been processed. You also should not need the code following on inside the if (count != 0)
Replace the error:nil statements with proper error:&&error and log errors. To log the errors do the following (apologies but the code formatting doesn't seem to work - no idea why):
NSError *error = nil; //Declared upfront
// Your streamlined code
// ....
error = nil; //Just before a fetchRequest or context:save
/* After looping through all your code now attempt to save */
if(![context save:&error]) {
NSLog(#"Failed to save to data store: %#", [error localizedDescription]);
NSArray *detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError *detailedError in detailedErrors) {
NSLog(#"DetailedError: %#", [detailedError userInfo]);
}
} else {
NSLog(#" %#", [error userInfo]);
}
}
Then check the log to see if you're getting any odd messages. You can also use similar code anywhere in Core Data that you need to check for errors (i.e. executeFetchRequest). It's worth a shot to find out what the error is here.