Swift strange NSInvalidArgumentException - ios

This code is in the initialization for a subclass of a UIView object. The UIView is circular in shape and displays a percentChange value using a nested UILabel. The following code resizes the UILabel and the font size to fit the text in the UIView. percentChange is some Int.
let stringAttrs: NSMutableDictionary = [NSFontAttributeName: stringFont, NSForegroundColorAttributeName: self.GreenColor]
if percentChange > 0 {
self.layer.borderColor = self.GreenColor.CGColor
stringAttrs.setValue(self.GreenColor, forKey: NSForegroundColorAttributeName)
indicator = ""
}
else if percentChange < 0 {
self.layer.borderColor = UIColor.redColor().CGColor
stringAttrs.setValue(UIColor.redColor().CGColor, forKey: NSForegroundColorAttributeName)
indicator = "▼"
}
else {
self.layer.borderColor = UIColor.grayColor().CGColor
stringAttrs.setValue(UIColor.grayColor().CGColor, forKey: NSForegroundColorAttributeName)
indicator = ""
}
do {
fontPointSize -= 0.5
stringFont = UIFont(name: "AmericanTypewriter", size: fontPointSize)!
stringAttrs.setValue(stringFont, forKey: NSFontAttributeName)
percentChangeLabel.attributedText = NSAttributedString(string: "\(indicator)\(abs(Int(percentChange)))%", attributes: stringAttrs)
percentChangeLabel.sizeToFit()
} while percentChangeLabel.frame.width > (self.frame.width - PaddingLeft - PaddingRight)
The three conditionals set indicator with "▲" (percentChange > 0), "▼" (percentChange < 0), or "" (percentChange == 0). Heres the bizarre thing, the app will only crash if percentChange is 0 and if indicator != "▲" or != "▼". If I change indicator to be "▼" or "▲" in the else statement, the app works fine. Every other character/string I have tried so far results in the same crash. Setting indicator to "" for percentChange > 0 or percentChange < 0 also does not cause any problems. I have attached the crash log and was hoping if someone could help me figure out whats going on, or perhaps guide me in the right direction.
2014-11-04 22:09:48.208 Cassandra[796:11817] -[__NSCFType set]: unrecognized selector sent to instance 0x7ff951b475f0
2014-11-04 22:09:48.210 Cassandra[796:11817] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType set]: unrecognized selector sent to instance 0x7ff951b475f0'
*** First throw call stack:
(
0 CoreFoundation 0x000000010937af35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010b36fbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010938204d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00000001092da27c ___forwarding___ + 988
4 CoreFoundation 0x00000001092d9e18 _CF_forwarding_prep_0 + 120
5 UIFoundation 0x000000010f42dcf3 __NSStringDrawingEngine + 28766
6 UIFoundation 0x000000010f42e1ec -[NSAttributedString(NSExtendedStringDrawing) drawWithRect:options:context:] + 561
7 UIKit 0x000000010a282a4c -[UILabel _drawTextInRect:baselineCalculationOnly:] + 5549
8 UIKit 0x000000010a280cab -[UILabel drawTextInRect:] + 624
9 UIKit 0x000000010a282c60 -[UILabel drawRect:] + 100
10 UIKit 0x000000010a130569 -[UIView(CALayerDelegate) drawLayer:inContext:] + 496
11 QuartzCore 0x0000000109f42942 -[CALayer drawInContext:] + 113
12 QuartzCore 0x0000000109e3fd5b CABackingStoreUpdate_ + 2793
13 QuartzCore 0x0000000109f42851 ___ZN2CA5Layer8display_Ev_block_invoke + 59
14 QuartzCore 0x0000000109f426e9 _ZN2CA5Layer8display_Ev + 1469
15 QuartzCore 0x0000000109f37801 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 301
16 QuartzCore 0x0000000109f37889 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
17 QuartzCore 0x0000000109ea563e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
18 QuartzCore 0x0000000109ea674a _ZN2CA11Transaction6commitEv + 390
19 QuartzCore 0x0000000109ea6db5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
20 CoreFoundation 0x00000001092afdc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
21 CoreFoundation 0x00000001092afd20 __CFRunLoopDoObservers + 368
22 CoreFoundation 0x00000001092a5b53 __CFRunLoopRun + 1123
23 CoreFoundation 0x00000001092a5486 CFRunLoopRunSpecific + 470
24 GraphicsServices 0x000000010e05e9f0 GSEventRunModal + 161
25 UIKit 0x000000010a0b7420 UIApplicationMain + 1282
26 Cassandra 0x0000000108da8ade top_level_code + 78
27 Cassandra 0x0000000108da8b1a main + 42
28 libdyld.dylib 0x000000010bb49145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Update: The UIView above is nested in a subclass of UITableCellView which is being added to a UITableView. It seems that the crash occurs consistently after the last UITableViewCell is added.

I still don't know whats wrong, but I circumvented the problem by using the UILabel properties to set the text, font and textColor instead of using an attributedText string.

I don't use this function: stringAttrs.setValue(stringFont, forKey: NSFontAttributeName)
Don't set the font like you did. Look at this example:
let stringFont = [NSFontAttributeName:UIFont(name: "AmericanTypewriter", size: 18.0)]
let stringAttrs= NSAttributedString(string: "Hello Swift! This is a tutorial looking at ", attributes:textFont)
Look at this link for usage: http://sketchytech.blogspot.com/2014/08/swift-creating-styled-and-attributed.html

Related

Xcode strange error when button is pressed

So my Swift program in Xcode 6.4 is working fine, until I click one of my buttons in particular. When I click it, the simulator crashes and the following is printed to the console:
2015-08-12 21:41:08.323 Unit Hero 2.0[2549:99472] -[Unit_Hero_2_0.ViewController finalUnitsButton:]: unrecognized selector sent to instance 0x7faf20675d10
2015-08-12 21:41:08.326 Unit Hero 2.0[2549:99472] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Unit_Hero_2_0.ViewController finalUnitsButton:]: unrecognized selector sent to instance 0x7faf20675d10'
*** First throw call stack:
0 CoreFoundation 0x000000010b630c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010d19bbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010b6380ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010b58e13c ___forwarding___ + 988
4 CoreFoundation 0x000000010b58dcd8 _CF_forwarding_prep_0 + 120
5 UIKit 0x000000010bed0d62 -[UIApplication sendAction:to:from:forEvent:] + 75
6 UIKit 0x000000010bfe250a -[UIControl _sendActionsForEvents:withEvent:] + 467
7 UIKit 0x000000010bfe18d9 -[UIControl touchesEnded:withEvent:] + 522
8 UIKit 0x000000010bf1d958 -[UIWindow _sendTouchesForEvent:] + 735
9 UIKit 0x000000010bf1e282 -[UIWindow sendEvent:] + 682
10 UIKit 0x000000010bee4541 -[UIApplication sendEvent:] + 246
11 UIKit 0x000000010bef1cdc _UIApplicationHandleEventFromQueueEvent + 18265
12 UIKit 0x000000010becc59c _UIApplicationHandleEventQueue + 2066
13 CoreFoundation 0x000000010b564431 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
14 CoreFoundation 0x000000010b55a2fd __CFRunLoopDoSources0 + 269
15 CoreFoundation 0x000000010b559934 __CFRunLoopRun + 868
16 CoreFoundation 0x000000010b559366 CFRunLoopRunSpecific + 470
17 GraphicsServices 0x000000010f604a3e GSEventRunModal + 161
18 UIKit 0x000000010becf8c0 UIApplicationMain + 1282
19 Unit Hero 2.0 0x000000010b4251c7 main + 135
20 libdyld.dylib 0x000000010d8d1145 start + 1
libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
And here is the code for the button in question:
#IBAction func newCalculationButton(sender: AnyObject)
{
if (equation.count != 0) //empties arrays to prepare for a new calculation
{
equation.removeAll()
}
if (unitsOriginal.count != 0)
{
unitsOriginal.removeAll()
}
if (operations.count != 0)
{
operations.removeAll()
}
if (numerator.count != 0)
{
numerator.removeAll()
}
if (denominator.count != 0)
{
denominator.removeAll()
}
if (largestComponent.count != 0)
{
largestComponent.removeAll()
}
finalNumerator = nil
finalDenominator = nil
isNilNumerator = 0 //counter for number of nil items in numerator
isNilDenominator = 0 //counter for number of nil items in denominator
mainLabel.text = ""
}
What exception could it be referring to? The code is pretty simple, I'm not sure what could be wrong. Any insight is much appreciated!
Some times we copy paste button and Xcode keeps old references (actions and outlets). Check it:
Check all Outlets (IB)
Check all Actions (IB)

CIGaussianBlur exception [UIImage _internalRepresentation]

I am trying to statically blur an UIImage using the method below:
func blurImage(image: UIImage!, blurLevel: CGFloat!) -> UIImage! {
if self.context == nil {
self.context = CIContext();
}
let inputImage = CIImage(image: image);
let filter = CIFilter(name: "CIGaussianBlur");
filter.setValue(image, forKey: kCIInputImageKey);
filter.setValue(blurLevel, forKey: kCIInputRadiusKey);
let outputImage = filter.valueForKey(kCIOutputImageKey) as CIImage;
let outImage = self.context?.createCGImage(outputImage, fromRect: outputImage.extent());
return UIImage(CGImage: outImage)!;
}
But the debugger immediately raises an exception on filter.valueForKey(kCIOutputImageKey), confirmed by trying to print the object in the LLDB debugger:
-[UIImage _internalRepresentation]: unrecognized selector sent to instance 0x7fef33e89b00
Does anyone know why this exception is surfacing? I've tried different variations of the method to no avail as per various stack overflow questions, but I can't seem to figure this out...
I suspect it may just be a just a bug on Apple's part after more investigation, but if anyone has encountered this before help is appreciated
Stacktrace
2015-03-09 19:34:14.502 Rocks[3346:511164] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImage _internalRepresentation]: unrecognized selector sent to instance 0x7fef33e89b00'
*** First throw call stack:
(
0 CoreFoundation 0x0000000112106f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000111d9fbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000011210e04d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000011206627c ___forwarding___ + 988
4 CoreFoundation 0x0000000112065e18 _CF_forwarding_prep_0 + 120
5 CoreImage 0x000000011192cef7 -[CIGaussianBlur outputImage] + 108
6 Foundation 0x000000010f939823 -[NSObject(NSKeyValueCoding) valueForKey:] + 251
7 Rocks 0x000000010f588024 _TFC4Rocks23LocalCollectionViewCell9blurImagefS0_FTGSQCSo7UIImage_9blurLevelGSQV12CoreGraphics7CGFloat__GSQS1__ + 3284
8 Rocks 0x000000010f589538 _TFC4Rocks23LocalCollectionViewCell31requestCellProfilePictureChangefS0_FGSQPSs9AnyObject__T_ + 3544
9 Rocks 0x000000010f58450c _TFC4Rocks29LocalCollectionViewController14collectionViewfS0_FTCSo16UICollectionView22cellForItemAtIndexPathCSo11NSIndexPath_CSo20UICollectionViewCell + 860
10 Rocks 0x000000010f584b6f _TToFC4Rocks29LocalCollectionViewController14collectionViewfS0_FTCSo16UICollectionView22cellForItemAtIndexPathCSo11NSIndexPath_CSo20UICollectionViewCell + 79
11 UIKit 0x0000000110bea41b -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 244
12 UIKit 0x0000000110bebb54 -[UICollectionView _updateVisibleCellsNow:] + 3445
13 UIKit 0x0000000110bef801 -[UICollectionView layoutSubviews] + 243
14 UIKit 0x0000000110635973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
15 QuartzCore 0x00000001103a0de8 -[CALayer layoutSublayers] + 150
16 QuartzCore 0x0000000110395a0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x000000011039587e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
18 QuartzCore 0x000000011030363e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
19 QuartzCore 0x000000011030474a _ZN2CA11Transaction6commitEv + 390
20 UIKit 0x00000001105ba54d -[UIApplication _reportMainSceneUpdateFinished:] + 44
21 UIKit 0x00000001105bb238 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2642
22 UIKit 0x00000001105b9bf2 -[UIApplication workspaceDidEndTransaction:] + 179
23 FrontBoardServices 0x0000000115f0b2a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
24 CoreFoundation 0x000000011203c53c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
25 CoreFoundation 0x0000000112032285 __CFRunLoopDoBlocks + 341
26 CoreFoundation 0x0000000112032045 __CFRunLoopRun + 2389
27 CoreFoundation 0x0000000112031486 CFRunLoopRunSpecific + 470
28 UIKit 0x00000001105b9669 -[UIApplication _run] + 413
29 UIKit 0x00000001105bc420 UIApplicationMain + 1282
30 Rocks 0x000000010f59262e top_level_code + 78
31 Rocks 0x000000010f59266a main + 42
32 libdyld.dylib 0x0000000112bb8145 start + 1
33 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

NSInvalidArgumentException: unrecognized selector sent to instance | SWIFT

I realize this question has been asked many times, but it seems to be caused by many different things and is very situational.
My trace:
2015-02-27 16:20:06.289 RTApp[43486:1122681] -[RTApp.conversationVC keyboardWasShown]: unrecognized selector sent to instance 0x7f866a766830
2015-02-27 16:20:06.291 RTApp[43486:1122681] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RTApp.conversationVC keyboardWasShown]: unrecognized selector sent to instance 0x7f866a766830'
*** First throw call stack:
(
0 CoreFoundation 0x00000001071b8f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000106e51bb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001071c004d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010711827c ___forwarding___ + 988
4 CoreFoundation 0x0000000107117e18 _CF_forwarding_prep_0 + 120
5 CoreFoundation 0x0000000107188cec __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
6 CoreFoundation 0x00000001070888a4 _CFXNotificationPost + 2484
7 Foundation 0x00000001069af6b8 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
8 UIKit 0x0000000107c75eb8 -[UIInputWindowController postEndNotifications:withInfo:] + 527
9 UIKit 0x0000000107c77725 __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke572 + 354
10 UIKit 0x0000000107617113 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 326
11 UIKit 0x00000001075fee6a -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 209
12 UIKit 0x00000001075ff1a0 -[UIViewAnimationState animationDidStop:finished:] + 76
13 QuartzCore 0x0000000105c4c7ee _ZN2CA5Layer23run_animation_callbacksEPv + 308
14 libdispatch.dylib 0x0000000108de57f4 _dispatch_client_callout + 8
15 libdispatch.dylib 0x0000000108dce8fb _dispatch_main_queue_callback_4CF + 949
16 CoreFoundation 0x0000000107120fe9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
17 CoreFoundation 0x00000001070e3eeb __CFRunLoopRun + 2043
18 CoreFoundation 0x00000001070e3486 CFRunLoopRunSpecific + 470
19 GraphicsServices 0x000000010aa0f9f0 GSEventRunModal + 161
20 UIKit 0x00000001075a5420 UIApplicationMain + 1282
21 RTApp 0x000000010563623e top_level_code + 78
22 RTApp 0x000000010563627a main + 42
23 libdyld.dylib 0x0000000108e1a145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
And the function in question:
func keyboardWasShown(notification: NSNotification){
let dict:NSDictionary = notification.userInfo!
let s:NSValue = dict.valueForKey(UIKeyboardFrameEndUserInfoKey) as NSValue
let rect:CGRect = s.CGRectValue()
UIView.animateWithDuration(0.3, delay: 0, options: .CurveLinear, animations: {
self.resultsScrollView.frame.origin.y = self.scrollViewOriginalY - rect.height
self.frameMessageView.frame.origin.y = self.frameMessageOriginalY - rect.height
var bottomOffset:CGPoint = CGPointMake(0, self.resultsScrollView.contentSize.height - self.resultsScrollView.bounds.size.height)
self.resultsScrollView.setContentOffset(bottomOffset, animated: false)
}, completion: {
(finished:Bool) in
})
}
So this should just be pushing the view up so it's not covered by the keyboard as you type. But as soon as I pull the keyboard up, it crashes. It would be great if Xcode told you what line the error is on, but that would be too easy..
Does this mean the function doesn't recognizer the parameter I'm passing in to it? Or why can't it recognize the 'selector'?
Judging by the error message reason: '-[RTApp.conversationVC keyboardWasShown]: unrecognized selector you used the wrong selector when you added the Notification Observer.
You should use Selector("keyboardWasShown:") instead of Selector("keyboardWasShown") because your method has one parameter.

Something strange happening when assigning title to UIViewController

I am having some viewControllers each connected by segues. The rootViewController is connected to the NavigationController. Now, in one UIViewController, I am performing a segue to go to another UIViewController like this and it works:
self.performSegueWithIdentifier("toLoginTypeActivity", sender: self)
The UIViewController to which I am taken to after the segues is performed is this:
import Foundation
import UIKit
class LoginTypeActivityViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
println("I am here.")
//self.title = "Namaskar" // Here seems to be something strange.
println("I am here also.")
}
}
But, the segue does not work if I comment out self.title in the code(marked as strange). Though, all the println are working. Even, "I am here also." gets printed. But, the segues is not getting performed. It gives a runtime error.
What should be the problem and how should it be resolved? I am sure I have named the identifier correctly.
Here is the runtime error:
2014-10-13 17:21:27.878 mobilepay[29387:1382271] -[Swift._NSContiguousString set]: unrecognized selector sent to instance 0x7b6b33d0
2014-10-13 17:21:27.881 mobilepay[29387:1382271] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Swift._NSContiguousString set]: unrecognized selector sent to instance 0x7b6b33d0'
*** First throw call stack:
(
0 CoreFoundation 0x00bb5df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x0083fa97 objc_exception_throw + 44
2 CoreFoundation 0x00bbda75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x00b069c7 ___forwarding___ + 1047
4 CoreFoundation 0x00b0658e _CF_forwarding_prep_0 + 14
5 UIFoundation 0x067eeb91 __NSStringDrawingEngine + 29221
6 UIFoundation 0x067e784d -[NSString(NSExtendedStringDrawing) drawWithRect:options:attributes:context:] + 171
7 UIKit 0x013be151 -[UILabel _drawTextInRect:baselineCalculationOnly:] + 6626
8 UIKit 0x013bbe30 -[UILabel drawTextInRect:] + 581
9 UIKit 0x013be256 -[UILabel drawRect:] + 98
10 UIKit 0x0123354b -[UIView(CALayerDelegate) drawLayer:inContext:] + 519
11 QuartzCore 0x01077d51 -[CALayer drawInContext:] + 118
12 QuartzCore 0x01077c87 _ZL16backing_callbackP9CGContextPv + 96
13 QuartzCore 0x00f5c7ae CABackingStoreUpdate_ + 2788
14 QuartzCore 0x01077c1f ___ZN2CA5Layer8display_Ev_block_invoke + 93
15 QuartzCore 0x010ad406 x_blame_allocations + 15
16 QuartzCore 0x01077a85 _ZN2CA5Layer8display_Ev + 1591
17 QuartzCore 0x01077cd6 -[CALayer _display] + 33
18 QuartzCore 0x01077446 _ZN2CA5Layer7displayEv + 142
19 QuartzCore 0x01077cb0 -[CALayer display] + 33
20 QuartzCore 0x0106bee6 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 322
21 QuartzCore 0x0106bf6c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 38
22 QuartzCore 0x00fca676 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 284
23 QuartzCore 0x00fcba3c _ZN2CA11Transaction6commitEv + 392
24 QuartzCore 0x00fcc108 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
25 CoreFoundation 0x00ad8fbe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
26 CoreFoundation 0x00ad8f00 __CFRunLoopDoObservers + 400
27 CoreFoundation 0x00ace93a __CFRunLoopRun + 1226
28 CoreFoundation 0x00ace1ab CFRunLoopRunSpecific + 443
29 CoreFoundation 0x00acdfdb CFRunLoopRunInMode + 123
30 GraphicsServices 0x0317124f GSEventRunModal + 192
31 GraphicsServices 0x0317108c GSEventRun + 104
32 UIKit 0x011a8e16 UIApplicationMain + 1526
33 mobilepay 0x001410de top_level_code + 78
34 mobilepay 0x0014111b main + 43
35 libdyld.dylib 0x03ad7ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Note that assigning to the self.title works in the other ViewControllers though.
Edit:
Here is the updated code.
class LoginTypeActivityViewController: UIViewController{
var delegate = UIApplication.sharedApplication().delegate as AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
println("viewDidLoad self.title = \(self.title)")
println("viewDidLoad self.navigationItem.title = \(self.navigationItem.title)")
}
override func viewWillAppear(animated: Bool) {
println("viewWillAppear self.title = \(self.title)")
println("viewWillAppear self.navigationItem.title = \(self.navigationItem.title)")
}
override func viewDidAppear(animated: Bool) {
println("viewDidAppear self.title = \(self.title)")
println("viewDidAppear self.navigationItem.title = \(self.navigationItem.title)")
self.navigationItem.title = "Koshish"
println("printing in viewDidAppear after setting self.navigatioItem.title = \(self.navigationItem.title)")
}
}
And here is the output:
viewDidLoad self.title = nil
viewDidLoad self.navigationItem.title = nil
viewWillAppear self.title = nil
viewWillAppear self.navigationItem.title = nil
viewDidAppear self.title = nil
viewDidAppear self.navigationItem.title = nil
printing in viewDidAppear after setting self.navigatioItem.title = Optional("Koshish")
2014-10-14 12:46:48.931 mobilepay[34547:1593230] -[Swift._NSContiguousString set]: unrecognized selector sent to instance 0x7a162090
2014-10-14 12:46:48.933 mobilepay[34547:1593230] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Swift._NSContiguousString set]: unrecognized selector sent to instance 0x7a162090'
*** First throw call stack:
(
0 CoreFoundation 0x00bd3df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x0085da97 objc_exception_throw + 44
2 CoreFoundation 0x00bdba75 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
3 CoreFoundation 0x00b249c7 ___forwarding___ + 1047
4 CoreFoundation 0x00b2458e _CF_forwarding_prep_0 + 14
5 UIFoundation 0x0680cb91 __NSStringDrawingEngine + 29221
6 UIFoundation 0x0680584d -[NSString(NSExtendedStringDrawing) drawWithRect:options:attributes:context:] + 171
7 UIKit 0x013dc151 -[UILabel _drawTextInRect:baselineCalculationOnly:] + 6626
8 UIKit 0x013d9e30 -[UILabel drawTextInRect:] + 581
9 UIKit 0x013dc256 -[UILabel drawRect:] + 98
10 UIKit 0x0125154b -[UIView(CALayerDelegate) drawLayer:inContext:] + 519
11 QuartzCore 0x01095d51 -[CALayer drawInContext:] + 118
12 QuartzCore 0x01095c87 _ZL16backing_callbackP9CGContextPv + 96
13 QuartzCore 0x00f7a7ae CABackingStoreUpdate_ + 2788
14 QuartzCore 0x01095c1f ___ZN2CA5Layer8display_Ev_block_invoke + 93
15 QuartzCore 0x010cb406 x_blame_allocations + 15
16 QuartzCore 0x01095a85 _ZN2CA5Layer8display_Ev + 1591
17 QuartzCore 0x01095cd6 -[CALayer _display] + 33
18 QuartzCore 0x01095446 _ZN2CA5Layer7displayEv + 142
19 QuartzCore 0x01095cb0 -[CALayer display] + 33
20 QuartzCore 0x01089ee6 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 322
21 QuartzCore 0x01089f6c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 38
22 QuartzCore 0x00fe8676 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 284
23 QuartzCore 0x00fe9a3c _ZN2CA11Transaction6commitEv + 392
24 QuartzCore 0x00fea108 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
25 CoreFoundation 0x00af6fbe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
26 CoreFoundation 0x00af6f00 __CFRunLoopDoObservers + 400
27 CoreFoundation 0x00aec93a __CFRunLoopRun + 1226
28 CoreFoundation 0x00aec1ab CFRunLoopRunSpecific + 443
29 CoreFoundation 0x00aebfdb CFRunLoopRunInMode + 123
30 GraphicsServices 0x0318f24f GSEventRunModal + 192
31 GraphicsServices 0x0318f08c GSEventRun + 104
32 UIKit 0x011c6e16 UIApplicationMain + 1526
33 mobilepay 0x00160f5e top_level_code + 78
34 mobilepay 0x00160f9b main + 43
35 libdyld.dylib 0x03af5ac9 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Solved
I finally found the problem in my code:
In my didFinishLaunchingWithOptions, I was doing this:
var navigationBarAppearance = UINavigationBar.appearance()
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
navigationBarAppearance.tintColor = UIColor(rgba: "#000000", alpha: 1.0)
navigationBarAppearance.barTintColor = UIColor(rgba: "#000000", alpha: 1.0)
navigationBarAppearance.titleTextAttributes = [NSFontAttributeName: UIFont(name: "Arial-BoldMT", size: 20.0), NSForegroundColorAttributeName: "#000000", alpha: 1.0)]
As you can see, in NSForegroundColorAttributeName, I was just setting the string and not calling the UIColor function with it.
I feel Swift should have given me some hint that I am not calling NSForegroundColorAttribute with the correct value.
I cannot give you the answer, but have suggestions on how you can solve it. Somehow the title property of your UINavigationItem is been set to some object not a NSString.
So where you have your "//self.title" line, log the value of title, the value of your class' UINavigationItem title, and if either is not nil, then log the class. My guess its somehow been set to a number not a string, but it may just be garbage or something released. Or, your storyboard file could have become corrupted.
EDIT: So something is really weird here. Other ideas:
if this segue is triggered before viewDidLoad by the presenting view, odd things might happen.
implement 'override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)' in the calling class, then verify you are on the main thread
use the debugger, add an exception breakpoint, and when you get the crash verify the crash is on Thread 0. Also, poke around - there is an object that doesn't respond to a selector, you have its address, so do a 'po 0x.......' in the debugger and see what it is.
failing that, you'll need to spend some time and attempt to create a demo project modeled after your real one, that has the same problem. If you can do that, you can upload it to a public site like Dropbox, update your question, and people like me will look at it (I'll at least do it). Its traditional if you get to this point to offer some bounty, I just say that so you know, but I'll look at it without one (I don't really need any more points).

Parsing JSON and sometimes getting number instead of a string

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).

Resources