Parsing JSON into individual NSArray elements - ios

My problem is this. When Im parsing my JSON data it is getting returned to me as an NSSArray with one element. Inside this one element it looks like this:
2015-07-14 20:45:38.467 ICBuses[51840:14872349] Bus Location: {
agencyname = Cambus;
agencytag = uiowa;
color = 00ff66;
directions = (
{
direction = Loop;
directiontag = loop;
stops = (
{
directiontitle = Loop;
stoplat = "41.659541";
stoplng = "-91.53775";
stopnumber = 1050;
stoptitle = "Main Library";
},
{
directiontitle = Loop;
stoplat = "41.6414999";
stoplng = "-91.55676";
stopnumber = 3200;
stoptitle = "Studio Arts Building";
},
{
directiontitle = Loop;
stoplat = "41.66504";
stoplng = "-91.54094";
stopnumber = 2100;
stoptitle = "Art Building";
},
{
directiontitle = Loop;
stoplat = "41.6662587";
stoplng = "-91.5405201";
stopnumber = 2106;
stoptitle = "Theatre Building";
},
{
directiontitle = Loop;
stoplat = "41.6679058";
stoplng = "-91.5401033";
stopnumber = 2120;
stoptitle = "Hancher/North Riverside";
},
{
directiontitle = Loop;
stoplat = "41.6660209";
stoplng = "-91.5406198";
stopnumber = 2105;
stoptitle = "Riverside & River St";
},
{
directiontitle = Loop;
stoplat = "41.66499";
stoplng = "-91.54106";
stopnumber = 2101;
stoptitle = "Art Building West";
},
{
directiontitle = Loop;
stoplat = "41.6612";
stoplng = "-91.5403422";
stopnumber = 145;
stoptitle = EPB;
}
);
}
);
I want each block to be in there once element...How do I do this? Below is my coded that parses the data and stores it to an array.
code that stores it to an array:
self.routeInfo = [[API sharedAPI] routeInfoAgency:self.routeAgency
Route:self.route];
self.busLocation = [[API sharedAPI] busLocation:self.routeAgency
Route:self.route];
NSLog(#"Bus Location: %#", self.routeInfo);
Heres the code that gets it from the server and parses it:
- (NSArray *) routeInfoAgency:(NSString *)agency Route:(NSString *)route {
NSError *error;
NSString *requestString = [NSString stringWithFormat:#"http://api.ebongo.org/route?format=json&agency=%#&route=%#&api_key=", agency, route];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",requestString, kApiKey]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if (!data) {
NSLog(#"Download Error: %#", error.localizedDescription);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"Error %#", error.localizedDescription] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
return nil;
}
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSArray *JSONArray = [JSON valueForKeyPath:#"route.directions"];
return JSONArray;
}
I want what is after stops = to be in an array that where each element is a block of directions title, stipulate, stoping, stop number and stoptitle.
Thank you
When I try to use floatValue I get this error:
{
When I do that I'm getting this error {2015-07-15 10:31:05.821 ICBuses[56344:16107040] -[__NSArrayI floatValue]: unrecognized selector sent to instance 0x7f91fb5bdf90
2015-07-15 10:31:05.868 ICBuses[56344:16107040] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI floatValue]: unrecognized selector sent to instance 0x7f91fb5bdf90'
*** First throw call stack:
(
0 CoreFoundation 0x000000010bc53c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010b8ecbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010bc5b0ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010bbb113c ___forwarding___ + 988
4 CoreFoundation 0x000000010bbb0cd8 _CF_forwarding_prep_0 + 120
5 ICBuses 0x000000010958f26e -[MapViewController viewDidLoad] + 3950
6 UIKit 0x000000010c17d1d0 -[UIViewController loadViewIfRequired] + 738
7 UIKit 0x000000010c17d3ce -[UIViewController view] + 27
8 UIKit 0x000000010c1a2257 -[UINavigationController _startCustomTransition:] + 633
9 UIKit 0x000000010c1ae37f -[UINavigationController _startDeferredTransitionIfNeeded:] + 386
10 UIKit 0x000000010c1aeece -[UINavigationController __viewWillLayoutSubviews] + 43
11 UIKit 0x000000010c2f96d5 -[UILayoutContainerView layoutSubviews] + 202
12 UIKit 0x000000010c0cc9eb -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
13 QuartzCore 0x000000010b18eed2 -[CALayer layoutSublayers] + 146
14 QuartzCore 0x000000010b1836e6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
15 QuartzCore 0x000000010b183556 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
16 QuartzCore 0x000000010b0ef86e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
17 QuartzCore 0x000000010b0f0a22 _ZN2CA11Transaction6commitEv + 462
18 QuartzCore 0x000000010b0f10d3 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
19 CoreFoundation 0x000000010bb86ca7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
20 CoreFoundation 0x000000010bb86c00 __CFRunLoopDoObservers + 368
21 CoreFoundation 0x000000010bb7ca33 __CFRunLoopRun + 1123
22 CoreFoundation 0x000000010bb7c366 CFRunLoopRunSpecific + 470
23 GraphicsServices 0x000000010e727a3e GSEventRunModal + 161
24 UIKit 0x000000010c04c8c0 UIApplicationMain + 1282
25 ICBuses 0x000000010958e2cf main + 111
26 libdyld.dylib 0x000000010d481145 start + 1
27 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I think it is because the for loop is saving it as an array with one element.
Any suggestions?

It looks like it's not an array at all. It looks like it's actually a dictionary. When you log a collection like that you can see dictionaries because they are marked with { and arrays are marked with (. Based on the structure of your data, something like this should get the correct members:
NSDictionary *JSONDict = [JSON valueForKeyPath:#"route.directions"];
NSArray *directions = JSONDict[#"directions"];
NSDictionary *directionsDict = directions.firstObject; // seems to be an array with just 1 element.
NSArray *stops = directionsDict[#"stops"];
for(NSDictionary *stop in stops)
{
NSString *title = stop[#"directiontitle"];
NSString *stopLat = stop[#"stoplat"];
// etc
}

In your example, it appears that [JSON valueForKeyPath:#"route.directions"]; returns a NSSdictionary, not a NSArray.
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
NSDictionary * directions = [json valueForKeyPath:#"route.directions"];
NSArray * stops = [directions valueForKeyPath:#"stops"];
You can then iterate through the stops array.

Related

Download JSON async crash

I download my Firebase database in json with AFNetworking 3. Everything works fine but there is a crash in the function cellForRoAtIndexPath.
Thanks
Work :
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:#"https://jojol-concours-lists.firebaseio.com/.json" parameters:URLParameters progress:nil success:^(NSURLSessionTask *task, id responseObject) {
self.contestArray = responseObject;
[_collectionView reloadData];
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Work :
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.contestArray count];
}
Not work : (NSDictionary *array = [self.contestArray objectAtIndex:indexPath.row];)
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
DemoCollectionViewCell *retVal = [collectionView dequeueReusableCellWithReuseIdentifier:#"collectionViewCell"
forIndexPath:indexPath];
//////// Not work ///////
NSDictionary *array = [self.contestArray objectAtIndex:indexPath.row];
//////// Not work ///////
retVal.name.text = #"";
retVal.contentView.layer.cornerRadius = 10;
retVal.contentView.layer.masksToBounds = YES;
return retVal;
}
JSON :
{
"Concours-1" : {
"Description" : "Description du concours",
"Title" : "Titre"
},
"Concours-2" : {
"Description" : "Description du concours",
"Titre" : "iPhone 6"
}
}
Log Crash :
-[NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x61000086c8c0
2017-07-18 10:00:26.787 jojol67[7003:4420828] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x61000086c8c0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c084b0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010e5c9141 objc_exception_throw + 48
2 CoreFoundation 0x000000010c0f4134 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x000000010c00b840 ___forwarding_ + 1024
4 CoreFoundation 0x000000010c00b3b8 _CF_forwarding_prep_0 + 120
5 jojol67 0x000000010756db3f -[DEMOConcoursTableViewController collectionView:cellForItemAtIndexPath:] + 191
6 UIKit 0x000000010d162925 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 446
7 UIKit 0x000000010d162761 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 35
8 UIKit 0x000000010d1679bd -[UICollectionView _updateVisibleCellsNow:] + 4764
9 UIKit 0x000000010d16d38e -[UICollectionView layoutSubviews] + 313
10 UIKit 0x000000010c8f355b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
11 QuartzCore 0x000000010c6a4904 -[CALayer layoutSublayers] + 146
12 QuartzCore 0x000000010c698526 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 370
13 QuartzCore 0x000000010c6983a0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
14 QuartzCore 0x000000010c627e92 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
15 QuartzCore 0x000000010c654130 _ZN2CA11Transaction6commitEv + 468
16 QuartzCore 0x000000010c654b37 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 115
17 CoreFoundation 0x000000010c02a717 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23
18 CoreFoundation 0x000000010c02a687 __CFRunLoopDoObservers + 391
19 CoreFoundation 0x000000010c00f720 __CFRunLoopRun + 1200
20 CoreFoundation 0x000000010c00f016 CFRunLoopRunSpecific + 406
21 GraphicsServices 0x00000001103c2a24 GSEventRunModal + 62
22 UIKit 0x000000010c830134 UIApplicationMain + 159
23 jojol67 0x000000010752ef5f main + 111
24 libdyld.dylib 0x000000010f31d65d start + 1
25 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
/////// Firebase realtime database ////////
Your id responseObject is not an array because your JSON contains an object not an array. App crashes because you are calling objectAtIndex on a NSDictionary object.
If you want to access this JSON as an array, you may want to format it to something like this,
[{
"Concours": 1,
"Description": "Description du concours",
"Title": "Titre"
}, {
"Concours": 2,
"Description": "Description du concours",
"Titre": "iPhone 6"
}]
It will help you for such responce:
NSDictionary *jsonDict =responseObject;
NSArray *allKeys = [jsonDict allKeys];
NSMutableArray *allDataArray = [NSMutableArray new];
for (int x = 0; x<allKeys.count; x++) {
NSString *key = [allKeys objectAtIndex:x];
[allDataArray addObject:[jsonDict valueForKey:key]];
// then reload your collection on allDataArray
}
Current JSON:
{
"Concours-1" : {
"Description" : "Description du concours",
"Title" : "Titre"
},
"Concours-2" : {
"Description" : "Description du concours",
"Titre" : "iPhone 6"
}
}
How it should be:
[
{
"Description": "Description du concours",
"Title": "Titre"
},
{
"Description": "Description du concours",
"Titre": "iPhone 6"
}
]
"-[NSDictionaryI objectAtIndex:]: unrecognized selector sent to instance 0x61000086c8c0 "
It seems that the self.contestArray is NSDictionary class;
You can log the responseObject it maybe a Dictionary , not Array;

How to get all values of one specific key from an array?

I am developing application using Objective C.
I am getting following array in the response from server side ( i'm using Get method of AFNetworking).
Response from server: `[{"name":"option1","profile_id":0,"profile_name":"option1"},{"name":"option2","profile_id":0,"profile_name":"option2"},{"name":"option3","profile_id":0,"profile_name":"option3"},{"name":"option4","profile_id":0,"profile_name":"option4"},{"name":"option5","profile_id":0,"profile_name":"option5"},{"name":"option6","profile_id":0,"profile_name":"option6"},{"name":"option7","profile_id":0,"profile_name":"option7"},{"name":"option8","profile_id":0,"profile_name":"option8"},{"name":"option9","profile_id":0,"profile_name":"option9"},{"name":"option10","profile_id":0,"profile_name":"option10"}]`
I want to separate values for the key name.
In short, i want output like:[option1,option2,option3,option4,option5,option6,option7,option8,option9,option10]
For that i tried like following way:
store that response in array (_arr). and then try to separate values for key name like following way,
NSArray *optionArray = [_arr valueForKey:#"name"];
NSLog(#"%#",optionArray);
but, unfortunately this is not working. Application crashes and gives following logs.
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x7abd0600> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
*** First throw call stack:
(
0 CoreFoundation 0x00ae2a14 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x005a3e02 objc_exception_throw + 50
2 CoreFoundation 0x00ae2631 -[NSException raise] + 17
3 Foundation 0x00239098 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 282
4 Foundation 0x0017a798 _NSGetUsingKeyValueGetter + 105
5 Foundation 0x0017a727 -[NSObject(NSKeyValueCoding) valueForKey:] + 288
6 Foundation 0x001bac40 -[NSFunctionExpression expressionValueWithObject:context:] + 1079
7 Foundation 0x001ba739 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 290
8 Foundation 0x001ba60f -[NSPredicate evaluateWithObject:] + 48
9 Foundation 0x001ba593 _filterObjectsUsingPredicate + 437
10 Foundation 0x001ba360 -[NSArray(NSPredicateSupport) filteredArrayUsingPredicate:] + 314
11 Wellness_24x7 0x0008fbc4 __31-[ForthViewController Donating]_block_invoke + 564
12 Wellness_24x7 0x0006c097 __116-[AFHTTPSessionManager dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:downloadProgress:success:failure:]_block_invoke97 + 231
13 Wellness_24x7 0x00080bd5 __72-[AFURLSessionManagerTaskDelegate URLSession:task:didCompleteWithError:]_block_invoke_2132 + 213
14 libdispatch.dylib 0x0330e377 _dispatch_call_block_and_release + 15
15 libdispatch.dylib 0x033319cd _dispatch_client_callout + 14
16 libdispatch.dylib 0x03316f90 _dispatch_main_queue_callback_4CF + 910
17 CoreFoundation 0x00a33fde __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
18 CoreFoundation 0x009f1cd4 __CFRunLoopRun + 2356
19 CoreFoundation 0x009f10e6 CFRunLoopRunSpecific + 470
20 CoreFoundation 0x009f0efb CFRunLoopRunInMode + 123
21 GraphicsServices 0x050c8664 GSEventRunModal + 192
22 GraphicsServices 0x050c84a1 GSEventRun + 104
23 UIKit 0x012ecbfa UIApplicationMain + 160
24 Wellness_24x7 0x0006905a main + 138
25 libdyld.dylib 0x0335ba21 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Thank you in advance.
actually your JSON Response started with Array, so do like
NSArray *ResponseArray = [NSJSONSerialization JSONObjectWithData: data options: KNilOptions error: nil];
NSMutableArray *finalArray = [NSMutableArray array];
for (NSDictionary *temp in ResponseArray) {
[finalArray addObject:temp[#"name"]];
}
Choice-2 for AFNetworking
NSMutableArray *finalArray = [NSMutableArray array];
for (NSDictionary *temp in responseObject) {
[finalArray addObject:temp[#"name"]];
}
Try this
NSMutableArray *arrOptions = [NSMutableArray new];
for (int i=0; i<_arr.count; i++) {
[arrOptions addObject:[[_arr objectAtIndex:i] objectForKey:#"name"]];
}
here arrOptions will contain your desired output.
I can see that you are getting response in JSON format. So you can convert JSON into mutable containers like Dictionary and Arrays. In your case it is array of dictionaries.
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &e];
if(!jsonArray)
{
for(NSDictionary *dict in jsonArray)
{
NSLog(#"%#", dict valueForKey: #"name");
}
}
According to your JSON data below you need to store data using NSDictionary instead of an Array.
[{
"name": "option1",
"profile_id": 0,
"profile_name": "option1"
}, {
"name": "option2",
"profile_id": 0,
"profile_name": "option2"
}, {
"name": "option3",
"profile_id": 0,
"profile_name": "option3"
}, {
"name": "option4",
"profile_id": 0,
"profile_name": "option4"
}, {
"name": "option5",
"profile_id": 0,
"profile_name": "option5"
}, {
"name": "option6",
"profile_id": 0,
"profile_name": "option6"
}, {
"name": "option7",
"profile_id": 0,
"profile_name": "option7"
}, {
"name": "option8",
"profile_id": 0,
"profile_name": "option8"
}, {
"name": "option9",
"profile_id": 0,
"profile_name": "option9"
}, {
"name": "option10",
"profile_id": 0,
"profile_name": "option10"
}]
Get the data using dict like:
NSDictionary *jsonDataDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *optionArray = [jsonDataDict valueForKey:#"name"];
Problem: you are trying to get data of name key and you storing whole JSON data inside an array.
Array doesn't contain key value pair use NSDictionary.
What you want to achieve and your thinking i can say you are on right track.
You have converted your response Data in NSDictionary but it must be an array.
NSArray *responseArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
this will convert your response to array and you can use
NSArray *optionArray = [responseArray valueForKey:#"name"];
This will lead to same result as answer from #Krishna Kumar but with this you will be able to avoid "for" loop.

NSCFDictionary - Unrecognized selector sent to instance

I have two modes - Mode 1 and Mode 2 which can be switched by a central button. Switch between modes allows user to see two different types of clustered annotations.
I can switch from Mode 1 to Mode 2 easily, but when I switch back to Mode 1 I'm getting this nasty error
-[__NSCFDictionary componentsSeparatedByString:]: unrecognized selector sent to instance 0x7fb1308cca50
I'm opening my code and in the TBClusteredAnnotations.m (script I'm using for clusterization). I have the following snippet of code relating to componentsSeparatedByString:
TBQuadTreeNodeData TBDataFromLine(NSString *line)
{
NSString *separator=#">>>>>>>>";
NSArray *components = [line componentsSeparatedByString: separator];
double latitude = [components[0] doubleValue];
double longitude = [components[1] doubleValue];
TBUserInfo* userInfo = malloc(sizeof(TBUserInfo));
NSString *userName = [components[2] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
userInfo->userId = malloc(sizeof(char) * userName.length + 1);
strncpy(userInfo->userId, [userName UTF8String], userName.length + 1);
NSString *userId = [components [3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
userInfo->userImage = malloc(sizeof(char) * userId.length + 1);
strncpy(userInfo->userImage, [userId UTF8String], userId.length + 1);
return TBQuadTreeNodeDataMake(latitude, longitude, userInfo);
}
but I'm loading my annotations with the following code in the MainViewController:
-(void)annotationsmode1:(NSMutableArray*)marr
{
if(marr.count>0)
{
NSMutableArray *newMarr1=[NSMutableArray new];
NSString *separatestuff=#">>>>>>>>";
for(NSMutableDictionary *dic in marr)
{
NSString *newStr=[NSString stringWithFormat:#"%#%#",[dic[#"latitude"] isEqualToString:#""]?#" ":dic[#"latitude"],separatestuff];
newStr=[NSString stringWithFormat:#"%#%#%#",newStr,[dic[#"longitude"] isEqualToString:#""]?#" ":dic[#"longitude"],separatestuff];
newStr=[NSString stringWithFormat:#"%#%#%#",newStr,[dic[#"id"] isEqualToString:#""]?#" ":dic[#"id"],separatestuff];
newStr=[NSString stringWithFormat:#"%#%#",newStr,[dic[#"image"] isEqualToString:#""]?#" ":dic[#"image"]];
[newMarr1 addObject:newStr];
}
//NSLog(#"NEW Array: %#",newMarr);
[self.coordinateQuadTree buildTree:newMarr1];
}
}
-(void)annotationsmode2:(NSMutableArray*)marr
{
if(marr.count>0)
{
NSMutableArray *newMarr=[NSMutableArray new];
NSString *separatestuff2=#">>>>>>>>";
for(NSMutableDictionary *dic in marr)
{
NSString *newStr=[NSString stringWithFormat:#"%#%#",[dic[#"lat"] isEqualToString:#""]?#" ":dic[#"lat"],separatestuff2];
newStr=[NSString stringWithFormat:#"%#%#%#",newStr,[dic[#"lang"] isEqualToString:#""]?#" ":dic[#"lang"],separatestuff2];
newStr=[NSString stringWithFormat:#"%#%#%#",newStr,[dic[#"id"] isEqualToString:#""]?#" ":dic[#"id"],separatestuff2];
newStr=[NSString stringWithFormat:#"%#%#",newStr,[dic[#"image"] isEqualToString:#""]?#" ":dic[#"image"]];
[newMarr addObject:newStr];
}
//NSLog(#"NEW Array: %#",newMarr);
[self.coordinateQuadTree buildTree:newMarr];
}
}
UPDATE: This is the block of code where the TBDataFromLine is used
- (void)buildTree:(NSMutableArray *)lines
{
#autoreleasepool {
NSInteger count = lines.count - 1;
TBQuadTreeNodeData *dataArray = malloc(sizeof(TBQuadTreeNodeData) * count);
for (NSInteger i = 0; i < count; i++) {
dataArray[i] = TBDataFromLine(lines[i]);
}
//TBBoundingBox world = TBBoundingBoxMake(19, -166, 72, -53);
TBBoundingBox world = TBBoundingBoxMake(0,0,100,100);
_root = TBQuadTreeBuildWithData(dataArray, count, world, 4);
}
}
I've been working on this issue for hours now and still have no clue.
UPDATE: Here is the debugger's log I'm getting
2015-06-20 19:40:23.759 MapProject[13426:395344] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary componentsSeparatedByString:]: unrecognized selector sent to instance 0x7fdf93775680'
*** First throw call stack:
(
0 CoreFoundation 0x0000000112699c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001121c3bb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001126a10ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00000001125f713c ___forwarding___ + 988
4 CoreFoundation 0x00000001125f6cd8 _CF_forwarding_prep_0 + 120
5 MapProject 0x000000010f469ac4 TBDataFromLine + 84
6 MapProject 0x000000010f46a36f -[TBCoordinateQuadTree buildTree:] + 191
7 MapProject 0x000000010f3d2503 -[MMViewController findSpot:] + 771
8 UIKit 0x0000000110a52da2 -[UIApplication sendAction:to:from:forEvent:] + 75
9 UIKit 0x0000000110b6454a -[UIControl _sendActionsForEvents:withEvent:] + 467
10 UIKit 0x0000000110b63919 -[UIControl touchesEnded:withEvent:] + 522
11 UIKit 0x0000000110a9f998 -[UIWindow _sendTouchesForEvent:] + 735
12 UIKit 0x0000000110aa02c2 -[UIWindow sendEvent:] + 682
13 UIKit 0x0000000110a66581 -[UIApplication sendEvent:] + 246
14 UIKit 0x0000000110a73d1c _UIApplicationHandleEventFromQueueEvent + 18265
15 UIKit 0x0000000110a4e5dc _UIApplicationHandleEventQueue + 2066
16 CoreFoundation 0x00000001125cd431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
17 CoreFoundation 0x00000001125c32fd __CFRunLoopDoSources0 + 269
18 CoreFoundation 0x00000001125c2934 __CFRunLoopRun + 868
19 CoreFoundation 0x00000001125c2366 CFRunLoopRunSpecific + 470
20 GraphicsServices 0x000000011444da3e GSEventRunModal + 161
21 UIKit 0x0000000110a51900 UIApplicationMain + 1282
22 MapProject 0x000000010f474c2f main + 111
23 libdyld.dy
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Add an Exception break point and it will take to exactly to that line where that crash is happening. Also check 'line' cause it is changed to dictionary but you code expect it
to be a string
There is no [] operator on NSArray or NSMutableArray.
You need this:
for (NSInteger i = 0; i < count; i++) {
dataArray[i] = TBDataFromLine([lines objectAtIndex:i]);
}
Using [] on NSArray* effectively acted like "lines" was really a pointer to an array of NSMutableArray instances, whereas you wanted to get one of the items out of the array to which it pointed.

Attempting to Display Array on to UITableView

I am attempting to display an array which I receive from a JSON Dictionary onto a UITableView but I keep getting an error. I am trying to display all the comments for a given Instagram Picture onto a Table. Here is how I am attempting to display the cells:
MessageTableViewCell *cell = (MessageTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:MessengerCellIdentifier];
NSDictionary *instaPics = self.instagramData;
NSArray *commentArray = instaPics[#"comments"][#"data"];
NSString *commentText = [commentArray valueForKey:#"text"]; // Error occurs here
Message *message = self.messages[indexPath.row];
cell.titleLabel.text = message.username;
cell.bodyLabel.text = commentText;
Here is the error I receive:
-[__NSArrayI length]: unrecognized selector sent to instance 0x7f913052db10
2015-05-05 22:16:08.848 Floadt[6061:514032] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI length]: unrecognized selector sent to instance 0x7f913052db10'
*** First throw call stack:
(
0 CoreFoundation 0x0000000107d60c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010763cbb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000107d680ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000107cbe13c ___forwarding___ + 988
4 CoreFoundation 0x0000000107cbdcd8 _CF_forwarding_prep_0 + 120
5 UIKit 0x0000000106543ab4 -[UILabel _textRectForBounds:limitedToNumberOfLines:includingShadow:] + 65
6 UIKit 0x000000010654390f -[UILabel textRectForBounds:limitedToNumberOfLines:] + 76
7 UIKit 0x00000001065473b9 -[UILabel _intrinsicSizeWithinSize:] + 170
8 UIKit 0x0000000106547499 -[UILabel intrinsicContentSize] + 76
9 UIKit 0x00000001069e5b6c -[UIView(UIConstraintBasedLayout) _generateContentSizeConstraints] + 33
10 UIKit 0x00000001069e5930 -[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 422
11 UIKit 0x00000001069ecd25 -[UIView(AdditionalLayoutSupport) updateConstraints] + 162
12 UIKit 0x0000000106547304 -[UILabel updateConstraints] + 274
13 UIKit 0x00000001069ec346 -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 242
14 UIKit 0x00000001069ec53e -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
15 CoreFoundation 0x0000000107c67354 CFArrayApplyFunction + 68
16 UIKit 0x00000001069ec2ed -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
17 Foundation 0x0000000105b021be -[NSISEngine withBehaviors:performModifications:] + 155
18 UIKit 0x00000001069ec53e -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
19 CoreFoundation 0x0000000107c67354 CFArrayApplyFunction + 68
20 UIKit 0x00000001069ec2ed -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
21 UIKit 0x00000001069ec53e -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
22 UIKit 0x00000001069eca0e __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 96
23 UIKit 0x00000001069ec6d6 -[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 231
24 UIKit 0x00000001067d7531 -[UITableViewCellContentView updateConstraintsIfNeeded] + 94
25 UIKit 0x00000001069ecdde -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeeded] + 146
26 UIKit 0x00000001063e4a3d -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 114
27 UIKit 0x00000001063f0a2b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
28 QuartzCore 0x00000001061b4ec2 -[CALayer layoutSublayers] + 146
29 QuartzCore 0x00000001061a96d6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
30 UIKit 0x00000001063e4675 -[UIView(Hierarchy) layoutBelowIfNeeded] + 607
31 Floadt 0x0000000104195848 -[SLKTextViewController viewWillAppear:] + 296
32 UIKit 0x00000001064a4fa1 -[UIViewController _setViewAppearState:isAnimating:] + 487
33 UIKit 0x00000001064c6395 -[UINavigationController _startCustomTransition:] + 887
34 UIKit 0x00000001064d23bf -[UINavigationController _startDeferredTransitionIfNeeded:] + 386
35 UIKit 0x00000001064d2f0e -[UINavigationController __viewWillLayoutSubviews] + 43
36 UIKit 0x000000010661d715 -[UILayoutContainerView layoutSubviews] + 202
37 UIKit 0x00000001063f0a2b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
38 QuartzCore 0x00000001061b4ec2 -[CALayer layoutSublayers] + 146
39 QuartzCore 0x00000001061a96d6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
40 QuartzCore 0x00000001061a9546 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
41 QuartzCore 0x0000000106115886 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
42 QuartzCore 0x0000000106116a3a _ZN2CA11Transaction6commitEv + 462
43 UIKit 0x000000010636d626 _UIApplicationHandleEventQueue + 2140
44 CoreFoundation 0x0000000107c94431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
45 CoreFoundation 0x0000000107c8a2fd __CFRunLoopDoSources0 + 269
46 CoreFoundation 0x0000000107c89934 __CFRunLoopRun + 868
47 CoreFoundation 0x0000000107c89366 CFRunLoopRunSpecific + 470
48 GraphicsServices 0x0000000109716a3e GSEventRunModal + 161
49 UIKit 0x0000000106370900 UIApplicationMain + 1282
50 Floadt 0x0000000104218c5f main + 111
51 libdyld.dylib 0x0000000109f2b145 start + 1
52 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Here is an example copy of the JSON:
{
attribution = "<null>";
caption = {
"created_time" = 1430877943;
from = {
"full_name" = "Shreya M.";
id = 25085898;
"profile_picture" = "https://igcdn-photos-h-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-19/10890672_320752588135679_1815913692_a.jpg";
username = "shreya_mandava";
};
id = 978597576956579585;
text = "9+10????";
};
comments = {
count = 2;
data = (
{
"created_time" = 1430878007;
from = {
"full_name" = "Aleesha Toteja";
id = 17117902;
"profile_picture" = "https://instagramimages-a.akamaihd.net/profiles/profile_17117902_75sq_1373927314.jpg";
username = leeshtotes;
};
id = 978598112887967529;
text = "DIRT \Ud83d\Ude3b";
},
{
"created_time" = 1430878307;
from = {
"full_name" = "Shritha M.";
id = 375799796;
"profile_picture" = "https://igcdn-photos-f-a.akamaihd.net/hphotos-ak-xpf1/t51.2885-19/10454159_1056687271012469_2048676049_a.jpg";
username = "shritha_m";
};
id = 978600630846098439;
text = sigh;
}
);
};
"created_time" = 1430877943;
filter = Normal;
id = "978597574314167442_25085898";
images = {
"low_resolution" = {
height = 306;
url = "https://scontent.cdninstagram.com/hphotos-xfa1/t51.2885-15/s306x306/e15/11241842_1401517966839213_670743424_n.jpg";
width = 306;
};
"standard_resolution" = {
height = 640;
url = "https://scontent.cdninstagram.com/hphotos-xfa1/t51.2885-15/e15/11241842_1401517966839213_670743424_n.jpg";
width = 640;
};
thumbnail = {
height = 150;
url = "https://scontent.cdninstagram.com/hphotos-xfa1/t51.2885-15/s150x150/e15/11241842_1401517966839213_670743424_n.jpg";
width = 150;
};
};
likes = {
count = 22;
data = (
{
"full_name" = "Ronak Chopra";
id = 347652824;
"profile_picture" = "https://scontent.cdninstagram.com/hphotos-xpa1/t51.2885-19/11142328_1644920965736964_1040275960_a.jpg";
username = "conak_rhopra";
},
{
"full_name" = "emily bach";
id = 292615252;
"profile_picture" = "https://igcdn-photos-a-a.akamaihd.net/hphotos-ak-xap1/t51.2885-19/10454121_1558984144374824_122699173_a.jpg";
username = "emily_bach_";
},
{
"full_name" = "\Ud83c\Udf38Trisha\Ud83c\Udf38";
id = 303629882;
"profile_picture" = "https://igcdn-photos-g-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-19/10955125_708435799269374_749376734_a.jpg";
username = trishddishh;
},
{
"full_name" = "Shritha M.";
id = 375799796;
"profile_picture" = "https://igcdn-photos-f-a.akamaihd.net/hphotos-ak-xpf1/t51.2885-19/10454159_1056687271012469_2048676049_a.jpg";
username = "shritha_m";
}
);
};
link = "https://instagram.com/p/2UrU8bDgyS/";
location = {
id = 772010926;
latitude = "38.913782928";
longitude = "-77.383238738";
name = "ft. dirt";
};
tags = (
);
type = image;
user = {
"full_name" = "Shreya M.";
id = 25085898;
"profile_picture" = "https://igcdn-photos-h-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-19/10890672_320752588135679_1815913692_a.jpg";
username = "shreya_mandava";
};
"user_has_liked" = 0;
"users_in_photo" = (
{
position = {
x = "0.6703125";
y = "0.246875";
};
user = {
"full_name" = "John Nguyen";
id = 1477626916;
"profile_picture" = "https://igcdn-photos-d-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-19/11018467_1431648953794187_659343544_a.jpg";
username = bumbonguyen;
};
}
);
}
You are trying to get a value from key in a NSArray on:
[commentArray valueForKey:#"text"];
NSArray is not a dictionary has not keys (has multiple comments), should be accessed by his index.
[[commentArray objectAtIndex:0] valueForKey:#"text"];
Probably you will want, iterate over the comments and on each comment get his "text"
You can replace this line :
NSString *commentText = [commentArray valueForKey:#"text"];
with
for (NSDictionary *comment in commentArray ) {
NSString *commentText = [comment valueForKey:#"text"];
cell.bodyLabel.text = commentText;
}
Gonzalo is right. Your accessing commentArray like a NSDictionary but it is actually a NSArray. That causes the crash.
NSArray *commentArray = instaPics[#"comments"][#"data"];
It looks like a wrong access of key value..
As per my understanding you are trying to get value of comments.
your Json data contains root & child key value like,
comments
count
Data
caption
images
likes
...
Here your Comments having child value like count,data.
So can write the code to fetch value of comment > data>text
--------1--------
NSMutableDictionary *response = [[[json valueForKey:#"comments"] objectAtIndex:0]mutableCopy];
NSMutableDictionary *data = [[[response valueForKey:#"data"] objectAtIndex:0]mutableCopy];
NSString *text = [data valueForKey:#"text"];
----OR----2--------
NSMutableDictionary *response = [[[json valueForKey:#"comments"] objectAtIndex:0]mutableCopy];
NSArray *textarr=[response valueForKey:#"text"];

iOS Core Data NSRangeException

I have an issue I cant solve. Im creating an iOS application with Core Data framework. Everything was going just fine until I got NSRangeException. This exception I get in function which checks if Application data needs to be updated.
My code is:
- (BOOL) isTimetableUpdatedWithJSONData:(NSMutableDictionary*) data
{
appDelegate = [[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
//Do database update check logic here
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"MobileTimetableDataHash" inManagedObjectContext:managedObjectContext]];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
if (error != nil)
{
[self printErrorAlert];
}
//THERE IS ERROR HERE
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
NSString *changesFromDatabase = [changesGrabbed valueForKey:#"changes"];
NSString *changesFromService = [data valueForKeyPath:#"changes"];
if ([changesFromService isEqualToString:changesFromDatabase])
{
return YES;
}
else
{
[changesGrabbed setValue:changesFromService forKey:#"changes"];
[managedObjectContext save:&error];
if (error != nil)
{
[self printErrorAlert];
}
return NO;
}
}
Exception:
2014-06-12 21:36:12.034 MIF[437:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(
0 CoreFoundation 0x0000000101cb3495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000101a1299e objc_exception_throw + 43
2 CoreFoundation 0x0000000101c6be3f -[__NSArrayI objectAtIndex:] + 175
3 MIF 0x0000000100001942 -[MIFTimetableService isTimetableUpdatedWithJSONData:] + 514
4 MIF 0x000000010000219d -[MIFAppDelegate synchrinizeTimetableService] + 157
5 MIF 0x0000000100001dc2 -[MIFAppDelegate application:didFinishLaunchingWithOptions:] + 114
6 UIKit 0x00000001005ba3d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
7 UIKit 0x00000001005babe1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1605
8 UIKit 0x00000001005bea0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
9 UIKit 0x00000001005cfd4c -[UIApplication handleEvent:withNewEvent:] + 3189
10 UIKit 0x00000001005d0216 -[UIApplication sendEvent:] + 79
11 UIKit 0x00000001005c0086 _UIApplicationHandleEvent + 578
12 GraphicsServices 0x0000000103ce671a _PurpleEventCallback + 762
13 GraphicsServices 0x0000000103ce61e1 PurpleEventCallback + 35
14 CoreFoundation 0x0000000101c35679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
15 CoreFoundation 0x0000000101c3544e __CFRunLoopDoSource1 + 478
16 CoreFoundation 0x0000000101c5e903 __CFRunLoopRun + 1939
17 CoreFoundation 0x0000000101c5dd83 CFRunLoopRunSpecific + 467
18 UIKit 0x00000001005be2e1 -[UIApplication _run] + 609
19 UIKit 0x00000001005bfe33 UIApplicationMain + 1010
20 MIF 0x0000000100001d23 main + 115
21 libdyld.dylib 0x000000010234b5fd start + 1
22 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Guys, can anyone help me please? I realy need your help. Thank you.
Your troublemaker seems to be
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
If results is an empty array, calling objectAtIndex:0 will cause a NSRangeException, because there is no object at index 0. You better call [results firstObject], which won't crash with an error if results is empty array. firstObject() just returns nil in this case.
You are attempting to retrieve an object from an empty array. You should first check to see if the array contains any objects. Use the count property:
if (results.count > 0) {
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
//continue...
} else {
//Array is empty, object 0 will be beyond bounds
}
Just before
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
Add a branch based on the returned results. Something like the following:
if (results && [results count] > 0) {
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
...
}
Your array is empty. The stacktrace pretty much spells it out for you --
reason: '* -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for
empty array'

Resources