Một số kỹ thuật về Event Kit trong lập trình iOS
Request Permission EvenKit là 1 framework giúp chúng ta truy cập và sử dụng Calendar và Reminder của người dùng. Kỹ thuật đầu tiên là cách xin quyền user truy cập vào Calendar và Reminder (Request Permission) cũng như là cách kiểm tra người dùng có cho phép chúng ta truy cập vào ...
Request Permission
EvenKit là 1 framework giúp chúng ta truy cập và sử dụng Calendar và Reminder của người dùng. Kỹ thuật đầu tiên là cách xin quyền user truy cập vào Calendar và Reminder (Request Permission) cũng như là cách kiểm tra người dùng có cho phép chúng ta truy cập vào chúng hay không.
Đầu tiên, chúng ta sẽ khởi tạo biến eventStore có kiểu EKEventStore. EKEventStore là trung tâm trong EventKit, cho phép chúng ta đọc hoặc ghi vào Calendar và Reminder của người dùng.
1 2 3 |
let eventStore = EKEventStore() |
Tiếp theo, chúng ta sẽ kiểm tra quyền hạn App có được phép truy cập vào Calendar hay không. Điều này cực kỳ quan trọng, ảnh hưởng trực tiếp đến sự “sống còn” của App, cần thực hiện mỗi khi màn hình hiện lên (viewDidAppear/ viewWillAppear).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) checkCalendarAuthorizationStatus() } func checkCalendarAuthorizationStatus() { let status = EKEventStore.authorizationStatus(for: .event) switch (status) { case .notDetermined: break // Lần đầu vào app case .authorized: break // User đã cho phép sử dụng case .restricted, .denied: break // User chưa cho phép/ bỏ qua } } |
Công việc tiếp theo là tạo ra 1 func requestAccessToCalendar và sau đó đưa vào case .notDetermined
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
func requestAccessToCalendar() { eventStore.requestAccess(to: .event) { (isAllowed, error) in if error != nil { print(error?.localizedDescription) } else { if isAllowed { print("User Allowed") } else { print("User Denied") } } } } |
Ở bước tiếp theo, chúng ta cần 1 mảng chứa tất các các event của User
1 2 3 |
var calendars: [EKCalendar] = [EKCalendar]() |
Và sau đó, tạo func để load tất cả dữ liệu của User vào mảng
1 2 3 4 5 6 |
func loadCalendars() { self.calendars = eventStore.calendars(for: .event) print(calendars) } |
Tiếp theo, chúng ta sẽ bỏ func trên vào case authorized. Sau khi thiếp lập tất cả các dòng lệnh trên, chúng ta sẽ run App và chờ xem điều gì sẽ xảy ra.
Chúng ta sẽ quay lại file info.plist và xét quyền vào cho app của chúng ta là xong.
Lấy danh sách các Event
Chúng ta sẽ tiếp tục lấy các event từ các danh muc lấy được và đổ chúng vào UITableView.
Đầu tiên, chúng ta tạo UITableView và đổ các danh mục vào trước.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
extension ViewController : UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return calendars.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let event = calendars[indexPath.row] cell.textLabel?.text = event.title return cell } } |
Chúng ta cần tạo thêm 1 ViewController nữa, và đặt Storyboard ID cho nó là EventVC.
Bước tiếp theo, chúng ta sẽ bắt sự kiện User chọn vào 1 cell nào đó, và chuyển màn hình và hiển thị các event thuộc calendar đó (Calendar, US Holidays, Birthdays).
1 2 3 4 5 6 7 8 9 10 11 |
extension ViewController : UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: false) guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "EventVC") as? EventViewController else {return} vc.calendar = calendars[indexPath.row] self.navigationController?.pushViewController(vc, animated: true) } } |
Để có thể gọi được vc.calendar, cần khởi tạo nó ở EventViewController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
var calendar : EKCalendar? func loadEvents(calendar: EKCalendar) { // DateFormatter: dùng để chuyển kiểu String sang kiểu Date và ngược lại let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" // Chúng ta chỉ muốn lấy các event nằm trong khoảng thời gian nào đó, chúng không phải load lên hết let startDate = dateFormatter.date(from: "2016-01-01") let endDate = dateFormatter.date(from: "2016-12-31") if let startDate = startDate, let endDate = endDate { let eventStore = EKEventStore() // Dùng eventStore để tạo và thiết lập thuộc tính cho NSPredicate let eventsPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: [calendar]) // Dùng NSPredicate vừa thiết lập để tìm ra những event phù hợp với điều kiện đưa ra self.events = eventStore.events(matching: eventsPredicate).sorted(){ (e1: EKEvent, e2: EKEvent) -> Bool in return e1.startDate.compare(e2.startDate) == ComparisonResult.orderedAscending } print(events) self.tableView.reloadData() } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) loadEvents(calendar: calendar!) } |
Tới bước này, chúng ta đã lấy được tất cả sự kiện từ đầu năm 2016 đến cuối năm 2016. Và công việc còn lại của các bạn chỉ là từ dữ liệu nhận được mà đổ chúng vào tableview là xong.
Chúc các bạn thành công!!!
Tạo Calendar
Đầu tiên, chúng ta cần tạo thêm 1 màn hình và 1 file ViewController nữa, để đơn giản chúng ta chỉ cần 1 textfield và 1 button là xong. Và công việc lại lẩn quẩn là ánh xạ, đặt tên. Để quy chuẩn lại cách đặt tên của các bạn trong bài viết này, mình sẽ đặt tên như sau:
- NewCalendarViewController
- calendarTitleTextField
-
addNewCalendarActionButton
Ở addNewCalendarActionButton, chúng ta sẽ:
- Khởi tạo biến eventStore có kiểu dữ liệu là EKEventStore
- Khởi tạo biến newCalendar có kiểu dữ liệu là EKCalendar
- Xét title cho biến newCalendar bằng với nội dung của user nhập vào
- Xét source cho newCalendar
- Save Calendar
- Xử lý nếu có lỗi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
@IBAction func addNewCalendarActionButton(_ sender: AnyObject) { guard let calendarTitle:String = calendarTitleTextField.text else {return} if calendarTitle == "" { return } let eventStore = EKEventStore() let newCalendar = EKCalendar(for: .event, eventStore: eventStore) newCalendar.title = calendarTitle // Lấy các source từ biến eventStore let sourcesInEventStore = eventStore.sources // Lọc ra những source có type là local, và chỉ lấy phần tử đầu tiên và add vào source của newCalendar newCalendar.source = sourcesInEventStore.filter{ (source: EKSource) -> Bool in source.sourceType.rawValue == EKSourceType.local.rawValue }.first! // Save Calendar vừa tạo do { try eventStore.saveCalendar(newCalendar, commit: true) let _ = self.navigationController?.popViewController(animated: true) } catch {
Có thể bạn quan tâm
0
|