J'apprends Swift 3 et j'essaie d'utiliser NSNotificationCenter
. Voici mon code:
func savePost(){
let postData = NSKeyedArchiver.archivedData(withRootObject: _loadedpost)
UserDefaults.standard().object(forKey: KEY_POST)
}
func loadPost(){
if let postData = UserDefaults.standard().object(forKey: KEY_POST) as? NSData{
if let postArray = NSKeyedUnarchiver.unarchiveObject(with: postData as Data) as? [Post]{
_loadedpost = postArray
}
}
//codeerror
NotificationCenter.default().post(NSNotification(name: "loadedPost" as NSNotification.Name, object: nil) as Notification)
}
et voici l'observateur:
override func viewDidLoad() {
super.viewDidLoad()
//codeerorr
NotificationCenter.default().addObserver(self, selector: Selector(("onPostLoaded")), name: "loadedPost", object: nil)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
Cela me donne toujours l'erreur "signal SIGBRT". Quand j'essaye de changer le nom dans l'observateur, ce n'est pas une erreur, mais évidemment, cela ne montre rien. Comment puis-je réparer ça?
Swift 3, et maintenant Swift 4, ont remplacé de nombreux API "typés de manière stricte" par struct
"types d'encapsuleurs", comme c'est le cas avec NotificationCenter. Les notifications sont maintenant identifiées par un struct Notfication.Name
plutôt que par String
. Pour plus de détails, consultez le guide maintenant hérité Guide de la migration vers Swift
Utilisation de Swift 2.2 :
// Define identifier
let notificationIdentifier: String = "NotificationIdentifier"
// Register to receive notification
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)
// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)
Utilisation de Swift 3 & 4 :
// Define identifier
let notificationName = Notification.Name("NotificationIdentifier")
// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)
// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)
// Stop listening notification
NotificationCenter.default.removeObserver(self, name: notificationName, object: nil)
Tous les types de notification système sont maintenant définis en tant que constantes statiques sur Notification.Name
; c'est-à-dire .UIApplicationDidFinishLaunching
, .UITextFieldTextDidChange
, etc.
Vous pouvez étendre Notification.Name
avec vos propres notifications personnalisées afin de rester cohérent avec les notifications système:
// Definition:
extension Notification.Name {
static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)
Swift 4.2 utilisation:
Identique à Swift 4, sauf que les noms des notifications système font maintenant partie de UIApplication. Donc, pour rester cohérent avec les notifications du système, vous pouvez étendre UIApplication
avec vos propres notifications personnalisées au lieu de Notification.Name:
// Definition:
UIApplication {
public static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: UIApplication.yourCustomNotificationName, object: nil)
Pour tous ceux qui luttent avec le sélecteur # dans Swift 3 ou Swift 4, voici un exemple de code complet:
// WE NEED A CLASS THAT SHOULD RECEIVE NOTIFICATIONS
class MyReceivingClass {
// ---------------------------------------------
// INIT -> GOOD PLACE FOR REGISTERING
// ---------------------------------------------
init() {
// WE REGISTER FOR SYSTEM NOTIFICATION (APP WILL RESIGN ACTIVE)
// Register without parameter
NotificationCenter.default.addObserver(self, selector: #selector(MyReceivingClass.handleNotification), name: .UIApplicationWillResignActive, object: nil)
// Register WITH parameter
NotificationCenter.default.addObserver(self, selector: #selector(MyReceivingClass.handle(withNotification:)), name: .UIApplicationWillResignActive, object: nil)
}
// ---------------------------------------------
// DE-INIT -> LAST OPTION FOR RE-REGISTERING
// ---------------------------------------------
deinit {
NotificationCenter.default.removeObserver(self)
}
// either "MyReceivingClass" must be a subclass of NSObject OR selector-methods MUST BE signed with '@objc'
// ---------------------------------------------
// HANDLE NOTIFICATION WITHOUT PARAMETER
// ---------------------------------------------
@objc func handleNotification() {
print("RECEIVED ANY NOTIFICATION")
}
// ---------------------------------------------
// HANDLE NOTIFICATION WITH PARAMETER
// ---------------------------------------------
@objc func handle(withNotification notification : NSNotification) {
print("RECEIVED SPECIFIC NOTIFICATION: \(notification)")
}
}
Dans cet exemple, nous essayons d'obtenir des POST à partir d'AppDelegate (ainsi, dans AppDelegate, implémentons ceci):
// ---------------------------------------------
// WHEN APP IS GOING TO BE INACTIVE
// ---------------------------------------------
func applicationWillResignActive(_ application: UIApplication) {
print("POSTING")
// Define identifiyer
let notificationName = Notification.Name.UIApplicationWillResignActive
// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)
}
Les notifications semblent avoir de nouveau changé (octobre 2016).
// Inscrivez-vous pour recevoir une notification
NotificationCenter.default.addObserver(self, selector: #selector(yourClass.yourMethod), name: NSNotification.Name(rawValue: "yourNotificatioName"), object: nil)
// Publier une notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)
Je pense que cela a encore changé.
Pour poster cela fonctionne dans Xcode 8.2.
NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)