Contents
Chào bạn đến với Fx Studio. Bài viết này sẽ trình bày về chủ đề “Sign in with Apple” trong iOS và cách sử dụng nó.
Chuẩn bị
- Xcode 11.0
- iOS 13.0
- Swift 5.1
Về chuẩn bị, bạn phải sử dụng các công cụ và OS mới nhất. Tính năng này được sử dụng bắt đầu với iOS 13. Nên bạn hãy đảm bảo rằng các settings trong iOS Project và Account đúng như vậy. Về demo thì không quá cầu kì, chỉ cần 1 UIViewController là okay rồi. Còn bây giời thì …
Bắt đầu thôi!
1. Giới thiệu
1.1. Bắt đầu
Trong sự kiện WWDC 2019, Apple đã giới thiệu một login service mới tập trung vào sự bảo mật và tính riêng tư, được gọi là Sign in with Apple. Tại thời điểm đó, Apple có nói rằng nếu một app iOS sử dụng third-party login service thì bắt buộc sẽ phải sử dụng thêm Sign in with Apple.
Câu chuyện nếu đơn giản như vậy thì không có bài viết này rồi. Một lý do được đưa ra là như thế này:
Các app mới submit lên App Store cũng như các app hiện tại và các bản update bắt buộc phải tuân thủ guildline Sign in with Apple. Áp dụng kể từ tháng 4 năm 2020.
Chi tiết ở đây : https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple . (Ngày 12-09-2019, guildline chính thức về việc sử dụng Sign in with Apple đã được đưa ra.)
Các app đang sử dụng các login service của các third-party, mạng xã hội (như Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with LinkedIn, Login with Amazon hoặc WeChat Login) để xác thực tài khoản người dùng thì phải cung cấp thêm lựa chọn tương đương Sign in with Apple. Tài khoản người dùng (user’s primary account) được hiểu là tài khoản được tạo để xác thực, đăng nhập và truy cập các tính năng và các dịch vụ.
Như vậy, bạn có muốn hay không muốn thì cũng phải có tính năng này trong ứng dụng của bạn.
1.2. Lưu ý
Không cần implement Sign in with Apple trong các trường hợp sau:
- Các ứng dụng sử dụng hệ thống đăng nhập internal riêng của một công ty, tập đoàn để đăng nhập.
- Ứng dụng thuộc lĩnh vực giáo dục, doanh nghiệp mà yêu cầu người dùng đăng nhập bằng một tài khoản giáo dục, doanh nghiệp đã tồn tại sẵn.
- Ứng dụng được hỗ trợ bởi chính phủ, tổ chức sử dụng hệ thống xác thực công dân để xác minh bằng các hệ thống quản lý công dân, căn cước, ID điện tử
- Các ứng dụng là client dịch vụ cho một bên thứ 3 cụ thể, yêu cầu người dùng đăng nhập để có thể truy cập, sử dụng content, media của bên thứ 3 đó.
1.3. Lợi ích
Sign in with Apple là cách thức giúp người dùng có thể đăng ký, đăng nhập tài khoản và sử dụng app, website của bạn. Apple hứa hẹn rằng đây là một login service thân thiện, riêng tư, nhanh và bảo mật.
2. Cài đặt
Tạo mới 1 project hoặc sử dụng project hiện tại cũng được. Tuy nhiên cần xác định được Deployment iOS SDK 13.0 (trở lên).
2.1. Capability
Để implement tính năng này, điều đầu tiên chúng ta cần làm đó là thêm mới capability
. Thêm nó như sau:
Bằng cách click vào App target > Signing & Capabilities tab > click + Capability > double click vào “Sign in with Apple“.
2.2. Button
Đầu tiên, bạn không cần quá lo lắng nhiều. Apple đã support bạn tận răng rồi. Kể cả việc hiển thị cái button phục vụ cho “Sign in with Apple” này.
Tất nhiên là phải khai báo thư viện trước.
import AuthenticationServices
Class ASAuthorizationAppleIDButton
có UI sẵn cho việc Sign in with Apple. Mở file ViewController nào đó và tại chỗ nào đó cũng được. Bạn thêm đoạn code sau:
let button = ASAuthorizationAppleIDButton() button.center = view.center view.addSubview(button)
Build project và xem kết quả nào!
EZ Game! mọi thứ từ UI, font chữ, màu sắc thì Apple đã làm hết cho chúng ta rồi. Tuy nhiên, nếu bạn cần chỉnh thêm xí cho phù hợp với UI ứng dụng thì cũng được.
2.3. Custom Button
Bạn cần xem qua về hướng dẫn cho việc custom button này của Apple. Link này viết ở đây. Theo đó thì bạn có thể:
- Custom được kích thước
- Tuỳ chọn được
style
màu sắc. Mà cũng có 2 màu đen và trắng thôi. - Corner radius
- Thay cái title như
Sign in
haySign up
… Cũng cho phép vài mẫu có sẵn - Hoặc chỉ còn 1 cái logo của Apple thôi
Như chúng ta có thể thấy, UI của button không thể can thiệp nhiều được. Vì vậy để đồng bộ UI với các login button của các login service khác, hãy layout login button của Apple trước, từ đó xác định font size phù hợp cho các login button khác.
Ví dụ code 1 chút
let signInAppleButton = ASAuthorizationAppleIDButton(type: .default, style: .black) let frame = CGRect(x: 0, y: 0, width: 300, height: 100) signInAppleButton.frame = frame signInAppleButton.center = view.center view.addSubview(signInAppleButton)
Kết quả như sau:
Để thay đổi theo các chế độ Light hay Dark Mode thì bạn phải tự cài đặt cho nó, vì button này không hỗ trợ việc tự thay đổi. Tham khảo code sau:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) let hasUserInterfaceStyleChanged = traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) if hasUserInterfaceStyleChanged { setupProviderLoginView() } } func setupProviderLoginView() { // Remove the old button from container switch traitCollection.userInterfaceStyle { case .dark: authorizationButton = ASAuthorizationAppleIDButton(type: .default, style: .white) default: authorizationButton = ASAuthorizationAppleIDButton(type: .default, style: .black) } // Replace it with a new one we just created ... }
2.4. Action
Mọi việc setup hiển thị cho cái nút đó đã OKE rồi. Bạn chuyển sang phần sự kiện cho nó. Đáng buồn thay, ASAuthorizationAppleIDButton
, chỉ là một view bình thường. Nên bạn phải tiến hành thêm sự kiện cho nó.
- Đầu tiên tạo 1 function
@objc private func handleLoginWithApple() { //... }
- Add Target cho button
signInAppleButton.addTarget(self, action: #selector(handleLoginWithApple), for: .touchUpInside)
Chuyển sang phần quan trọng nhất của cả bài thôi!
3. Sign in with Apple
3.1. Request
Cũng như trên, Apple cũng đã nhiệt tình support cho chúng ta thêm nhiều thứ nữa rồi. Công việc chúng ta bây giờ là khai báo và sử dụng. Bắt đầu với việc tạo request.
let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email]
Tạo ASAuthorizationAppleIDRequest
từ ASAuthorizationAppleIDProvider
. Quan trong nhất chỗ cung cấp scope
cho nó. Và các công việc khó thì Apple cũng handle luôn cho chúng ta.
Giờ tạo ra một ViewController để cho người dùng đăng nhập thông tin vào. Bạn tiếp tục với đoạn code sau:
let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.presentationContextProvider = self authorizationController.performRequests()
Trong đó:
ASAuthorizationController
là controller handle việc đăng nhập. Tham số cần truyền vào làrequest
presentationContextProvider
là xác địnhwindow
để present Controller đóperformRequests()
tiến hành đăng nhập
Bạn tiến hành implement protocol sau ASAuthorizationControllerPresentationContextProviding
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { return self.view.window! }
Để đảm bảo cho cái window mà controller kia bám víu vào. Okay sang phần handle dữ liệu nhận được thôi.
3.2. Handle
Mọi thứ, bạn lại không cần quan tâm và Apple trả về cho bạn 2 function để xử lý thành công hoặc thất bại. Tiến hành implement protocol sau ASAuthorizationControllerDelegate
- Thành công
- Chúng ta sẽ lấy một số thông tin cần thiết
- Bạn tự tìm hiểu thêm để sử dụng được đầy đủ hết dữ liệu nhận được
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential { guard let appleIDToken = appleIDCredential.identityToken else { print("Unable to fetch identity token") return } guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else { print("Unable to serialize token string from data: \(appleIDToken.debugDescription)") return } let userIdentifier = appleIDCredential.user let fullName = appleIDCredential.fullName let email = appleIDCredential.email ?? "n/a" print(idTokenString) print(userIdentifier) print(fullName) print(email) } }
- Thất bại
- Tuỳ ý bạn muốn xử lý như thế nào.
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // Handle error. guard let error = error as? ASAuthorizationError else { return } switch error.code { case .canceled: print("Canceled") case .unknown: print("Unknown") case .invalidResponse: print("Invalid Respone") case .notHandled: print("Not handled") case .failed: print("Failed") @unknown default: print("Default") } }
4. Các trường hợp xảy ra
Giờ sang phần sử dụng nó như thế nào. Và một số lưu ý khi sử dụng.
4.1. Không có Apple ID
Nếu như device của bạn không có Apple ID thì delegate
sẽ call method authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error)
với error trả về ASAuthorizationErrorUnknown
.
Với trường hợp này, chúng ta không cần làm gì hết, iOS sẽ tự hiển thị alert thông báo và hướng dẫn người dùng đăng nhập Apple ID.
Để đăng nhập vào một app hoặc website sử dụng tính năng Sign in with Apple, chúng ta cần có:
- Một Apple ID có bật xác thực 2 bước.
- Đăng nhập iCloud sử dụng Apple ID đó trên device của Apple.
Chi tiết xem How to use Sign in with Apple.
4.2. Lần đầu sử dụng
Khi lần đầu đăng nhập thì hiển thị một màn hình với một số thông tin vui vui như sau:
- Nếu người dùng tap vào button Cancel thì error return sẽ là
ASAuthorizationErrorCanceled
. - Còn nếu tap vào Continue thì hệ thống sẽ chuyển đến giao diện đăng nhập tiếp theo.
Trên simulator, mỗi lần tap vào button Sign in with Apple đều sẽ luôn được tính là lần đầu tiên. Vậy nên chúng ta sẽ thấy giao diện này hiển thị liên tục.
Tuỳ thuộc vào scope
được khai báo ở request
mà chúng ta sẽ lấy được những thông tin như thế nào. Trường hợp dưới đây là cho trên thiết bị thật và full scope
Các lần đăng nhập tiếp theo thì chỉ hiển thị đơn giản như sau
Vì vậy, các thông tin người dùng mà chúng ta lấy được như
- user
- name
- …
Thì một số thông tin sẽ không lấy được ở lần đăng nhập thứ 2 và các lần sau lần đầu tiên. Do đó, bạn cần phải lưu trữ chúng để sử dụng.
5. Hide my email
Đối với email, ngoài email chính, người dùng còn có thể chọn bất kỳ email nào liên kết đến tài khoản Apple đó. Hoặc người dùng có thể ẩn email của mình bằng việc chọn option Hide my email.
Với option này, Apple sẽ tạo một địa chỉ email nặc danh (anonymous) cho người dùng (một email có dạng một chuỗi random với đuôi @privaterelay.appleid.com).
Email trên chỉ nhận được 1 lần duy nhất lúc đăng nhập lần đầu tiên mà thôi.
Các email anonymous này (private relay email addresses) có một số đặc điểm sau:
- Có đuôi
@privaterelay.appleid.com
- Các email gửi đến sẽ được chuyển hướng đến một trong các email đã được xác thực của Apple ID đó (một kiểu không public địa chỉ email nhưng bạn vẫn nhận được các email khi cần thiết).
- Các app của cùng một development team sẽ dùng chung một email private này. App của development team khác sẽ có một email private khác.
- Các email này luôn được active, bạn có thể truy cập bất kỳ lúc nào để gửi, nhận email, ngay cả khi app đó active hay không active, được cài hay đã gỡ bỏ.
Sau khi share một private relay email với app, người dùng có thể tìm, xem lại và quản lý chúng bằng cách truy cập vào.
Settings > Apple ID > Password & Security > Apple ID Logins
Tất cả các anonymous email được cấp sẽ được lưu trữ ở đây.
OKAY! Qua trên, mình đã trình bày những thứ cần thiết để bạn tiến hành Sign in with Apple trong project của bạn. Bạn nên ghi nhớ các lưu ý & chú ý khi sử dụng tính năng này. Bạn có thể checkout mã nguồn tại đây.
Tạm kết
- Cài đặt Sign in with Apple
- Custom Button
- Xử lý thông tin
- Cách sử dụng tính năng & các lưu ý
Nếu có góp ý gì, thì bạn có thể để lại reply hoặc send contact cho mình. Còn nếu thấy hay thì hãy share cho nhiều người khác cùng đọc.
Cảm ơn bạn đã đọc bài viết này!
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)