Nhiều ứng dụng có tính năng tự động đăng xuất bạn sau một khoảng thời gian không hoạt động. Tuy nhiên, một số ứng dụng này đăng xuất bạn dựa trên API không hoạt động, trong khi những ứng dụng khác triển khai bộ hẹn giờ đăng xuất bằng cách ghi đè các điều khiển UIView. Trong bài viết này, chúng ta sẽ khám phá một cách tốt hơn để đạt được hành vi này bằng cách sử dụng phương pháp hitTest. Và một số ứng dụng đăng xuất bạn dựa trên chênh lệch thời gian giữa lần đăng nhập cuối cùng / lệnh gọi API với thời gian hiện tại. Vấn đề với cách tiếp cận cuối cùng là bạn có thể giữ cho phiên của mình liên tục hoạt động bằng cách đặt thủ công thời gian của bạn trên thiết bị thành điểm thời gian đăng nhập.
Vấn đề với cách tiếp cận đầu tiên là một số người dùng có thể bị đăng xuất ngay cả khi họ chỉ cuộn qua nội dung và không thực hiện bất kỳ yêu cầu nào đối với chương trình phụ trợ. Hãy tưởng tượng một người dùng đọc các điều khoản và điều kiện của một sản phẩm ngân hàng nhất định trước khi mở và anh ta đang bị đăng xuất. Chúng tôi chắc chắn muốn tránh điều này.
Vấn đề với cách tiếp cận thứ hai là có thể khó triển khai tính năng đăng xuất không hoạt động trong cơ sở mã hiện có, đặc biệt nếu ứng dụng có cơ sở mã lớn với chế độ xem tùy chỉnh.
Đây là nơi phương pháp hitTest có thể rất hữu ích.
Chúng ta có thể sử dụng hack với phương pháp hitTest để khắc phục các sự cố được liệt kê.
Giả sử rằng chúng ta đã có phiên bản triển khai của một lớp chịu trách nhiệm theo dõi thời gian hoạt động của người dùng.
Chúng tôi sẽ thể hiện nó bằng API sau:
protocol IUserActivity { func resetInactiveTime() }
extension UIWindow { open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { userActivity.resetInactiveTime() return super.hitTest(point, with: event) } }
Và thế là xong! Giờ đây, phương pháp này sẽ được kích hoạt trên mọi sự kiện tương tác mà người dùng thực hiện trên màn hình, chẳng hạn như ghi âm, cuộn và các hoạt động cử chỉ khác.
Bạn cũng có thể khai báo một lớp con của UIWindow và ghi đè phương thức hitTest trong đó.
Sự kiện chạm trong iOS thường bắt nguồn từ tương tác của người dùng với màn hình cảm ứng của thiết bị.
Khi người dùng chạm vào màn hình, phần cứng sẽ phát hiện thao tác chạm và tạo luồng dữ liệu cảm ứng thô bao gồm thông tin như vị trí, áp lực và thời lượng chạm.
Dữ liệu cảm ứng thô này sau đó được hệ điều hành xử lý và chuyển đổi thành các sự kiện cảm ứng cấp cao mà UIKit có thể xử lý. Hệ điều hành xác định đối tượng UIWindow mà sự kiện chạm tương ứng dựa trên vị trí chạm và cấu trúc phân cấp dạng xem, sau đó gửi sự kiện chạm tới đối tượng UIResponder của đối tượng đó để xử lý.
Khi một sự kiện chạm xảy ra, hệ điều hành iOS sử dụng thuật toán thử nghiệm lần truy cập để xác định đối tượng UIView hoặc UIWindow mà sự kiện chạm tương ứng.
Thuật toán thử nghiệm lượt truy cập bắt đầu ở đối tượng UIWindow cấp cao nhất và kiểm tra đệ quy từng chế độ xem con trong phân cấp chế độ xem cho đến khi tìm thấy chế độ xem sâu nhất có chứa điểm tiếp xúc. Nó thực hiện điều này bằng cách kiểm tra xem điểm tiếp xúc có nằm trong khung của mỗi chế độ xem con hay không.
Thử nghiệm lần truy cập sử dụng thuật toán duyệt theo thứ tự ngược theo thứ tự trước theo chiều sâu. Nói cách khác, thuật toán truy cập vào nút gốc trước và sau đó duyệt qua các cây con của nó từ chỉ số cao hơn đến chỉ số thấp hơn.
Loại truyền tải này cho phép giảm số lần lặp truyền tải và dừng quá trình tìm kiếm sau khi tìm thấy chế độ xem con cháu sâu nhất đầu tiên có chứa điểm tiếp xúc.
Điều này có thể xảy ra vì một chế độ xem phụ luôn được hiển thị trước chế độ xem giám sát của nó và chế độ xem anh chị em luôn được hiển thị trước chế độ xem anh chị em của nó với chỉ số thấp hơn trong mảng chế độ xem phụ. Khi nhiều chế độ xem chồng chéo chứa một điểm cụ thể, chế độ xem sâu nhất trong cây con ngoài cùng bên phải sẽ là chế độ xem ngoài cùng (1) .
Như chúng ta có thể thấy, thuật toán di chuyển ngang luôn bắt đầu từ đối tượng UIWindow, bất kể người dùng tương tác với chế độ xem hoặc điều khiển nào.
Và chúng tôi chắc chắn có thể sử dụng điều này cho mục đích của mình chỉ bằng cách chặn các sự kiện này trong phương thức hitTest của lớp UIWindow!
Đó là nó! Hãy cho tôi biết những gì bạn nghĩ trong các ý kiến dưới đây.