Trong Swift thì chúng ta có nhiều cách để truyền dữ liệu giữa các View, đó là Delegate, Key-Value Observing(KVO), Segue, NSNotification, Target-Action, Callbacks. Mỗi phương pháp đều có điểm mạnh và yếu, và mục đích của bài viết này là giới thiệu cho các bạn một trong những phương pháp trên, đó là NSNotification.
Đầu tiên, xin các bạn lưu ý một điểm là tuy phương pháp này có tên gọi là NSNotification, nhưng những gì chúng ta đang đọc không liên quan gì đến tính năng Push Notification cả, cùng một cái tên nhưng chức năng và cách sử dụng là hoàn toàn khác nhau.
Trong bài viết này, bạn sẽ học được 2 thứ. Đầu tiên, bạn sẽ hiểu được cách để "notify" tức là "thông báo" cho một view controller khác khi có một sự kiện ở bên View Controller hiện tại diển ra. Thứ hai là bạn sẽ nắm được điểm mạnh và điểm yếu của NSNotification.
UI Component
Đầu tiên chúng ta có 2 View Controller, tôi gọi chúng la FirstVC và SecondVC. Ở đây tôi mặc định các bạn đã biết cách nhúng UINavigationController và các thao tác cơ bản như kết nối IBOutlets và IBAction.
Cơ chế hoạt động ở đây sẽ là SecondVC sẽ thông báo cho FirstVC khi tôi thực hiện "notify", hay chính xác là thao tác "thông báo" tới FirstVC. Ví dụ dưới đây mô phỏng lại thao tác update profile trên Facebook hay Instagram.
Tưởng tượng 2 View Controller giống như một cặp đôi vậy, họ có smartphone (NSNotification Object) để nói chuyện với nhau, mỗi chiếc smartphone có 2 tính năng, đó là gửi và nhận tin nhắn (data). Cuối cùng là để kết nối tới thiết bị kia, họ cần phải có một liên kết riêng (secret key) và bên đầu dây bên kia có thể từ chối hoặc nhận kết nối.
Sau khi đã nắm được logic rồi thì chúng ta bắt tay vào code thôi !
Đầu tien hãy tìm một chỗ để lưu giữ secret key, bạn có thể tạo một file Swift mới hoặc chỉ cần tạo một View Controller bên ngoài như sau:
import UIKit
let myNotificationKey = "com.bobthedeveloper.notificationKey"
class SecondVC: UIViewController {}
myNotificationKey
sẽ được sử dụng để kết nối các smartphone với nhau. Bạn cũng có thể tạo nhiều key hơn nữa tùy theo mục đích của mình.
Bây giờ là lúc đưa smartphone vào, chúng ta gọi đây là một Observer
.Observer sẽ có 4 tham số, chúng ta đặt tham số đầu tiên là self, tức là chính smartphone của chúng ta, ở đây được thể hiện là SecondVC. Tiếp theo tại Selector
, là hành động mà bạn muốn notify tới smartphone kia, tức là FirstVC. Thứ ba, chúng ta truyền vào name
biến secret code. Cuối cùng là người nhận notify, object
sẽ là FirstVC
. Tuy nhiên tạm thời lúc này chúng ta sẽ để là nil
class SecondVC: UIViewController {
@IBOutlet weak var secondVCLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(doThisWhenNotify),
name: NSNotification.Name(rawValue: myNotificationKey),
object: nil)
}
func doThisWhenNotify() { print("I've sent a spark!") }
}
Sau đó chúng ta khởi tạo action khi button được ấn
@IBAction func tabToNotifyBack(_ sender: UIButton) {
NotificationCenter.default.post(name: Notification.Name(rawValue: myNotificationKey), object: self)
secondVCLabel.text = "Notification Completed!😜"
}
Trong tình huống này, object tham chiếu tới người gửi, SecondVC đang thông báo tới chính nó, vậy chúng ta truyền vào self.
Ở đay FirstVC vẫn chưa đăng ký mọt observer nào cả, do vậy mọi tác động bên này đều sẽ ko ảnh hưởng. Như tôi đã nói ở trên thì người nhận có thể nhâc máy hoặc mặc kệ khi có cuộc gọi tới. Ở iOs, chúng ta gọi đó là "loose coupling".
Tiếp theo, tại FirstVC chúng ta cập nhật đoạn code như sau để nó có thể nhận "cuộc gọi tới" :
import UIKit
class FirstVC: UIViewController {
@IBOutlet weak var FirstVCLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(doSomethingAfterNotified),
name: NSNotification.Name(rawValue: myNotificationKey),
object: nil) }
func doSomethingAfterNotified() {
print("I've been notified")
FirstVCLabel.text = "Damn, I feel your spark 😱"
}
}
Kết quả nhận được như sau:
Truyền dữ liệu
Như vậy là bạn đã biết cách truyền thông báo (notify), tiếp theo chúng ta sẽ nghiên cứu cách truyền dữ liệu theo luồng notify đã thiết lập ở trên
Tại SecondVC, chúng ta sửa code lại như sau:
// Pass Spark
NotificationCenter.default.post(name: NSNotification.Name(rawValue: myNotificationKey), object: nil)
Sau đó tại FirstVC, chúng ta thêm đoạn code sau tại hàm viewDidLoad() :
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: myNotificationKey),
object: nil,
queue: nil,
using:catchNotification)
Như vậy là mỗi khi button từ SecondVC được ấn, phương thức catchNotification sẽ tự động chuyển đối tượng userInfo từ SecondVC sang FirstVC. Rất đơn giản !
Kết quả cuối cùng chúng ta có là như sau:
Lời kết
Như vậy là qua bài viết trên, tôi đã giới thiệu cho các bạn một cách thức đơn giản để truyền dữ liệu trong iOS là NSNotification, bên cạnh Delegate. Vậy khi nào nên dùng Notification, khi nào nên dùng Delegate, phương pháp nào tối ưu hơn, chúng ta sẽ cùng tìm hiểu điều này trong bài viết tới của tôi: So sánh Delegate và Notification nhé.
Khóa học lập trình di động tại Techmaster:
Để cài đặt MacOSX lên phần cứng không phải Apple liên hệ chuyên gia cài Hackintosh:
- Nguyễn Minh Sơn: 01287065634
- Huỳnh Minh Sơn: 0936225565
- Website: caidatmacos.com
Bình luận