Tích hợp iOS SDK
Hướng dẫn tích hợp CICReader iOS SDK, phiên bản 1.0.7. Viết bằng Swift; entry point là CESNfc.
Yêu cầu build
| Thông tin | Mô tả |
|---|---|
| Xcode | 16.0+ |
| Phiên bản iOS mục tiêu | 13+ |
Tích hợp
Thêm SDK framework vào target của bạn, sau đó thêm các pod sau:
pod 'OpenSSL-Universal', '~> 1.1.180'
pod 'PromisesSwift', '~> 2.4.0'Bật capability Near Field Communication Tag Reading, sau đó khai báo usage description và các application identifier ISO7816:
<key>NFCReaderUsageDescription</key>
<string>We would like to use NFC to scan NID chip</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
<string>A0000002472001</string>
<string>00000000000000</string>
</array>WARNING
Thiếu bất kỳ identifier nào trong ba ISO7816 identifier ở trên sẽ khiến việc đọc chip âm thầm thất bại trên bản build production, dù vẫn hoạt động ở bản debug. Xem Kiểm tra cấu hình IPA bên dưới.
Khởi tạo
let nfcConfig = CESNfcConfig(baseUrl: "<BASE_URL>",
enableCheckNfcData: true,
readTimeout: 60000,
writeTimeout: 60000)
let nfcReader = CESNfc(nfcConfig)
nfcReader.delegate = self // tùy chọn
nfcReader.displayMessageDelegate = self // tùy chọnTham số:
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
baseUrl | string | Có | — | Base URL cho các lệnh gọi API. |
enableCheckNfcData | bool | Không | true | Xác minh dữ liệu NFC với Cake RAR. |
readTimeout | int | Không | 60000 | Timeout đọc API tính bằng mili-giây. |
writeTimeout | int | Không | 60000 | Timeout ghi API tính bằng mili-giây. |
cacheScanStrategy | enum | Không | .NO_CACHE | Xem Tổng quan Mobile SDK § Cache khi server lỗi. |
sessionDelayConfig | CESSessionDelayConfig | Không | — | Thời gian chờ thử lại theo từng thiết bị. Xem bên dưới. |
Header tùy chỉnh
extension DemoViewController: CESNfcDelegate {
func provideHeaders() -> [String: String?] {
return [
"custom_header1": "value1",
"custom_header2": "value2"
]
}
}Thông báo hiển thị tùy chỉnh
Mỗi phương thức đều tùy chọn — chỉ override những thông báo bạn muốn thay đổi.
extension ViewController: CESNfcDisplayMessageDelegate {
func presentRequestPresentPassport() -> String { }
func presentAuthenticatingWithPassport(progress: Int) -> String { }
func presentReadingDataGroupProgress(dataGroup: DataGroupId, progress: Int) -> String { }
func presentError(error: CESNfcError) -> String { }
func presentSuccessfulRead() -> String { }
func presentStartVerifyData() -> String { }
func presentVerifyDataDone() -> String { }
}Đọc chip
Dùng MRZ — số CCCD 9 chữ số, ngày sinh, ngày hết hạn
Ném lỗi InvalidFullMRZKey khi bất kỳ đầu vào nào sai.
nfcReader.readNfc(
idCard: "xxxxxxxxx",
dayOfBirth: "901212",
expireDate: "301212",
accessToken: "<ACCESS_TOKEN>",
refId: "ref_00000001")
.then { result in
// result
}.catch { err in
// handle error
}| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
idCard | string | Có | — | 9 chữ số cuối của số CCCD. |
dayOfBirth | string | Có | — | Ngày sinh, định dạng yyMMdd. |
expireDate | string | Có | — | Ngày hết hạn của thẻ, định dạng yyMMdd. |
accessToken | string | Có | — | Access token của request. |
refId | string | Có | — | Reference ID của giao dịch cần xác minh. |
Dùng CAN — số CCCD 12 chữ số
Ném lỗi InvalidCANKey khi số sai.
nfcReader.readNfc(
docId: "001xxxxxxxxx",
accessToken: "<ACCESS_TOKEN>",
refId: "ref_00000001")
.then { result in
// result
}.catch { err in
// handle error
}| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
docId | string | Có | — | Số CCCD đầy đủ 12 chữ số. |
accessToken | string | Có | — | Access token của request. |
refId | string | Có | — | Reference ID của giao dịch cần xác minh. |
Kết quả
CESNfcResult mang theo các data group thô, cùng với các trường thông tin công dân đã phân tích khi enableCheckNfcData là true.
Dữ liệu chip
| Trường | Kiểu | Mô tả |
|---|---|---|
com | string | Thông tin phiên bản Unicode và danh sách các data group hiện có. Base64. |
sod | string | Dữ liệu SOD từ lần quét NFC. Base64. |
dg1 | string | Thông tin cơ bản của cá nhân — thông tin MRZ. Base64. |
dg2 | string | Ảnh khuôn mặt công dân đã mã hóa. Base64. |
dg13 | string | Thông tin liên quan đến công dân. Base64. |
dg14 | string | Dùng cho cơ chế truy cập EAC. Base64. |
dg15 | string | Public key, dùng cho Passive Authentication. Base64. |
cloneStatus | CESNfcVerdict | Clone status của thẻ. Xem Tổng quan Mobile SDK § Clone status. |
imageData | String? | Ảnh khuôn mặt được tính toán từ dữ liệu dg2. |
Trường thông tin công dân — lấy từ API
| Trường | Kiểu | Mô tả |
|---|---|---|
idCardNo | string | Số định danh của công dân. |
oldIdCardNumber | string | Số định danh cũ. |
fullName | string | Họ và tên đầy đủ. |
dateOfBirth | string | Ngày sinh. |
dateOfExpiry | string | Ngày hết hạn của thẻ. |
gender | string | Giới tính. |
nationality | string | Quốc tịch. |
ethnic | string | Dân tộc. |
religion | string | Tôn giáo. |
placeOfOrigin | string | Quê quán. |
residenceAddress | string | Nơi thường trú. |
personalSpecificIdentification | string | Đặc điểm nhận dạng cá nhân. |
dateOfIssuance | string | Ngày cấp thẻ. |
fatherName | string | Họ tên cha. |
motherName | string | Họ tên mẹ. |
spouseName | string | Họ tên vợ/chồng. |
faceImage | string | Ảnh khuôn mặt. Base64. |
isVerified | bool | Thẻ có được RAR xác minh hay không. |
verificationKey | string | Verification key — truyền giá trị này vào Xác minh NFC. |
requestId | string | Request ID của lần xác thực. |
iOS dùng idCardNo và residenceAddress, trong khi Flutter dùng citizenIdentify và placeOfResidence — cùng giá trị, khác tên gọi.
Event listener
// nfcReader.eventDelegate = self
public func nfcScanWillStart() -> Void { }
public func nfcScanDidEnd(isScanSuccess: Bool) -> Void { }
public func dataVerificationWillStart(isCacheHit: Bool) -> Void { }
public func dataVerificationDidEnd(isCacheHit: Bool) -> Void { }Khi bật cache và cache hit, nfcScanDidEnd sẽ không được gọi — hãy tự hiển thị giao diện xác minh của bạn từ dataVerificationWillStart:
public func dataVerificationWillStart(isCacheHit: Bool) -> Void {
if (isCacheHit) {
// show your UI for data verification here
} else {
// SDK shows its dialog and asks the user to scan as normal
}
}
public func dataVerificationDidEnd(isCacheHit: Bool) -> Void {
if (isCacheHit) {
// close your UI for data verification here
} else {
// SDK closes its own dialog
}
}Thời gian chờ thử lại
Mỗi CESNfcError.SessionOnGoing đi kèm một thời gian chờ khuyến nghị trước lần quét tiếp theo. SDK tự xử lý việc này; bạn có thể tinh chỉnh thời lượng ban đầu theo từng dòng máy.
CESNfcConfig(baseUrl: "<BASE_URL>",
sessionDelayConfig: CESSessionDelayConfig(
defaultDelayMs: 10000,
mappingDurations: [
DeviceModel.iPhone15ProMax.rawValue: 15000,
DeviceModel.iPhone7Plus.rawValue: 12000
])
)Xử lý lỗi
Lỗi được ném dưới dạng CESNfcError. Danh sách đầy đủ nằm ở Mã lỗi; những lỗi bạn sẽ gặp nhiều nhất:
| Trường | Kiểu | Mô tả |
|---|---|---|
NFCNotSupported | 600032 | NFC không được hỗ trợ trên thiết bị này. |
SessionOnGoing | 600101 | Một phiên đọc khác đang diễn ra. |
SystemResourceUnavailable | 600102 | Hệ thống NFC đang bận. |
UserCanceled | 600432 | Người dùng đã hủy. |
InvalidFullMRZKey | 600316 | Khóa MRZ không hợp lệ. |
InvalidCANKey | 600317 | Khóa CAN không hợp lệ. |
InvalidCardType | 600396 | Thẻ được quét không phải CCCD. |
NetworkError | 601400 | Xảy ra lỗi mạng. |
ServerError | 601503 | Xảy ra lỗi server. |
Hàm dựng sẵn
public var isNfcAvailable: Bool {
NFCNDEFReaderSession.readingAvailable
}iOS không có isNfcEnable hay openNfcSetting — hai hàm đó chỉ dành cho Android.
Kiểm tra cấu hình IPA
Nếu NFC hoạt động ở bản debug nhưng thất bại ở bản build production, hãy kiểm tra artefact đã build.
Info.plist phải chứa:
NFCReaderUsageDescriptionvới một usage descriptioncom.apple.developer.nfc.readersession.iso7816.select-identifierschứaA0000002471001,A0000002472001và00000000000000
embedded.mobileprovision phải chứa com.apple.developer.nfc.readersession.formats với entitlement TAG.
Bước tiếp theo
- Xác minh NFC — redeem
verificationKeytừ backend của bạn - Mã lỗi — bảng lỗi đầy đủ cho iOS
- Tổng quan Mobile SDK — các khái niệm dùng chung giữa các nền tảng