I am having an app in which I am passing some data between viewControllers with NSUserDefaults.
This is the code below I am using.
[[NSUserDefaults standardUserDefaults]setObject:selectedLists forKey:UserID];
Where selectedLists is NSMutableArray and UserID is NSString.
This code works fine until ios7 and xCode5.
Since I have updated xCode6 and now I am using ios8, my app works fine with xCode 6 and ios 7.1 but the app crashes when I run the app in ios8 devices with the error below.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0x7a027060'
I just don't understand what is the problem here.
If anyone has faced this problem with ios8 then please help me.
Thanks in advance.
Value of selectedLists
{
CardFace = Word;
ImportFlag = Import;
ListID = 1;
ListName = "Adjectives - Appearance";
QuizBy = Definition;
UserID = 1;
}
and UserId is 1.
EDITED
*** First throw call stack:
(
0 CoreFoundation 0x06a24df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x03ac8a97 objc_exception_throw + 44
2 CoreFoundation 0x06a2ca75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x069759c7 ___forwarding___ + 1047
4 CoreFoundation 0x0697558e _CF_forwarding_prep_0 + 14
5 CoreFoundation 0x068df30f CFStringGetLength + 143
6 CoreFoundation 0x069de510 _CFPrefsEncodeKeyValuePairIntoMessage + 64
7 CoreFoundation 0x06a275cf -[CFPrefsPlistSource sendMessageSettingValue:forKey:] + 111
8 CoreFoundation 0x06954f3a -[CFPrefsPlistSource alreadylocked_setValue:forKey:] + 250
9 CoreFoundation 0x06954e22 -[CFPrefsSource setValue:forKey:] + 82
10 CoreFoundation 0x06954dc3 ___CFPreferencesSetValueWithContainer_block_invoke + 51
11 CoreFoundation 0x0690ef0a +[CFPrefsSource withSourceForIdentifier:user:byHost:container:perform:] + 1274
12 CoreFoundation 0x06954d61 _CFPreferencesSetValueWithContainer + 225
13 CoreFoundation 0x06a0aa62 _CFPreferencesSetAppValueWithContainer + 66
14 Foundation 0x0347f53f -[NSUserDefaults(NSUserDefaults) setObject:forKey:] + 59
15 Foundation 0x0353eeba -[NSUserDefaults(NSKeyValueCoding) setValue:forKey:] + 68
16 Vocab 0x000eaecc Vocab + 720588
17 libobjc.A.dylib 0x03ade7cd -[NSObject performSelector:withObject:withObject:] + 84
18 UIKit 0x022a079d -[UIApplication sendAction:to:from:forEvent:] + 99
19 UIKit 0x022a072f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
20 UIKit 0x023d3a16 -[UIControl sendAction:to:forEvent:] + 69
21 UIKit 0x023d3e33 -[UIControl _sendActionsForEvents:withEvent:] + 598
22 UIKit 0x023d309d -[UIControl touchesEnded:withEvent:] + 660
23 UIKit 0x022f0aba -[UIWindow _sendTouchesForEvent:] + 874
24 UIKit 0x022f1595 -[UIWindow sendEvent:] + 791
25 UIKit 0x022b6aa9 -[UIApplication sendEvent:] + 242
26 UIKit 0x022c68de _UIApplicationHandleEventFromQueueEvent + 20690
27 UIKit 0x0229b079 _UIApplicationHandleEventQueue + 2206
28 CoreFoundation 0x069487bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
29 CoreFoundation 0x0693e2cd __CFRunLoopDoSources0 + 253
30 CoreFoundation 0x0693d828 __CFRunLoopRun + 952
31 CoreFoundation 0x0693d1ab CFRunLoopRunSpecific + 443
32 CoreFoundation 0x0693cfdb CFRunLoopRunInMode + 123
33 GraphicsServices 0x0436424f GSEventRunModal + 192
34 GraphicsServices 0x0436408c GSEventRun + 104
35 UIKit 0x0229ee16 UIApplicationMain + 1526
36 Vocab 0x0004c9bc Vocab + 72124
37 libdyld.dylib 0x03ee6ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Edited
On my tableview's didselect method...
UserID = [[users objectAtIndex:indexPath.row] valueForKey:#"UserID"];
where users is an array.
You should check the UserID type because crash is not related with changing NSArray to NSMutableArray.
You must be confusing NSNumber with NSString on your userID:
Change your code and instead of userID use the variable userIDString
NSString userIDString;
//If UserID is class of NSNumber turn its value to NSString
if ([UserID isKindOfClass:[NSNumber class]])
{
userIDString = [UserID stringValue];
}
else
userIDString = UserID ;
During runtime UserId is probably of type NSNumber, even if in your code it is typed NSString.
Check how UserId is created. Use the debugger to check the runtime type.
The newly posted code shows that your retrieve the UserId from the users array which probably consists of dictionaries. In those dictionaries there's a value for the key UserID. It depends on how the array of dictionaries is created (json deserialization?) but it seems that the type of object referred to by the UserID key is a number type, not a string. So all you have to do is convert this number into a string:
UserID = [[[users objectAtIndex:indexPath.row] valueForKey:#"UserID"] stringValue];
Now your key is always a string.
Try to encode your data in NSData and save it in NSUserDefaults and retrieved back, once needed. Have a look at this thread and this one.
Should not use NSUSerdefault to keep a collection of custom objects.
You should save them using NSkeyedUnarchiver/NSkeyedarchiver.
Ref: NSCoding.
I think can't store NSMutableArrays in NSUserDefaults since iOS8 (according to different posts). Try casting it into an array before (or create a new one).
Like this for example :
NSArray *arr = [NSArray arrayWithArray:selectedLists];
And store arr in NSUserDefaults.
Related
I am using for in loop to fetch data from plist. But it is showing following exception:
2015-07-16 11:16:43.597 plistNeha[640:60b] -[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x8d671b0
2015-07-16 11:16:43.721 plistNeha[640:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x8d671b0'
*** First throw call stack:
(
0 CoreFoundation 0x017ed1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x0156c8e5 objc_exception_throw + 44
2 CoreFoundation 0x0188a243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x017dd50b ___forwarding___ + 1019
4 CoreFoundation 0x017dd0ee _CF_forwarding_prep_0 + 14
5 plistNeha 0x00002b7d -[sdViewController plistbtn:] + 333
6 libobjc.A.dylib 0x0157e880 -[NSObject performSelector:withObject:withObject:] + 77
7 UIKit 0x0022e3b9 -[UIApplication sendAction:to:from:forEvent:] + 108
8 UIKit 0x0022e345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
9 UIKit 0x0032fbd1 -[UIControl sendAction:to:forEvent:] + 66
10 UIKit 0x0032ffc6 -[UIControl _sendActionsForEvents:withEvent:] + 577
11 UIKit 0x0032f243 -[UIControl touchesEnded:withEvent:] + 641
12 UIKit 0x0026dddd -[UIWindow _sendTouchesForEvent:] + 852
13 UIKit 0x0026e9d1 -[UIWindow sendEvent:] + 1117
14 UIKit 0x002405f2 -[UIApplication sendEvent:] + 242
15 UIKit 0x0022a353 _UIApplicationHandleEventQueue + 11455
16 CoreFoundation 0x0177677f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
17 CoreFoundation 0x0177610b __CFRunLoopDoSources0 + 235
18 CoreFoundation 0x017931ae __CFRunLoopRun + 910
19 CoreFoundation 0x017929d3 CFRunLoopRunSpecific + 467
20 CoreFoundation 0x017927eb CFRunLoopRunInMode + 123
21 GraphicsServices 0x037e15ee GSEventRunModal + 192
22 GraphicsServices 0x037e142b GSEventRun + 104
23 UIKit 0x0022cf9b UIApplicationMain + 1225
24 plistNeha 0x00002e1d main + 141
25 libdyld.dylib 0x01e34701 start + 1
26 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Code:
NSString *path=[[NSBundle mainBundle]pathForResource:#"x" ofType:#"plist"];
ald=[[NSDictionary alloc]initWithContentsOfFile:path];
for(NSDictionary *awq in ald){
NSLog(#"check");
NSString *qqw=#"";
qqw=[awq objectForKey:#"qq"];
NSLog(#"%#",qqw);
}
But, if I am fetching data one by one then it is showing on debugger area. for in loop is also working as it is printing check. May be the line after NSLog(#"check"); is creating some exceptions.
Try this
NSString *path=[[NSBundle mainBundle]pathForResource:#"x" ofType:#"plist"];
NSDictionary *ald=[[NSDictionary alloc]initWithContentsOfFile:path];
for(NSDictionary *awq in [ald allValues]){
NSLog(#"check");
NSString *qqw=#"";
qqw=[awq objectForKey:#"qq"];
NSLog(#"%#",qqw);
}
for in on a dictionary is enumerating its keys, not values. See this question for each loop in objective c for accessing NSMutable dictionary
Try this:
NSString *path=[[NSBundle mainBundle]pathForResource:#"x" ofType:#"plist"];
NSDictionary *plistDictionary = [[NSDictionary alloc]initWithContentsOfFile:path];
for(NSString *key in plistDictionary){
NSDictionary *dictionary = [plistDictionary objectForKey:key];
NSLog(#"%#",[dictionary objectForKey:#"qq"]);
}
I had to change your variable names because it was too confusing to work with 'ald', 'awq', 'qqw' , etc.
I implemented SQLite in xcode. I have 2 columns. When the first column has a row, then the second one is set to null, and vice versa. I'm trying to go through both columns and check if it has an object at that index.
NSLog(#"%# and %#", firstArray, secondArray); // It gives the right risults, but there aren't any null objects in any of them.
for (int i = 0; i < [firstArray count]; i++)
{
if (![[firstArray objectAtIndex:i] length] && [[secondArray objectAtIndex:i] length]) {
...
}
}
I have two issues.
First: There aren't any null objects in the rows, even though I set some to null. So what should I do to check if there is a null object, or if there's another way to add some kind null object that will actually add to the tables row?
Second: When I compile and run the app, it crashes with the error below. But when I remove the if statement, it works flawlessly.
-[__NSArrayM length]: unrecognized selector sent to instance 0x7fbfeb53b0a0
2015-03-30 11:25:04.731 MyApp [610:15600] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x7fbfeb53b0a0'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110874f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000011050dbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000011087c04d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00000001107d427c ___forwarding___ + 988
4 CoreFoundation 0x00000001107d3e18 _CF_forwarding_prep_0 + 120
5 MyApp 0x000000010fec3b59 -[ViewController ingredientAction] + 889
6 MyApp 0x000000010feba253 -[ViewController menuAction:] + 195
7 UIKit 0x0000000110ea58be -[UIApplication sendAction:to:from:forEvent:] + 75
8 UIKit 0x0000000110fac410 -[UIControl _sendActionsForEvents:withEvent:] + 467
9 UIKit 0x00000001110269ea -[UISegmentedControl _setSelectedSegmentIndex:notify:animate:] + 570
10 UIKit 0x0000000111028a0f -[UISegmentedControl touchesEnded:withEvent:] + 143
11 UIKit 0x0000000111252540 _UIGestureRecognizerUpdate + 9487
12 UIKit 0x0000000110eeaff6 -[UIWindow _sendGesturesForEvent:] + 1041
13 UIKit 0x0000000110eebc23 -[UIWindow sendEvent:] + 667
14 UIKit 0x0000000110eb89b1 -[UIApplication sendEvent:] + 246
15 UIKit 0x0000000110ec5a7d _UIApplicationHandleEventFromQueueEvent + 17370
16 UIKit 0x0000000110ea1103 _UIApplicationHandleEventQueue + 1961
17 CoreFoundation 0x00000001107aa551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
18 CoreFoundation 0x00000001107a041d __CFRunLoopDoSources0 + 269
19 CoreFoundation 0x000000011079fa54 __CFRunLoopRun + 868
20 CoreFoundation 0x000000011079f486 CFRunLoopRunSpecific + 470
21 GraphicsServices 0x0000000114c759f0 GSEventRunModal + 161
22 UIKit 0x0000000110ea4420 UIApplicationMain + 1282
23 MyApp 0x000000010fec11b3 main + 115
24 libdyld.dylib 0x00000001122ad145 start + 1
25 ??? 0x0000000000000001 0x0 + 1
Edit
I put #"" instead of null into the row. Then I change the if statement (in the for loop) to the following:
NSStirng *objectAtIndexFromArray = [NSString stringWithFormat:#"%#", [firstArray objectAtIndex:i]];
if ([objectAtIndexFromArray isEqualToString:#""])
{
NSLog(#"Hello");
}
I don't get any NSLogs of Hello.
I'm pretty new to ios development, but I know that if you want to add null object to you data collection you have to use NSNULL class.
NSArray can't hold nils, if you want to check if null, please use this code
id object = myArray[0];// similar to [myArray objectAtIndex:0]
if(![object isEqual:[NSNull null]])
{
//do something if object is not equals to [NSNull null]
}
I am getting the following error while joining a array of attributed strings.
2014-12-14 12:57:22.280 Matchismo[57752:60b] -[NSConcreteAttributedString _encodingCantBeStoredInEightBitCFString]: unrecognized selector sent to instance 0x8e81e20
2014-12-14 12:57:22.322 Matchismo[57752:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteAttributedString _encodingCantBeStoredInEightBitCFString]: unrecognized selector sent to instance 0x8e81e20'
*** First throw call stack:
(
0 CoreFoundation 0x017fa1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x015798e5 objc_exception_throw + 44
2 CoreFoundation 0x01897243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x017ea50b ___forwarding___ + 1019
4 CoreFoundation 0x017ea0ee _CF_forwarding_prep_0 + 14
5 CoreFoundation 0x0177e4e6 CFStringAppend + 566
6 CoreFoundation 0x017ebf04 -[NSArray componentsJoinedByString:] + 532
7 Matchismo 0x00004d59 -[CardGameViewController updateTextLabel] + 345
8 Matchismo 0x00005334 -[CardGameViewController updateUI] + 1396
9 Matchismo 0x00004bdd -[CardGameViewController touchCard:] + 253
10 libobjc.A.dylib 0x0158b880 -[NSObject performSelector:withObject:withObject:] + 77
11 UIKit 0x0023b3b9 -[UIApplication sendAction:to:from:forEvent:] + 108
12 UIKit 0x0023b345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
13 UIKit 0x0033cbd1 -[UIControl sendAction:to:forEvent:] + 66
14 UIKit 0x0033cfc6 -[UIControl _sendActionsForEvents:withEvent:] + 577
15 UIKit 0x0033c243 -[UIControl touchesEnded:withEvent:] + 641
16 UIKit 0x0027addd -[UIWindow _sendTouchesForEvent:] + 852
17 UIKit 0x0027b9d1 -[UIWindow sendEvent:] + 1117
18 UIKit 0x0024d5f2 -[UIApplication sendEvent:] + 242
19 UIKit 0x00237353 _UIApplicationHandleEventQueue + 11455
20 CoreFoundation 0x0178377f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
21 CoreFoundation 0x0178310b __CFRunLoopDoSources0 + 235
22 CoreFoundation 0x017a01ae __CFRunLoopRun + 910
23 CoreFoundation 0x0179f9d3 CFRunLoopRunSpecific + 467
24 CoreFoundation 0x0179f7eb CFRunLoopRunInMode + 123
25 GraphicsServices 0x037ee5ee GSEventRunModal + 192
26 GraphicsServices 0x037ee42b GSEventRun + 104
27 UIKit 0x00239f9b UIApplicationMain + 1225
28 Matchismo 0x00008d5d main + 141
29 libdyld.dylib 0x01e41701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Here is my code:
self.textLabel.text = [myArray componentsJoinedByString:#","];
I understand that the attributed strings that have shading and what not cannot be stored in a NSString. What should be the correct code.
Attaching a screenshot of what kind of data the NSAttributed strings hold. They hold the circles/squares/triangles that you see in the image.
If you want to append new string inside attributed string you can directly use appendAttributedString method. But it will always add at the end of attributed string.
If your requirement is to add in the middle of your attributed string and you want to add "," in each word of your attributed string with the shading attributes as well. So in this case you need to first convert your attributed string into string and then you need to store your words in array and then you need to iterate the words from array and convert that string into attributed string with your attributes and then use appendAttributedString with ",". Like that you can implement the same.
int x = 5;
int t = 6;
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:#"books.book", #"og:type",
#"www.goodreads.com", #"og:url",
#"Snow Crash", #"og:title",
#"978-3-16-148410-0",#"books:isbn",
#"http://en.wikipedia.org/wiki/File:Snowcrash.jpg", #"og:image",
#"www.google.com",#"og:audio:url",
#"www.facebook.com",#"al:windows_universal:url",
#"www.facebook.com",#"al:windows_phone:url",
#"www.facebook.com",#"al:windows:url",
#"www.facebook.com",#"al:iphone:url",
#"www.facebook.com",#"al:ipad:url",
x,#"books:rating:value",
t,#"books:rating:scale",
#"In reality, Hiro Protagonist delivers pizza for Uncle Enzo’s CosoNostra Pizza Inc., but in the Metaverse he’s a warrior prince. Plunging headlong into the enigma of a new computer virus that’s striking down hackers everywhere, he races along the neon-lit streets on a search-and-destroy mission for the shadowy virtual villain threatening to bring about infocalypse. Snow Crash is a mind-altering romp through a future America so bizarre, so outrageous…you’ll recognize it immediately.", #"og:description",
#"Science Fiction",#"books:genre",
#"eu_es",#"books:language:locale",
#[#"en_us",#"ca_es",#"cs_cz"],#"books:language:alternate",nil];
As you can see above I'm trying to create a Dictionary, however whenever i run the code i get error like this.
2014-06-11 23:50:50.338 TestApp[8374:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSDictionary dictionaryWithObjectsAndKeys:]: second object of each pair must be non-nil. Or, did you forget to nil-terminate your parameter list?'
*** First throw call stack:
(
0 CoreFoundation 0x00000001019ef495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010174e99e objc_exception_throw + 43
2 CoreFoundation 0x00000001019d27e3 +[NSDictionary dictionaryWithObjectsAndKeys:] + 1043
3 TestApp 0x000000010000724d -[CYCViewController postBooks:] + 1021
4 UIKit 0x00000001002fcf06 -[UIApplication sendAction:to:from:forEvent:] + 80
5 UIKit 0x00000001002fceb4 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 17
6 UIKit 0x00000001003d9880 -[UIControl _sendActionsForEvents:withEvent:] + 203
7 UIKit 0x00000001003d8dc0 -[UIControl touchesEnded:withEvent:] + 530
8 UIKit 0x0000000100333d05 -[UIWindow _sendTouchesForEvent:] + 701
9 UIKit 0x00000001003346e4 -[UIWindow sendEvent:] + 925
10 UIKit 0x000000010030c29a -[UIApplication sendEvent:] + 211
11 UIKit 0x00000001002f9aed _UIApplicationHandleEventQueue + 9579
12 CoreFoundation 0x000000010197ed21 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
13 CoreFoundation 0x000000010197e5f2 __CFRunLoopDoSources0 + 242
14 CoreFoundation 0x000000010199a46f __CFRunLoopRun + 767
15 CoreFoundation 0x0000000101999d83 CFRunLoopRunSpecific + 467
16 GraphicsServices 0x0000000103b66f04 GSEventRunModal + 161
17 UIKit 0x00000001002fbe33 UIApplicationMain + 1010
18 TestApp 0x0000000100008153 main + 115
19 libdyld.dylib 0x00000001020875fd start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I've followed solutions by adding NILbut still doesn't work. Everything is well placed. I checked and checked.
The values which can be nil in your dictionary are x and t. The above error says the object can't be nil, you can't put nil in place of an object of a key in a dictionary, instead you can try to put #"" or even you can supply [NSNull null].
Update
As you are trying to put
int x = 5;
int t = 6;
the above values are non-object values, a dictionary requires object, try put.
[NSNumber numberWithInt:x]
[NSNumber numberWithInt:t]
I have an iPhone app which fetches user information (first name, last name, city) in JSON format from different social networks.
This works mostly well, but one of the social networks returns the city as a number instead of a string (actually I should made one more REST call to map this number to a city name... but for now I just want to display the number).
And when I try to display that number in a UILabel I get the exception (here fullscreen):
2014-02-15 11:24:16.194 MyAuth[8872:a0b] -[__NSCFNumber length]: unrecognized selector sent to instance 0xb074f90
2014-02-15 11:24:16.203 MyAuth[8872:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb074f90'
*** First throw call stack:
(
0 CoreFoundation 0x01bb15e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x019348b6 objc_exception_throw + 44
2 CoreFoundation 0x01c4e903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x01ba190b ___forwarding___ + 1019
4 CoreFoundation 0x01ba14ee _CF_forwarding_prep_0 + 14
5 Foundation 0x015798ed -[NSConcreteMutableAttributedString replaceCharactersInRange:withString:] + 39
6 Foundation 0x0157a55a -[NSConcreteMutableAttributedString initWithString:attributes:] + 293
7 UIKit 0x0084fbc6 -[UILabel _setText:] + 97
8 UIKit 0x0084fd84 -[UILabel setText:] + 40
9 MyAuth 0x0000a296 -[UserViewController viewDidLoad] + 678
10 UIKit 0x007b6318 -[UIViewController loadViewIfRequired] + 696
11 UIKit 0x007b65b4 -[UIViewController view] + 35
12 UIKit 0x007d03e2 -[UINavigationController _startCustomTransition:] + 778
13 UIKit 0x007dd0c7 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
14 UIKit 0x007ddcb9 -[UINavigationController __viewWillLayoutSubviews] + 57
15 UIKit 0x00917181 -[UILayoutContainerView layoutSubviews] + 213
16 UIKit 0x0070d267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
17 libobjc.A.dylib 0x0194681f -[NSObject performSelector:withObject:] + 70
18 QuartzCore 0x054e12ea -[CALayer layoutSublayers] + 148
19 QuartzCore 0x054d50d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
20 QuartzCore 0x054d4f40 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
21 QuartzCore 0x0543cae6 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
22 QuartzCore 0x0543de71 _ZN2CA11Transaction6commitEv + 393
23 QuartzCore 0x0543e544 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
24 CoreFoundation 0x01b794ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
25 CoreFoundation 0x01b7941f __CFRunLoopDoObservers + 399
26 CoreFoundation 0x01b57344 __CFRunLoopRun + 1076
27 CoreFoundation 0x01b56ac3 CFRunLoopRunSpecific + 467
28 CoreFoundation 0x01b568db CFRunLoopRunInMode + 123
29 GraphicsServices 0x031a09e2 GSEventRunModal + 192
30 GraphicsServices 0x031a0809 GSEventRun + 104
31 UIKit 0x006a2d3b UIApplicationMain + 1225
32 MyAuth 0x0000ab7d main + 141
33 libdyld.dylib 0x02518725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
So I go to my JSON parsing code:
- (User*)createUserFromJson:(id)json
{
if (![json isKindOfClass:[NSDictionary class]]) {
NSLog(#"Parsing response failed");
return nil;
}
NSDictionary *dict = json[#"response"][0];
User *user = [[User alloc] init];
user.key = kVK;
user.userId = dict[#"uid"];
user.firstName = dict[#"first_name"];
user.lastName = dict[#"last_name"];
user.city = dict[#"city"]; // THE PROBLEMATIC LINE
user.avatar = dict[#"photo_big"];
user.female = (2 == [dict[#"female"] intValue]);
return user;
}
and try to change it to:
user.city = [NSString stringWithFormat:#"%d", dict[#"city"]];
but then I get the compile-time warning (here fullscreen):
Format specifies type 'int' but the argument has type 'id'
So my question is how to solve this issue cleanly (w/o Xcode warnings) and robust (when fetched JSON data happens to be a string)?
The fastest solution is:
[NSString stringWithFormat:#"%#", dict[#"city"]];
which will take the description of the string or the number and convert that into a string.
In the future you may want to use:
if ([1dict[#"city"] isKindOfClass:[NSNumber class]]) { ...
to check what you have received and work with it specifically. i.e. to do your lookup and to not use stringWithFormat: when you actually already have a string (because it's inefficient).