What to send as beaconsData to getActionsForBeacons (Kontakt beacons) - ios

I am using Kontakt beacons and iOS SDK and my code is again and again crashing at the part to get Actions for my beacons
Kontakt SDK docs are here
- (void)locationManager:(KTKLocationManager *)locationManager
didRangeBeacons:(NSArray *)beacons {
NSMutableDictionary *beaconsData = [NSMutableDictionary new];
for (CLBeacon *beacon in beacons) {
KTKBeacon *beaconData = [self _getDataForBeacon:beacon];
if (beaconData) [beaconsData setObject:beaconData forKey:beacon];
}
self.actionManager = [KTKActionManager new];
self.actionManager.delegate = self;
[self.actionManager processBeacons:beacons withData:beaconsData];
}
The method to get beacon Data
-(NSDictionary *)_getDataForBeacon:beacon
{
NSLog(#"%#",beacon);
NSData * jsonData = [NSData dataWithContentsOfURL:[NSURL
URLWithString:#"****"]];
NSError * error=nil;
NSDictionary *dic = [NSJSONSerialization
JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSLog(#"%#",dic);
NSArray *array = [NSArray arrayWithObject:beacon];
NSDictionary *data = [self.client getActionsForBeacons:array changedSince:0 error:&error]; //##It crashes here##
NSLog(#"%#",data);
return data;
}
The contents of dic dictionary
{
"id" : "42152577-e3d2-4687-b499-8112402b2ca2",
"major" : 56809,
"txPower" : 3,
"browserActions" : [
],
"serial" : "",
"uniqueId" : "OFSP",
"interval" : 350,
"urlRequestActions" : [
],
"minor" : 57237,
"masterPassword" : null,
"password" : null,
"alias" : null,
"venue" : {
"id" : "f7fe1874-c9c2-4f88-980b-876681e2eb18",
"description" : "Flat room",
"rates" : [
],
"users" : [
],
"managers" : [
],
"priv" : true,
"beacons" : [
],
"lat" : null,
"beaconsCount" : 1,
"lng" : null,
"coverType" : null,
"name" : "Home"
},
"contentActions" : [
{
"actionType" : "CONTENT",
"beacon" : null,
"distance" : null,
"id" : "b0897c61-55c3-49c9-9f23-538f279ca1ce",
"owner" : {
"venues" : [
],
"password" : null,
"active" : false,
"id" : "307d0ef9-7207-47ec-980f-9382cff9b773",
"company" : {
"id" : "c95cc0fc-70fb-4a82-960c-c91845654fc8",
"name" : "Shubhank Gaur",
"key" : null
},
"email" : "shubhank008pp#gmail.com",
"salt" : null
},
"contentType" : "image\/jpeg",
"contentLength" : 354008,
"impairmentTypes" : [
],
"proximity" : "IMMEDIATE",
"contentCategory" : "IMAGE"
}
],
"proximity" : "f7826da6-4fa2-4e98-8024-bc5b71e0893e",
"name" : "Kontakt",
"actionsCount" : 1
}
And finally here is the error
2014-07-24 17:52:10.249 Code64Beacons[371:60b] -[CLBeacon identifier]:
unrecognized selector sent to instance 0x15593ef0
2014-07-24 17:52:10.250 Code64Beacons[371:60b] * Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason: '-[CLBeacon
identifier]: unrecognized selector sent to instance 0x15593ef0'
* First throw call stack:
(0x30d00f0b 0x3b497ce7 0x30d04837 0x30d03137 0x30c52098 0xaa41b 0xa60b9
0xa5bd7 0xa85bf 0x311c5e91 0x311c0aeb 0x311ba081 0x30ccc01d 0x30ccb397
0x30cca001 0x30c34769 0x30c3454b 0x35ba16d3 0x33593891 0xa52cd 0x3b995ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)`

You might have resolved this as its too late. But below is the full code which you need to get the beacon data, might be useful for others running into this.
-(KTKBeacon *)_getDataForBeacon:(CLBeacon *)beacon
{
NSString *strURL = [NSString stringWithFormat:#"https://api.kontakt.io/beacon?proximity=%#&major=%#&minor=%#",
[beacon.proximityUUID UUIDString],
beacon.major,beacon.minor];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strURL]];
[request setValue:#"YOUR_API_KEY" forHTTPHeaderField:#"Api-Key"];
[request setValue:#"application/vnd.com.kontakt+json; version=2" forHTTPHeaderField:#"Accept"];
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError * error=nil;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#",dic);
KTKBeacon *newBeacon = [[KTKBeacon alloc] initWithDictionary:dic];
return newBeacon;
}

Related

Filter NSArray of NSDictionary , where the dictionary is of type <key , NSDictionary>

I have a NSArray like this
[ {
"268" : { "name" : "abc", "age" : "28"} }, {
"267" : { "name" : "xyz","age" : "25"} } ]
Now I want to filter it on behalf of keys (means 268 , 267 ).
Eg : If user search for 7 then it need to show
[ { "267" : { "name" : "xyz","age" : "25"} } ]
let filterText : String = "7"
let array : [Dictionary<String,Any>] = [ ["268" : [ "name" : "abc", "age" : "28"]], [ "267" : [ "name" : "xyz","age" : "25"] ] ]
let result = array.filter { (dictinory) -> Bool in
if let firstKey = dictinory.keys.first {
return firstKey.contains(filterText)
}
return false
}
You can use NSPredicate with block in Objective-C to filter it:
NSString *searchText = #"8";
NSArray *data = #[#{ #"268" : #{ #"name" : #"abc", #"age" : #"28"} }, #{ #"267" : #{ #"name" : #"xyz",#"age" : #"25"}}];
NSPredicate *predicate = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind) {
NSDictionary *dict = (NSDictionary *)obj;
NSString *key = dict.allKeys.firstObject;
return [key containsString:searchText];
}];
NSArray *filteredData = [data filteredArrayUsingPredicate:predicate];

How should i parse this JSON?

What would be the best way to parse this JSON object into a data object in Objective C?
{
"Properties" : {
"Property1" : {
"min" : 70.0,
"max" : 70.0
},
"Property2" : {
"min" : 0.41,
"max" : 0.41
},
"Property3" : {
"min" : 0.41,
"max" : 0.41
},
"Property4" : {
"min" : 0.41,
"max" : 0.41
}
}
The name "properties" will remain constant, but the name of properties inside this can change and so can the number of properties. For example, this could be;
{
"Properties":
"RandomNameOfProperty" : {
"min" : 0.41,
"max" : 0.41
},
"RandomNameOfProperty2" : {
"min" : 0.41,
"max" : 0.41
}
}
}
Edit: Corrected JSON format.
NSMutableDictionary *json = [[NSMutableDictionary alloc] init];
json = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: &e];
where data is your json data
Here is how you can transform you JSON to Objective-C
NSString *jsonString = #"{"name": "My name" ....}"
NSData *data = [#" " dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary *json = [[NSMutableDictionary alloc] init];
NSError *er;
json = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: &er];
MyClassModel *my = [[MyClassModel alloc] init];
my.name = json[#"name"];
my.age = [json[#"age"] integerValue];
my.type = json[#"type"];
There are also many libraries that does dynamic parsing and transformation for you.
JSONModel is really good one. With it you code would look like this -
NSString* json = #"{"name": "My name" ....}" //(fetch here JSON from Internet)
NSError* err = nil;
MyClassModel* country = [[MyClassModel alloc] initWithString:json error:&err];

NSJSONSerialization parsing data issue

I am parsing below data:-
NSURL *URL = [NSURL URLWithString:#"http://maps.googleapis.com/maps/api/directions/json?origin=40.714353,-74.005973&destination=40.650000,-73.950000&sensor=false&units=metric&mode=transit&departure_time=1396594530&alternatives=true"];
NSData* data = [NSData dataWithContentsOfURL:URL];
NSDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
Only part of Result not full result showing:
2014-04-04 15:24:10.036 Animation[478:907] {
routes = (
{
bounds = {
northeast = {
lat = "40.715478";
lng = "-73.94947789999999";
};
southwest = {
lat = "40.6497484";
lng = "-74.01035299999999";
};
};
copyrights = "Map data \U00a92014 Google";
legs = (
{
"arrival_time" = {
text = "03:35"; <<----- missing "am"
"time_zone" = "America/New_York";
value = 1396596948;
};
"departure_time" = {
text = "03:02";<<----- missing "am"
"time_zone" = "America/New_York";
value = 1396594936;
};`
when use this on simulator Correct result is coming, again showing part of response :-
{
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 40.715478,
"lng" : -73.94947789999999
},
"southwest" : {
"lat" : 40.6497484,
"lng" : -74.01035299999999
}
},
"copyrights" : "Map data ©2014 Google",
"legs" : [
{
"arrival_time" : {
"text" : "3:35am", <<----- showing "am"
"time_zone" : "America/New_York",
"value" : 1396596948
},
"departure_time" : {
"text" : "3:02am",<<----- showing "am"
"time_zone" : "America/New_York",
"value" : 1396594936
}
And same code is working on simulator fine.
You can pass the language when calling the maps api. Setting the language to en_US leads to the desired result:
NSURL *URL = [NSURL URLWithString:#"http://maps.googleapis.com/maps/api/directions/json?origin=40.714353,-74.005973&destination=40.650000,-73.950000&sensor=false&units=metric&mode=transit&departure_time=1396594530&alternatives=true&language=en_US"];

How to parse JSON multi-array

I need to parse the JSON file provided by Google Maps API
Then i use the AFNetworkingRequestHow to get the JSON response.
I built this dictionary:
NSDictionary *jsonDict = (NSDictionary *) JSON;
NSArray *rows = [jsonDict objectForKey:#"rows"];
But now, how can i reach the first value field of duration tag?
JSON File to parse:
{
"destination_addresses" : [ "San Francisco, CA, USA", "Victoria, BC, Canada" ],
"origin_addresses" : [ "Vancouver, BC, Canada", "Seattle, WA, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "1,527 km",
"value" : 1527251
},
"duration" : {
"text" : "15 hours 0 mins",
"value" : 54010
},
"status" : "OK"
},
{
"distance" : {
"text" : "112 km",
"value" : 111906
},
"duration" : {
"text" : "3 hours 1 min",
"value" : 10885
},
"status" : "OK"
}
]
}
}
Try
NSDictionary *jsonDict = (NSDictionary *) JSON;;
NSArray *rows = jsonDict[#"rows"];
NSDictionary *row = rows[0];
NSArray *elements = row[#"elements"];
NSDictionary *element = elements[0];
NSDictionary *duration = element[#"duration"];
NSInteger value = [duration[#"value"] integerValue];
[json objectForKey:#"elements"]
is an NSArray. You can't initialize an NSDictionary directly with an array.
(in JSON, { and } denote key-value pairs, like NSDictionary, whereas [ and ] delimit ordered lists like NSArray, that's why the mapping is done as it is...)
Following thinks can you understanding for development time so it may help lot.
You can use the following code:
NSString *valueString = [[[[[rows objectAtindex:0]objectForKey:#"elements" ]objectAtindex:0]objectForKey:#"duration"] objectForKey:#"value"];
//if you want integer value
NSInteger value = [valueString integerValue];

iOS JSON parse trouble

How should I parse JSONs with format:
{
"1": {
"name": "Бекон",
"unit": "гр."
},
"2": {
"name": "Бульон куриный",
"unit": "ст."
}
}
and:
{
"recipeCode" : "00001",
"inCategory" : "12",
"recipe" : "Зимний тыквенный суп",
"difficulty" : 2,
"personCount" : 4,
"prepHour" : 1,
"prepMin" : 30,
"comments" : "При подаче добавить сметану, крутоны и присыпать сыром",
"ingredients" : {
"2" : 3,
"11" : 2,
"13" : 1,
"14" : 2,
"19" : 1
}
}
The second one I even didn't try... But with the first one I have some problems. I do this:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Ingredients" ofType:#"json"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
NSError *error = nil;
NSDictionary *ingredients = [NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:&error];
and than I have ingredient dictionary with two key/value pairs. Both of them contains key "1" and value "1 key/value pairs" and nothing about "name" or "unit" values.
Any help how to correctly parse such JSONs
You are parsing it correctly,and what you will have output will be there in the dictionary
The parsing gives output as objects as NSDictionary and array as NSArray
so in your case the key 1 and key 2 have value a NSDictionary itself
NSDictionary *dict1 = [ingredients objectForKey:#"1"];
NSDictionary *dict2 = [ingredients objectForKey:#"2"];
and value as
NSString *name=[dict1 objectForKey:#"name"];
NSString *unit=[dict1 objectForKey:#"unit"];

Resources