How to fetch elements from NSArray in Objective C - ios

I'm using a bus timetable API and want to display the nearby bus stop according to user current location. I've already got the the JSON response through url and parsed JSON to NSArray. The NSArray looks like this.
{
result = {
distance = "0.00003292029";
lat = "-37.92091";
"location_name" = "Monash Medical Centre/Clayton Rd ";
lon = "145.120682";
"route_type" = 2;
"stop_id" = 16518;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003728643";
lat = "-37.92227";
"location_name" = "Monash Surgical Private Hospital/291 Clayton Rd ";
lon = "145.1202";
"route_type" = 2;
"stop_id" = 24348;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003804303";
lat = "-37.9230766";
"location_name" = "Clayton Railway Station/Clayton Rd ";
lon = "145.120209";
"route_type" = 2;
"stop_id" = 22809;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003976311";
lat = "-37.9186172";
"location_name" = "Monash Specialist Centre/Clayton Rd ";
lon = "145.121033";
"route_type" = 2;
"stop_id" = 22807;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00004085229";
lat = "-37.9186478";
"location_name" = "Dixon St/Clayton Rd ";
lon = "145.120911";
"route_type" = 2;
"stop_id" = 13889;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
}
)
My question is how to get the latitude and longitude from this NSArray. I wrote these code but it returns nil.
NSMutableArray *coordinateLatit = [[NSMutableArray alloc]init];
for (int i = 0; i<nearbyStop.count; i++) {
NSString *latit = [[nearbyStop objectAtIndex:1] objectForKey:#"lat"];
if(latit == nil)
{
NSLog(#"there is no data");
}
else
{
[coordinateLatit addObject:latit];
}
}
And also i want to display the stops(use longitude&latitude from NSArray) on MKMapView, how should i manage to implement the MKLocalSearchRequest
Appreciate it if anyone can help me!

Your code overlooked the extra nested result level.
NSMutableArray *coordinateLatit=[[NSMutableArray alloc]init];
for(NSDictionary *d in nearbyStop)
{
NSString *latit=d[#"result"][#"lat"];
if(lat) [coordinateLatit addObject:latit];
}

-(id) doApiCall:(NSString*)apiCall useCache:(BOOL)useCache
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", mBaseURL, [MapViewController signApiCall:apiCall]]];
id response = [self httpWrapper:url];
NSLog( #"%#", response );
return response;
}
-(id) httpWrapper:(NSURL*)url
{
__block id response = nil;
void (^doStuff)() = ^void()
{
int retry = 3;
NSError * error;
while( retry > 0) {
NSData * data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:600] returningResponse:nil error:&error ];
if( data != nil )
{
response = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if( response != nil)
retry = 0;
}
if(data == nil || response == nil)
{
NSLog(#"Bad response %#", url);
NSLog(#"%#", error);
--retry;
}
}
};
doStuff();
return response;
}
-(NSArray*) nearby:(CLLocation*)location
{
return [self doApiCall:[NSString stringWithFormat:#"/v2/nearme/latitude/%f/longitude/%f?limit=5", location.coordinate.latitude, location.coordinate.longitude]];
}
Here is the code i'm using to call the API. I use id for the response from url request. so does nearby method returns NSArray type?

you miss a level of the json response, it should be
for (Stop *stop in nearbyStop) {
NSString *latit = [[stop objectForKey:#"result"] objectForKey:#"lat"];
if(latit == nil)
{
NSLog(#"there is no data");
}
else
{
[coordinateLatit addObject:latit];
}
}

Related

Check and replace all null values with empty string in NSDictionary/NSArray

I am storing my json response in a NSDictionary and this dictionary contains various array, so I want to replace all the null values with #"" empty string.
{
Specialities = (
{
ApprovalStatus = Unapproved;
CurrencyCode = "<null>";
Packages = (
{
AssetId = 157965;
BasePrice = 10000;
BookingAdvance = 100;
Currency = INR;
Details = "<null>";
DiscountedPrice = 9000;
Id = 16579;
IsBestOffer = 1;
IsPopular = 1;
LineItems = (
{
IconClass = "fa-check";
Text = "A DVD with all edited and unedited images";
}
);
PackageVersion = 123955;
PriceUnit = 3;
Quantity = 4;
SpecialityId = 22;
Status = Rejected;
Tags = (
53
);
TermsAndConditions = "<null>";
Title = Test;
}
);
Photos = (
157965,
157964
);
ServiceDescription = 43534;
Speciality = 22;
SpecialityName = "Wedding Photographer";
UserFRPs = (
{
AssetId = 157965;
CurrencyCode = INR;
DiscountedPrice = 800;
FRPId = 13;
Id = 4559;
Price = 1000;
SpecialityId = 22;
Status = Active;
},
{
AssetId = 565441;
CurrencyCode = INR;
DiscountedPrice = 9000;
FRPId = 18;
Id = 5559;
Price = 10000;
SpecialityId = 22;
Status = Active;
}
);
Videos = (
{
VideoId = DaWOguXZbNA;
VideoLink = "http://www.youtube.com/watch?v=DaWOguXZbNA";
VideoType = YouTube;
},
{
VideoId = DGVJtAHzzDQ;
VideoLink = "http://www.youtube.com/watch?v=DGVJtAHzzDQ";
VideoType = YouTube;
},
{
VideoId = "_zxKLZR-xuk";
VideoLink = "http://www.youtube.com/watch?v=_zxKLZR-xuk";
VideoType = YouTube;
},
{
VideoId = 5SkBZcvuuQs;
VideoLink = "http://www.youtube.com/watch?v=5SkBZcvuuQs";
VideoType = YouTube;
},
{
VideoId = "H_Xi-lVB4Zw";
VideoLink = "http://www.youtube.com/watch?v=H_Xi-lVB4Zw";
VideoType = YouTube;
},
{
VideoId = TWhSjpsGvPQ;
VideoLink = "http://www.youtube.com/watch?v=TWhSjpsGvPQ";
VideoType = YouTube;
},
{
VideoId = N2CJrhHEydA;
VideoLink = "http://www.youtube.com/watch?v=N2CJrhHEydA";
VideoType = YouTube;
},
{
VideoId = Lq6faQVYcwY;
VideoLink = "http://www.youtube.com/watch?v=Lq6faQVYcwY";
VideoType = YouTube;
},
{
VideoId = v8WjMiodcKo;
VideoLink = "http://www.youtube.com/watch?v=v8WjMiodcKo";
VideoType = YouTube;
}
);
},
{
ApprovalStatus = Unapproved;
CurrencyCode = "<null>";
Packages = "<null>";
Photos = (
157967
);
ServiceDescription = Ddhd;
Speciality = 37;
SpecialityName = "Hair and Makeup Stylist";
UserFRPs = (
{
AssetId = 157967;
CurrencyCode = INR;
DiscountedPrice = 900;
FRPId = 34;
Id = 4560;
Price = 1000;
SpecialityId = 37;
Status = Active;
}
);
Videos = (
{
VideoId = "onvkllwM-OI";
VideoLink = "http://www.youtube.com/watch?v=onvkllwM-OI";
VideoType = YouTube;
},
{
VideoId = "_-cRVdTW2s8";
VideoLink = "http://www.youtube.com/watch?v=_-cRVdTW2s8";
VideoType = YouTube;
},
{
VideoId = DGVJtAHzzDQ;
VideoLink = "http://www.youtube.com/watch?v=DGVJtAHzzDQ";
VideoType = YouTube;
}
);
},
{
ApprovalStatus = Unapproved;
CurrencyCode = "<null>";
Packages = "<null>";
Photos = (
157963,
157962,
157961
);
ServiceDescription = Test;
Speciality = 55;
SpecialityName = Transport;
UserFRPs = "<null>";
Videos = (
{
VideoId = "cRchvv_dB2c";
VideoLink = "http://www.youtube.com/watch?v=cRchvv_dB2c";
VideoType = YouTube;
},
{
VideoId = "onvkllwM-OI";
VideoLink = "http://www.youtube.com/watch?v=onvkllwM-OI";
VideoType = YouTube;
},
{
VideoId = DGVJtAHzzDQ;
VideoLink = "http://www.youtube.com/watch?v=DGVJtAHzzDQ";
VideoType = YouTube;
}
);
},
{
ApprovalStatus = Unapproved;
CurrencyCode = "<null>";
Packages = "<null>";
Photos = "<null>";
ServiceDescription = Baby;
Speciality = 5;
SpecialityName = "Children/Babies Photographer";
UserFRPs = "<null>";
Videos = (
{
VideoId = "cRchvv_dB2c";
VideoLink = "http://www.youtube.com/watch?v=cRchvv_dB2c";
VideoType = YouTube;
},
{
VideoId = DGVJtAHzzDQ;
VideoLink = "http://www.youtube.com/watch?v=DGVJtAHzzDQ";
VideoType = YouTube;
}
);
},
}
I want all null values to be replace by empty string.
Then just do that
NSString *json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:yourDictionary options:0 error:nil] encoding: NSUTF8StringEncoding];
NSString *jsonWithoutNulls = [json stringByReplacingOccurrencesOfString:#"<null>" withString:#""];
NSData *data = [jsonWithoutNulls dataUsingEncoding:NSUTF8StringEncoding]
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
I prefer to use Macros to determine null values.
#define IS_NULL(value) (value != nil && value != Nil && value != NULL && value != (id)[NSNull null])
and I invoke it like
if (IS_NULL(CurrencyCode))
{
//insert ""
}else
{
//do necessary updates
}
OR you can also use the following method ,
-(BOOL) isNull: (NSString*)value{
if ([value isEqualToString:#"<null>"]){
return false;
}
return true;
}
and you can invoke it like,
if (isNull(currencyType))
{
//insert #""
}else{
//do necessary updates
}
Try this this is mine code i am using i hope it would be helpful!!
func checkDictionary(let dict:NSMutableDictionary)
{
let keys = Array(dict.allKeys)
for i in keys
{
let checkvalue = dict.valueForKey(i as! String)
if checkvalue! .isKindOfClass(NSNull)
{
dict.setObject("", forKey: i as! NSString)
}
else if checkvalue!.isKindOfClass(NSDictionary)
{
let dic = checkvalue as! NSDictionary
let dicts = dic.mutableCopy()
self.checkDictionary(dicts as! NSMutableDictionary)
dict.setObject(dicts, forKey: i as! NSString)
}
else if checkvalue! .isKindOfClass(NSArray)
{
let keys2 = checkvalue as! NSArray
let keys1 = keys2.mutableCopy() as! NSMutableArray
dict.setObject(keys1, forKey: i as! NSString)
for j in keys1
{
if j .isKindOfClass(NSNull)
{
keys1.replaceObjectAtIndex(keys1.indexOfObject(j), withObject:"")
}
if j.isKindOfClass(NSDictionary)
{
let dic = j as! NSDictionary
let dicts = dic.mutableCopy()
keys1.replaceObjectAtIndex(keys1.indexOfObject(j), withObject: dicts)
self .checkDictionary(dicts as! NSMutableDictionary)
}
}
}
}
}
In objective-C Try this!!
-(void)CheckDictionary:(NSMutableDictionary *)dic
{
NSArray *Arr = [dic allKeys];
for (int i = 0; i<Arr.count; i++)
{
if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSNull class]])
{
[dic setObject:#"" forKey:[Arr objectAtIndex:i]];
}
else if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *dict = [[dic valueForKey:[Arr objectAtIndex:i]] mutableCopy];
[dic setObject:dict forKey:[Arr objectAtIndex:i]];
[self CheckDictionary:dict];
}
else if ([[dic valueForKey:[Arr objectAtIndex:i]] isKindOfClass:[NSMutableArray class]])
{
NSMutableArray *Arr12 = [dic valueForKey:[Arr objectAtIndex:i]];
for (int j = 0; j<Arr12.count; j++)
{
if ([[Arr12 objectAtIndex:j] isKindOfClass:[NSDictionary class]])
{
NSDictionary *dict123 = [Arr12 objectAtIndex:j];
NSMutableDictionary *dict = [dict123 mutableCopy];
[Arr12 replaceObjectAtIndex:j withObject:dict];
[self CheckDictionary:dict];
}
}
}
}
}
And Just pass the whole dictionary when you call this method I hope it would be helpful!!
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:responseObject options: NSJSONReadingMutableContainers error: nil];
if (dictionary)
{
NSMutableDictionary *dict = [dictionary mutableCopy];
[self CheckDictionary:dict];
dictionary = [NSDictionary dictionaryWithDictionary:dict];
}
This is how we do it
#interface NSMutableArray (JSON)
- (void)recursivelyRemoveNulls;
#end
#implementation NSMutableArray (JSON)
- (void)recursivelyRemoveNulls
{
[self enumerateObjectsUsingBlock:^(id value, NSUInteger __unused idx, BOOL __unused *nestedStop)
{
if ([value isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *modifiedValue = [NSMutableDictionary dictionaryWithDictionary:value];
[modifiedValue recursivelyRemoveNulls];
[self removeObject:value];
[self addObject:modifiedValue];
}
else if ([value isKindOfClass:[NSArray class]])
{
NSMutableArray *modifiedValue = [NSMutableArray arrayWithArray:value];
[modifiedValue recursivelyRemoveNulls];
[self removeObject:value];
[self addObject:modifiedValue];
}
}];
}
#end
#interface NSMutableDictionary (JSON)
- (void)recursivelyRemoveNulls;
#end
#implementation NSMutableDictionary (JSON)
- (void)recursivelyRemoveNulls
{
[self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL __unused *stop)
{
if (value == [NSNull null] || value == nil)
{
[self removeObjectForKey:key];
}
else if ([value isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *modifiedValue = [NSMutableDictionary dictionaryWithDictionary:value];
[modifiedValue recursivelyRemoveNulls];
self[key] = modifiedValue;
}
else if ([value isKindOfClass:[NSArray class]])
{
NSMutableArray *modifiedValue = [NSMutableArray arrayWithArray:value];
[modifiedValue recursivelyRemoveNulls];
self[key] = modifiedValue;
}
}];
}
#end
The short code you can use here:-
NSString * newValue=[self isNotNull:[your Object here]] ? [your Object here] : #"Value that you want to replace";
- (BOOL)isNull:(NSObject *)object {
if (!object) return YES;
else if (object == [NSNull null]) return YES;
else if ([object isKindOfClass:[NSString class]]) {
return ([((NSString *)object)isEqualToString : #""]
|| [((NSString *)object)isEqualToString : #"null"]
|| [((NSString *)object)isEqualToString : #"<null>"]
|| [((NSString *)object)isEqualToString : #"(null)"]
);
}
return NO;
}
- (BOOL)isNotNull:(NSObject *)object {
return ![self isNull:object];
}

currentCenter returning nil iOS while using Json

The JSON Data
Please HELP I beg
2015-10-30 12:15:58.866 GooglePlaces[17141:989254] Google Data: (
{
geometry = {
location = {
lat = "55.599881";
lng = "-2.64616";
};
};
icon = "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png";
id = 4e3047fc80549f89389827d05fb89a999705fcf2;
name = "Scott's view";
photos = (
{
height = 2368;
"html_attributions" = (
"Clarke Thomas"
);
"photo_reference" = "CmRdAAAADgCHDAr9O_RZg24-kHykYexBOTpKfhOAWTV-K1Go-sn6CGUoikhGc3beyjErYvXzCPLwFLRr32lC8tPpgfIA-CXue6l75ziHrlRXMOt72IZFBcbZfCBSSbttW5lHjSdfEhD5d08GC5Myl8L1_Zs0VmW2GhTzCD7bh_klEqsROxGDZLvskhzaBw";
width = 3200;
}
);
"place_id" = ChIJP5eCRF54h0gR9nc97bjfO8k;
rating = "4.7";
reference = "CmRgAAAAfN6yeOvYQEeRAzOcidZiE83kPoIdw_vDDH7orFr3gbZVXHeb3prAMlOCVWnVqeeK786c8x-V1QUtWfpSn-50Bk4Q5lO7fY04cNLsXigf1nx1JWiTee5d4TdKI1ij-jGDEhDXYtJPM_1H5t9KhqdSJiyuGhQAXqV2rosfllEOfE-suQ_ur89Bmg";
scope = GOOGLE;
types = (
parking,
"point_of_interest",
establishment
);
vicinity = B6356;
},
{
geometry = {
location = {
lat = "55.756977";
lng = "-4.17221";
};
};
icon = "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png";
id = 481f927c8ea30c24ae902a14dd85efd7e2bae1d1;
name = "Kwik Fit";
"opening_hours" = {
"open_now" = 1;
"weekday_text" = (
);
};
photos = (
{
height = 608;
"html_attributions" = (
"Kwik Fit"
);
"photo_reference" = "CmRdAAAAY152xIVsahSMoZgsMMN1IdIlMq6fbPeMCJ_1feXg1BIOhRTaW-s_wauDF8WSVPXnOG4dOR3nE9fLzqHmTmdoyKIAef_tZVFKOK43880DeItFOKNejmt_QaEamB4nX8uvEhCPQYbVi8day5vi1KSzGPFtGhT8KzkGs_FuA5ZM11lydRplhPM8uA";
width = 1080;
}
);
"place_id" = "ChIJ1zdwq2s_iEgR1fI1QvrsCas";
reference = "CmRcAAAAkkARPnw1ApSjDPECBxsmTmcDDr5LESbSAWF0aNPvI2rX8BDJGfUj3dytKOotK2IbsCUaFbbhYZ8mgoDXfvYqtGliy2v06F2CarEAPSfD_25BGRYqUBsNKYiO05c-seGUEhDsuTEEt6PPKoZhmkBkj2VFGhQ-5vq-S7o73KmF2zw-MIJsPpWYgg";
scope = GOOGLE;
types = (
store,
parking,
"car_repair",
"point_of_interest",
establishment
);
vicinity = "1 Telford Road, East Kilbride";
},
{
geometry = {
location = {
lat = "55.618894";
lng = "-2.810683";
};
};
icon = "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png";
id = 8ec3c7e9dc0da1d102d516107178cd440579ecff;
name = "Kwik-Fit";
"opening_hours" = {
"open_now" = 1;
"weekday_text" = (
);
};
photos = (
{
height = 608;
"html_attributions" = (
"Kwik-Fit"
);
"photo_reference" = "CmRdAAAAfbp51L51v3Mz4STPTBbUPvSy8b0GW_PYHQMcP6kXBDKIqhANAnVJINu3mdJk4mrEnG8-RSmR9SBa59z9qjRSxIVSEJapVWMSgGZzLHC3EVnib3-P3n1PnJyewKHVzR2tEhC5qWkLkJlXZl-6ETTap3GZGhSZCS6Wm9jEVAHx0nHwMTi6TNkVsw";
width = 1080;
}
);
"place_id" = ChIJqf1X7LyEh0gRK7GrZbR1qlI;
reference = "CmRbAAAAoIW6Uer6wFdg9f9c_kRg0s5Wc-6wyUwg49CWQtn9hphJTfCqmidaP_unuejhxZBS_hChwfTHYWsspU7nOOFZx08cmzQ9bAW7cTp1N7vxepNfqR1YNybBBtB4romQAZO7EhCfxI62ia7XGtVPIyEPRSIPGhR4HnxB4lrDp1o4daDSipUAvFoG4Q";
scope = GOOGLE;
types = (
store,
parking,
"car_repair",
"point_of_interest",
establishment
);
vicinity = "Bridge Street, Galashiels";
},
{
geometry = {
location = {
lat = "55.827528";
lng = "-4.041783";
};
};
icon = "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png";
id = 993dd6caf6e87b27c95b597170f82fc535db8464;
name = "Scania Truck Rental";
photos = (
{
height = 416;
"html_attributions" = (
"Ian McCully"
);
"photo_reference" = "CmRdAAAAgxB25gl4CRnm6PENE9QPRq0WqPqIFUQCrvz7eOWsirTLMLZM_3gd_plKy9teW9AQdDIIZ3Ikmz96ADPiPD-wtDRvjDFMZl274q1HuA4zg8gVNi6QggypXkSPDdOdrfxUEhCf_qaIvJK0_iWgvnmT-TjcGhSRvsf9XiE5hkqcgwQdbKTm7oI5FA";
width = 640;
}
);
"place_id" = "ChIJ0YTxdlVqiEgRlNZz-R6gs9M";
reference = "CnRnAAAAGNBVd-2Rzx_pF8lzxZ5WsI1qC8752BhlsKAXwS36PkmNVCZ4VQkH2FjmRDJ3swxoGLfJ0YmG4Cr1MACDFNaPSv0QdBo5zjIXQyRfytk77g2g0XVspPR7IhO9mQpuQHNCA-DDp5m1ph_ry1W3kt8IahIQiW-loOYmR9yACbxLie-eyhoUQF04W9ZNAeasiM5OqTqPlyDn6g8";
scope = GOOGLE;
types = (
parking,
"car_repair",
"point_of_interest",
establishment
);
vicinity = "Melford Road, Bellshill";
},
{
geometry = {
location = {
lat = "55.778158";
lng = "-4.053103";
};
};
icon = "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png";
id = 5b4e2e7beef36bc21e795144d512adb9cbc9ba54;
name = "National Tyres and Autocare";
"opening_hours" = {
"open_now" = 1;
"weekday_text" = (
);
};
photos = (
{
height = 631;
"html_attributions" = (
"National Tyres and Autocare"
);
"photo_reference" = "CmRdAAAALn7YnxOv_yKF3Sfkau09mJ1T7aY_L7La0E_2dxN9AGndS6evIYUPWCvYrQgSxD6Y69IsdGhkh08iY4gX0-YgXrbdtD0OBW6y8AjwVjYA34FLAAH9c122Kr_ImAGAmogREhDUOxeBxKmpZPcawyxxfnC9GhTJNNzPhS1xvgh_XPBXGOdhFhFgpQ";
width = 789;
}
);
"place_id" = ChIJrVjMcTMViEgRqc4gOlJfoDs;
reference = "CnRuAAAAoOOZVebI5pz8rifXu3_n9RbZv0sobjodbPcP1DhknZcwTuZ_zCjch7l3D0tPqSO21S4wQlhYuH6tOrgBzHwkYBcRMS2-XP5r234IevwkdYV04gAk4BPBfuJMQIyrvASsDtRN9LJkPp8By7OleSyyqhIQco-kf732PwomY9loLvEtbBoUc2ZZKVbvMIYk0pVeFQronor3UM8";
scope = GOOGLE;
types = (
store,
parking,
"car_repair",
"point_of_interest",
establishment
);
vicinity = "Peacock Cross, Almada Street, Hamilton";
}
2015-10-30 12:16:05.573 GooglePlaces[17141:989254] name Yosemite National Park
The header file
Where currentCenter is defined
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#define kGOOGLE_API_KEY #"the key here"
#interface AboutPlaceViewController : UIViewController <MKMapViewDelegate , CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
CLLocation *location;
// Where Current Centre is defined
CLLocationCoordinate2D currentCentre;
int currenDist;
BOOL firstLaunch;
}
#property (weak, nonatomic) IBOutlet UILabel *placeLabell;
#end
The Implementation file
#import "AboutPlaceViewController.h"
#import "ViewController.h"
#interface AboutPlaceViewController ()
#end
#implementation AboutPlaceViewController
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
location = [locationManager location];
//Do any additional setup after loading the view.
NSDictionary *jsonDic = [[NSDictionary alloc]init];
[self getApiResponse:&jsonDic];
NSLog(#"jsonDic %#",jsonDic);
NSDictionary *resultDic = [jsonDic[#"results"] objectAtIndex:0];
NSString *name = resultDic[#"name"];
NSLog(#" name %#", name);
self.placeLabell.text = name;
}
-(void)getApiResponse:(NSDictionary**)dataDictionary
{
// Where i dig into the Json array one example provided above
NSDictionary *responseDict = [[NSDictionary alloc]init];
responseDict = [responseDict valueForKey:#"geometry"];
NSArray *responseArray = [responseDict valueForKey:#"location"];
NSDictionary *dict;
// The for loop it doesnt go inside the for loop when debugging
for(int i = 0; i< [responseDict count]; i++){
dict = [responseArray objectAtIndex:i];
NSLog(#"- %#",[responseArray objectAtIndex:i]);
}
// Where I declare but it returns nil :(
currentCentre.latitude = [dict[#"lat"]doubleValue];
currentCentre.longitude = [dict[#"lng"]doubleValue];
NSString *api_key = kGOOGLE_API_KEY;
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=50&types=%#&sensor=true&key=%#",currentCentre.latitude , currentCentre.longitude,[NSString stringWithFormat:#"%i", currenDist],api_key];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:
request returningResponse:&response error:&error];
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
dataDictionary = [[NSDictionary alloc]initWithDictionary:jsonObject copyItems:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
The responseDict and the responseArray are also returning nil.
The currentCenter is returning nil and when I debug the code it doesn't go into the for loop. I have looked into the json format to find.
NSDictionary *responseDict = [[NSDictionary alloc]init];
responseDict = [responseDict valueForKey:#"geometry"];
These two lines of code are utter nonsense. Throw away any thought of what you think what these do lines should do, but look at them and figure out what they are doing. How code responseDict possibly be anything other than nil after executing these two lines?
First on all:
You have the following line:
location = [locationManager location];
You call the location straight after you initialise the manager.
If you look at the location method description it says:
/*
* location
*
* Discussion:
* The last location received. Will be nil until a location has been received.
*/
#property(readonly, nonatomic, copy, nullable) CLLocation *location;
I.E you should wait till the first location has been received.
Your class needs to implement CLLocationManagerDelegate and override:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
Make sure that you requestAlwaysAuthorization before you access the user location
Moreover,
What are you trying to do in this line?
NSDictionary *responseDict = [responseDict valueForKey:#"geometry"];
You are basically defining the dictionary and use it straight away.
As I found(If I am right) you are trying to fetch values from son data form server.
You can use NSJsonSerilazation for getting data from NSData. Below is only a demo code for getting values
NSData *yourDataFromServer;
NSError*error;
id records= [NSJSONSerialization JSONObjectWithStream:yourDataFromServer options:NSJSONReadingMutableContainers error:&error];
if (error!=nil)
{
if ([records isKindOfClass:[NSArray class]]) //Since you are getting Array Of Dictionary
{
NSDictionary *dictAtZeroIndex = records[0];
NSDictionary *latLonDict= [dictAtZeroIndex valueForKey:#"geometry"]; //Again it will be a dictionary. For safety, Here you can again check wheter you are getting dictionary or array using "isKindOfClass"
}
}
else{
NSLog(#"error is :%#",error.localizedDescription);
}
"yourDataFromServer" is NSData object coming from server. Might be helpful. Let me know if you are having any query. Use valueForKey with "latLonDict" for getting lat-lon values.
Anamica first of all you need to get the latitude and longitude value correctly.If you don not get that,you can't get other details by passing latitude and longitude values.
Getting Latitude and longitude values from your response
NSString *lataddr=[[[responseDict objectForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lat"];
NSString *longaddr=[[[responseDict objectForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lng"];
Then pass these strings to your url.Now you can get the response without nil.
Also please remove below coding from your part
NSArray *responseArray = [responseDict valueForKey:#"location"];
NSDictionary *dict;
// The for loop it doesnt go inside the for loop when debugging
for(int i = 0; i< [responseDict count]; i++){
dict = [responseArray objectAtIndex:i];
NSLog(#"- %#",[responseArray objectAtIndex:i]);
}
// Where I declare but it returns nil :(
currentCentre.latitude = [dict[#"lat"]doubleValue];
currentCentre.longitude = [dict[#"lng"]doubleValue];
instead of these part, you need to add
NSString *lataddr=[[[responseDict objectForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lat"];
NSString *longaddr=[[[responseDict objectForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lng"];
currentCentre.latitude = [lataddr doubleValue];
currentCentre.longitude = [longaddr doubleValue];
Above code for getting only single latitude and longitude value.
Now if you want to get the multiple latitude and longitude values for showing in map
NSMutableArray *arrayLat = [[NSMutableArray alloc]init];
NSMutableArray *arrayLng = [[NSMutableArray alloc]init];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil]; //This is for actually you are getting response to dict.
NSArray *arrayResponse = [dict copy];
NSLog(#"The response is - %#",arrayResponse);
for(int i=0;i<[arrayResponse count];i++)
{
NSString *lataddr=[[[[[arrayResponse objectAtIndex:i]valueForKey:#"geometry"]valueForKey:#"location"]valueForKey:#"lat"];
NSString *longaddr=[[[[[arrayResponse objectAtIndex:i]valueForKey:#"geometry"]valueForKey:#"location"]valueForKey:#"lng"];
[arrayLat addObject:lataddr];
[arrayLng addObject:longaddr];
}
for(int j=0;j<[arrayLat count];j++)
{
currentCentre.latitude = [[arrayLat objectAtIndex:j] doubleValue];
currentCentre.longitude = [[arrayLng objectAtIndex:j] doubleValue];
NSString *api_key = kGOOGLE_API_KEY;
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=50&types=%#&sensor=true&key=%#",currentCentre.latitude , currentCentre.longitude,[NSString stringWithFormat:#"%i", currenDist],api_key];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:
request returningResponse:&response error:&error];
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
dataDictionary = [[NSDictionary alloc]initWithDictionary:jsonObject copyItems:YES];
}
All the best Anamica:-)

how to find closest locations between 5m to 10m range from array of locations in iOS?

this was my code and i want nearest locations from my current location in the range of 10meters and i want to add all the nearest locations with details of the person in response also add in array.thanks
and this is my response from server
{
born = 0;
completed = 0;
"emergency_id" = "-1";
eyes = "";
feet = 0;
"first_name" = Neil;
glasses = No;
hair = "";
inch = 0;
language = "<null>";
"last_name" = Ferris;
latitude = "30.1456987";
longitude = "76.69916";
marks = "";
"member_id" = 21634;
picture = "";
"profile_id" = 5826;
type = 1;
updated = "2015-09-16 06:32:08";
weight = 0;
}
like the above i am getting 5000 users from server ,after i filtering with 10 meters distance through my current location i need to display list in table view who are in below 10 meters range
- (void)getdata
{
NSString * apiURLStr =[NSString stringWithFormat:#"<MY API URL>"];
NSString *outputStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:apiURLStr] encoding:NSUTF8StringEncoding error:nil];
NSDictionary *response;
if (outputStr == nil)
{
return;
}
NSData* data = [outputStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *array=[[NSMutableArray alloc]init];
CLLocation *closestLocation = nil;
for (NSDictionary *dict in response)
{
NSString *latitude=[dict valueForKey:#"latitude"];
NSString *longitude=[dict valueForKey:#"longitude"];
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude.doubleValue
longitude:longitude.doubleValue];
[array addObject:location];
}
CLLocationDistance closestLocationDistance = DBL_MIN;
for (CLLocation *location in array)
{
if (!closestLocation) {
closestLocation = location;
closestLocationDistance = [currentUserLocation distanceFromLocation:location];
continue;
}
CLLocationDistance currentDistance = [currentUserLocation distanceFromLocation:location];
if (currentDistance < closestLocationDistance)
{
closestLocation = location;
closestLocationDistance = currentDistance;
}
}
NSLog(#"closestLocation %#",closestLocation.description);
NSLog(#"closestLocationDistance %f", closestLocationDistance);
}
thanks for answer bro,but i want list of closest locations in below 10 meters range.
NSMutableArray *locationsInRange = [NSMutableArray new];
for (CLLocation *location in array)
{
CLLocationDistance currentDistance = [currentUserLocation distanceFromLocation:location];
if (currentDistance < 10)
{
[locationsInRange addObject:location];
}
}
NSLog(#"locations in 10 metters %#",locationsInRange.description);

Parsing Json in Google Maps iOS

I have got the Json response. Here it is:
Directions {
routes = (
{
bounds = {
northeast = {
lat = "39.893397";
lng = "42.2477961";
};
southwest = {
lat = "21.4204199";
lng = "39.2398944";
};
};
copyrights = "Map data \U00a92014 Google, Mapa GISrael, ORION-ME";
legs = (
{
distance = {
text = "2,940 km";
value = 2940341;
};
duration = {
text = "1 day 15 hours";
value = 138793;
};
"end_address" = "Unnamed Road, Erzincan Province, Turkey";
"end_location" = {
lat = "39.893397";
lng = "39.906191";
};
"start_address" = "4289, Al Hajlah, Mecca 24231\U00a06970, Saudi Arabia";
"start_location" = {
lat = "21.4204199";
lng = "39.8258119";
};
steps = (
{
distance = {
text = "0.6 km";
value = 630;
};
duration = {
text = "1 min";
value = 55;
};
"end_location" = {
lat = "21.4235672";
lng = "39.8211613";
};
"html_instructions" = "Head <b>west</b> on <b>Alsouq Alsagheer Tunnel</b>";
polyline = {
points = "stvaCinarFEh#?h#?f#Cd#If#Gb#Yx#Yx#e#bAWb#Y`#CD[b#c#l#ILADIRIVGPKRGJKPILKPWRi#X_Ad#MFSJ]N[N_#P]ROJ";
};
"start_location" = {
lat = "21.4204199";
lng = "39.8258119";
};
"travel_mode" = DRIVING;
and it goes on....
Here is some code from my project:
Direction.h
-(void)retrieveDirectionsFromOrigin:(CLLocationCoordinate2D)origin toDestination:(CLLocationCoordinate2D)destination
{
NSString *directionsURL=[NSString stringWithFormat:#"http://maps.google.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false",origin.latitude,origin.longitude,destination.longitude,destination.longitude];
_directionsURL=[NSURL URLWithString:directionsURL];
[self retrieveDirections:nil withDelegate:self];
}
-(void)retrieveDirections:(SEL)selector withDelegate:(id)delegate{
dispatch_async(dispatch_get_main_queue(), ^{
NSData *data = [NSData dataWithContentsOfURL:_directionsURL];
[self fetchedData:data withDelegate:delegate];
});
}
-(void)fetchedData:(NSData *)data withDelegate:(id)delegate{
NSError* error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Directions %#",json);
if(!error){
self.steps = json[#"routes"][0][#"legs"][0][#"steps"];
}
//MapViewController.m
marker.position = CLLocationCoordinate2DMake(21.422492, 39.826169);
marker2.position = CLLocationCoordinate2DMake(21.413333, 39.893333);
marker.map = mapView;
marker2.map = mapView;
directions=[[Directions alloc]init];
[directions retrieveDirectionsFromOrigin:marker.position toDestination:marker2.position];
[mapViewView setNeedsDisplay];
[mapView setNeedsDisplay];
[self.view bringSubviewToFront:backButton];
}
I am a beginner. Please let me know what to do next to show directions via polyline. Thanks
Here's a tip on how to create the polyline which should get you started on your way
Gather the polystrings from the steps
NSArray *steps = [valDictionary valueForKey:#"steps"];
for (NSDictionary *stepdic in steps) {
NSString *polyStr = [[stepdic valueForKey:#"polyline"] valueForKey:#"points"];
if (polyStr != nil) [polyStrings addObject:polyStr];
}
Create a single path from the polystrings for a smooth line and create the final polyline
GMSMutablePath *path = [GMSMutablePath path];
for (NSString *polyStr in polyStrings) {
GMSPath *p = [GMSPath pathFromEncodedPath:polyStr];
for (NSUInteger i=0; i < p.count; i++) {
[path addCoordinate:[p coordinateAtIndex:i]];
}
}
GMSPolyline *polyLint = [GMSPolyline polylineWithPath:path];
good luck

How to check an object is a string or an array in ios

I am getting a response array from two different web services. But for the same methods. The problem is there 2 different web services give me bit different responses. These are those arrays
(NSMutableArray *) $2 = 0x003e9210 <__NSArrayM 0x3e9210>(
{
addedOn = "03/09/2013";
album = "Surendra Perera";
artistGroup = Female;
artists = "Surendra Perera";
bpm = 0;
categories = "Love Songs";
duration = "250.00";
energy = "";
era = Millenium;
extroTime = "0.00";
extroType = "";
genders = "";
id = 50;
imageUrl = "http://sample.com/CloudMusic/Images/sngfile.png";
introTime = "0.00";
language = Sinhala;
lyrics = "";
mediaUrl = "http://sample.com/CloudMusic/Music/0476/50.mp3";
moods = Lonely;
movie = "";
musicLabel = Evoke;
musician = "";
sDuration = "00:04:10";
soundCodes = "";
tempos = "";
textures = "";
thumbUrl = "http://sample.com/CloudMusic/Images/sngfile.png";
title = "Mee Mai Gaha";
writer = "";
year = "";
}
)
Other one is
addedOn = "19/09/2013";
albumName = Massina;
artists = (
{
artistGroup = 0;
description = "<null>";
id = 290;
imageUrl = "<null>";
name = Daddy;
noOfSongs = 0;
thumbUrl = "<null>";
}
);
duration = "260.00";
id = 2575;
imageUrl = "http://sample.com/CloudMusic/Images/sngfile.png";
mediaUrl = "http://sample.com/CloudMusic/Music/0905/2575.mp3";
sDuration = "00:04:20";
songMoods = (
{
id = 3;
name = Sad;
noOfSongs = 0;
}
);
thumbUrl = "http://sample.com/CloudMusic/Images/sngfile.png";
title = "Aai Kale";
year = "";
}
)
What I want to do is chek for this artists array. How can I check for this artists coming as an array or just a string. Please help me.
Thanks
This will illustarate your problem
Get data rx in _recievedData then check the class of the object.
id object = [NSJSONSerialization
JSONObjectWithData:_recievedData
options:kNilOptions
error:&error];
if (error)
{
NSLog(#"Error in rx data:%#",[error description]);
}
if([object isKindOfClass:[NSString class]] == YES)
{
NSLog(#"String rx from server");
}
else if ([object isKindOfClass:[NSDictionary class]] == YES)
{
NSLog(#"Dictionary rx from server");
}
else if ([object isKindOfClass:[NSArray class]] == YES)
{
NSLog(#"Array rx from server");
}
This should help you.
id object = [responseData objectForKey:#"artists"];
if ([object isMemberOfClass:[NSString class]]) {
// do the stuff for NSString
}
else if ([object isMemberOfClass:[NSArray class]]) {
// do the stuff for NSArray
}

Resources