Adding observers - ios

I've added observers like the below
NotificationCenter.default.addObserver(self, selector:#selector(handleCourseCompleted(_:)), name: NSNotification.Name ("com.course.completed"), object: nil)
Is this how to remove them
deinit {
NotificationCenter.default.removeObserver(self)
}

If your app doesn't run on iOS 8 or earlier, there is no need to remove the observer at all. The notification center has an ARC-weak reference to it, and nothing bad will happen after self goes out of existence.

Related

Setting the queue is calling the observer?

I am making a music player, and for some reason when I add the notification center observer and set the queue and play the song it gets called twice. I commented out the play method and it's only called once. I'm not sure how to fix this or whether this is the issue.
didLoad
NotificationCenter.default.addObserver(self, selector: #selector(change), name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: nil)
musicPlayer.beginGeneratingPlaybackNotifications()
change function
#objc func change() {
print(musicPlayer.nowPlayingItem?.title) //called twice
}
function to queue and play
musicPlayer.setQueue(with: queueArr)
musicPlayer.play()

How to check that user is back from Settings

I am sending local notifications to my users, and I want to show the relevant title on the notification settings button.
If local notifications are off, this title should be "Notifications: off", and if local notifications are on, this title should be something like "Preferences".
Right now I'm checking this in viewDidLoad and viewDidAppear, and it works.
if UIApplication.sharedApplication().currentUserNotificationSettings()?.types.rawValue == 0 {
//the first title
} else {
//the second title
}
Except one case. If my user is changing notifications in the phone settings from "on" to "off" or vice versa, and after that he is back — the title is not changing (because this viewController already loaded and did appear).
How could I check that user is back from the Settings?
You can observe this notification when your app is come to foreground from inactive, the selector will be called everytime your app is opened again from background:
Put in viewDidLoad:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.reloadData), name: UIApplicationWillEnterForegroundNotification, object: UIApplication.sharedApplication())
Put in viewDidDissapear or deinit:
NSNotificationCenter.defaultCenter().removeObserver(self)
Swift 5.5:
NotificationCenter.default.addObserver(
self,
selector: #selector(yourFunction),
name: UIApplication.willEnterForegroundNotification,
object: UIApplication.shared
)
And:
deinit {
NotificationCenter.default.removeObserver(self)
}

swift AVPlayerItemDidPlayToEndTimeNotification not work

I create a class named DecryptAudioPlayer,it inherit NSObject,this class refrenced a AVPlayer,and observe the notice AVPlayerItemDidPlayToEndTimeNotification when init.like below:
override init() {
super.init()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.playToEnd(_:)), name: AVPlayerItemDidPlayToEndTimeNotification, object: nil)
}
and i have the method:
func playToEnd(notification:NSNotification) {
Log.printLog("notification:\(notification)")
}
but sometimes the player's ower can't recived the AVPlayerItemDidPlayToEndTimeNotification,i am very confused.it seems the AVPlayerItem may don't post AVPlayerItemDidPlayToEndTimeNotification when its end time ,who can tell me why?
I can get the stalled notification to solve the problem. So the question could be put down for a while.

Stop method's execution - Swift

When my watchKit app goes to background it fires the delegate method applicationWillResignActive. Method documentation says it can be used to pause ongoing tasks.
I have an ongoing method that i want to be stopped or broken by the use of the external method. How do i do that?
Example
func method1(){
// performing some actions
}
func breakMethod1(){
// running this method can stop (break) the execution of method1
}
This is, of course, assuming that your app has been architected so that breakMethod1() will definitely cancel the action occurring in method1().
You should set up an observer for an NSNotification at the beginning of method1() like so:
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self, selector: "breakMethod1", name: UIApplicationWillResignActiveNotification, object: nil)
And for the sake of cleanup, you should also remove this observer after it's been triggered like so:
notificationCenter.removeObserver(self, name: UIApplicationWillResignActiveNotification, object: nil)

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

Resources