Uncaught NSException when battery level changes - ios

I'm working on a simple app that just shows the time and battery level. The time part works flawlessly, and I can monitor the battery level, but the battery indicator icon crashes the app when there are any changes to the device's battery. Here's the relevant code:
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.isBatteryMonitoringEnabled = true // Enable battery monitoring
NotificationCenter.default.addObserver(self, selector: Selector(("batteryStateDidChange:")), name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil) // Add battery state checker
NotificationCenter.default.addObserver(self, selector: Selector(("batteryLevelDidChange:")), name: NSNotification.Name.UIDeviceBatteryLevelDidChange, object: nil) // Add battery level checker
// Get the battery level
var batteryLevel: Int {
return Int(UIDevice.current.batteryLevel * 100)
}
update()
timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.update), userInfo: nil, repeats: true) // Start the timed scheduler
}
Here's the error:
2017-06-24 11:45:27.783761-0500 SimpleClock[1484:846193] -[SimpleClock.ViewController batteryLevelDidChange:]: unrecognized selector sent to instance 0x15dd15bc0
2017-06-24 11:45:27.785656-0500 SimpleClock[1484:846193] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SimpleClock.ViewController batteryLevelDidChange:]: unrecognized selector sent to instance 0x15dd15bc0'
*** First throw call stack:
(0x181c65858 0x18043c528 0x181c72a6c 0x188815140 0x181c6af68 0x181b4ce5c 0x181bf3004 0x181bf25a4 0x181bf2308 0x181c74268 0x181b2a4e4 0x1826f32d4 0x1884abd60 0x1884abbc8 0x181ecdaf0 0x181beda68 0x181c0cbc8 0x181c0c370 0x181c09d80 0x181b28280 0x183639f94 0x1884d70f0 0x100da10e4 0x180919e40)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

The -[SimpleClock.ViewController batteryLevelDidChange:]: unrecognised selector error indicates that the batteryLevelDidChange function is missing in the code or as Vadian commented, the signature is wrong.

Use an if condition before adding the observer for batteryStateDidChange: selector. You can use respondsToSelector: method for this. This way you can make sure if the selector is implemented.
Also you need to implement the selector in your source file as I can't see it in your code, hence giving the unrecognised selector error.
Hope it helps!

Related

KVO addObserver crashes on iOS 13

Strange exception started to occur when running stable project on iOS 13.
libc++abi.dylib: terminating with uncaught exception of type NSException
XCode provides no additional info and no stacktrace.
Here is the code causing the exception
self.collectionView?.addObserver(self, forKeyPath: "contentSize", options: [NSKeyValueObservingOptions.old], context: nil)
self.viewTranformObserver = self.collectionView?.observe(\.contentSize, options: [.old]) { (_, _) in
self.collectionViewContentSizeChanged()
}
Any ideas?

App crash when MFMessageComposeViewController is initialisation

I want to send a message through my app. I call the following method on click
#IBAction func sendMessage(_ sender: Any) {
if (MFMessageComposeViewController.canSendText()) {
let composeVC = MFMessageComposeViewController()
composeVC.messageComposeDelegate = self
// Configure the fields of the interface.
composeVC.recipients = ["4085551212"]
composeVC.body = "Hello from California!"
// Present the view controller modally.
self.presentViewController(composeVC, animated: true, completion: nil)
}
}
The problem is if I run the app on device, it crashes at MFMessageComposeViewController initialisation i.e.
let composeVC = MFMessageComposeViewController()
If I run the app in simulator, it crashes on presentation i.e.
self.present(composeVC, animated: true, completion: nil)
Error log when I run the app on device
2018-01-29 12:03:57.826816+0530 EWS[2495:806400] *** Assertion failure in -[UICGColor encodeWithCoder:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.33.7/UIColor.m:1722
2018-01-29 12:03:57.827522+0530 EWS[2495:806400] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only RGBA or White color spaces are supported in this situation.'
*** First throw call stack:
(0x183702364 0x182948528 0x183702238 0x18409d7f4 0x18d08fffc 0x1840574dc 0x18405e8d8 0x18d4ebf20 0x18d4eb74c 0x18d4e7044 0x1835d03c0 0x18d4e6d44 0x18d7f16fc 0x18d60bd18 0x18d60b94c 0x19aee4534 0x19aecbff4 0x19aecc314 0x1984ce830 0x101159ec0 0x101158888 0x1011584b4 0x1011589c0 0x18cc186b4 0x18cc18634 0x18cc031dc 0x18cc17f28 0x18cc17a48 0x18cc12f60 0x18cbe3f64 0x18d53931c 0x18d53b8a8 0x18d5347c0 0x1836aa97c 0x1836aa8fc 0x1836aa184 0x1836a7d5c 0x1835c7e58 0x185474f84 0x18cc4767c 0x101157170 0x1830e456c)
libc++abi.dylib: terminating with uncaught exception of type NSException
Error log when I run the app on simulator (without checking if(MFMessageComposeViewController.canSendText()))
2018-01-29 12:07:49.395714+0530 EWS[3533:67163] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <EWS.BlockVC: 0x7f899c61db10>.'
*** First throw call stack:
Any help would be appreciated.
Okay,
When you run it in iPhone : The crash log clearly states that "Only RGBA or White color spaces are supported in this situation." So by hint I would say you are assigning color somewhere, (Some Global tint, navigation bar tint) , which doesn't apply to a MFMessageComposeViewController, hence its crashing.
When you run it in the simulator :
if (MFMessageComposeViewController.canSendText()), this line will prevent it from initialising the MFMessageComposeViewController, in the simulator as it cant send text, hence when you try to present it, its not yet initialised and crashing.
On a second thought, as per your code : self.presentViewController(composeVC, animated: true, completion: nil), this line should not even be called while running in the simulator as this line is inside the if statement, which wont get through.
Also change the tint color or any while initialising the controller, and tell me what the results are.

How to safely removeObserver (Swift)

I have added an observer
override func viewDidLoad()
{
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector:"selector name", name: "observer name", object:nil)
...
}
When removing observer in deinit,
deinit
{
NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
}
the app sometimes crashes:
Terminating app due to uncaught exception 'NSRangeException', reason:
'Cannot remove an observer "class"
for the key path "some string" from
NSNotificationCenter because it is not registered as an
observer.
So I am trying to add do/catch
deinit
{
do{
try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
}catch{}
}
But I get a warning:
catch block is unreachable because no errors are thrown in do block
And the app crashes
and when I am adding a try
deinit
{
do{
try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
}catch{}
}
I get this warning:
no calls to throwing functions occur within try expresion
And the app crashes
How should that be done?
If you support iOS Versions by 9.0 you don't need to remove observers by yourself in your deinit method.
Taken from the documentation
In OS X 10.11 and iOS 9.0 NSNotificationCenter and
NSDistributedNotificationCenter will no longer send notifications to
registered observers that may be deallocated.
https://useyourloaf.com/blog/unregistering-nsnotificationcenter-observers-in-ios-9/
I think you should use code
NSNotificationCenter.defaultCenter().removeObserver(self)
Explain:
You have mistake here: You are using NSNotification & NSNotificationCenter so you have to using this code above to remove observe.
you have use code for KVO to remove observer so it will wrong.
More detail you can read at here. Key-Value-Observing

NSNotification Random Like unrecognized exception

I am trying to use NSNotification to communicate between two swift class. I don't know what am I doing wrong but where other notifications work fine, one of them keeps giving unrecognized selector sent to instance exception randomly. By randomly I mean that each time I execute that code exception is same but class reference is different like __CALayer, __NSArray, __NSSet etc. where I even do not use those classes directly. Any help?
Here is observer class init method:
override init() {
super.init()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "downloadChapter:", name: "downloadListNotification", object: DisplayMangaViewController.self)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "downloadChapter:", name: "downloadListNotification", object: DownloadRequestListViewController.self)
}
and the one I post notification inside :
let userInfo = ["downloadList" : self.selectedChapters , "mangaName" : self.obtainedMangaName]
let notification = NSNotification(name: "downloadListNotification", object: DownloadRequestListViewController.self, userInfo: userInfo as [NSObject : AnyObject])
NSNotificationCenter.defaultCenter().postNotification(notification)
Here is one example exception:
2015-09-05 19:49:45.598 TurkİşManga[12708:58814] -[__NSArrayM
downloadChapter:]: unrecognized selector sent to instance
0x7fbf9c80dd90 2015-09-05 19:49:45.600 TurkİşManga[12708:58814] ***
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSArrayM downloadChapter:]:
unrecognized selector sent to instance 0x7fbf9c80dd90'
And also here is the draft of downloadChapter method :
func downloadChapter(notification : NSNotification){}
Apparently my observer class gets deallocated and thus when notification posted there would any observer. So before posting any notification, creating an instance from observer class has solved the problem. Thanks.

UITextFieldView markedTextRange crash on iOS4?

My apps use UITextFieldView to receive input method from user and work fine on iOS6/iOS7. and I am using the following code to prevent user input chinese/japanese/something like that. Method to detect the real input words:
-(void)textFieldChanged:(UITextField *)textField
//crash here if device iOS version at 4.3
UITextRange *selectRange = [textField markedTextRange];
if (selectRange == nil)
//get word to do something...
Crash log :
2013-11-20 12:35:09.480 [My app][203:607]-[UITextField markedTextRange]: unrecognized selector sent to instance 0x287e270
2013-11-20 12:35:09.480 [My app][203:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITextField markedTextRange]: unrecognized selector sent to instance 0x287e270'

Resources