NFC çip okuma
T.C. kimlik kartı ve pasaportlardaki çip, PassportReader ile okunur. Çipe erişmek için belgenin seri numarası, doğum tarihi ve son geçerlilik tarihi gerekir; bunları belge tarama sonucundan (capturedData) alıp kullanıcıya onaylatın.
Okuma sırasında iOS kendi NFC penceresini gösterir; penceredeki metinleri SDK ayarlar. Önce NFC yeteneğini ekleyin.
1. Okuyucuyu hazırlayın
Bölüm başlığı “1. Okuyucuyu hazırlayın”import passport_readerimport ProveIDApiClient
final class NFCViewController: UIViewController { var transactionId = "" var documentNumber = "" // capturedData.sno var birthDate = "" // capturedData.bdat, gg.AA.yyyy var expireDate = "" // capturedData.edat, gg.AA.yyyy
private var passportReader: PassportReader?
override func viewDidLoad() { super.viewDidLoad()
PassportReader.PACE_ENABLED = true LocalNFCCommandTransmitter.NFC_START_MESSAGE = "Kimliğinizi, ortası telefonun üst kısmına gelecek şekilde yerleştirin ve hareket ettirmeyin."
passportReader = PassportReader(commandTransmitter: LocalNFCCommandTransmitter(), progressMessage: { input in ProgressMessageOutput(alertMessage: "Okunuyor…") }, errorMessage: { input in ErrorMessageOutput(alertMessage: "Okuma başarısız.", suppressError: false) }) startReading() }}progressMessage ve errorMessage, iOS NFC penceresindeki metni belirler. input.nfcOperationType ve input.progress okumanın ne kadar ilerlediğini, input.error ise hatayı verir (bkz. Hatalar).
2. Nonce alın ve çipi okuyun
Bölüm başlığı “2. Nonce alın ve çipi okuyun”Aktif kimlik doğrulama için Prove ID’den işleme özel bir nonce alıp okumayı başlatın:
func startReading() { IDServiceAPI.generateNonce(body: NonceGeneratorModel(transactionId: transactionId)) { result in switch result { case .success(let response): DispatchQueue.main.async { self.read(nonce: response.nonce) } case .failure(let error): showError(error) } }}
func read(nonce: String?) { let formatter = DateFormatter() formatter.dateFormat = "dd.MM.yyyy" formatter.timeZone = TimeZone(secondsFromGMT: 0)
guard let birth = formatter.date(from: birthDate), let expire = formatter.date(from: expireDate) else { // Kullanıcıdan tarihleri düzeltmesini isteyin return }
passportReader?.read(documentNumber: documentNumber, birthDate: birth, expireDate: expire, nonce: nonce, callback: self)}extension NFCViewController: PassportReaderCallback { func result(passportModel: PassportModel) { // Çip verisini doğrulamaya gönderin (aşağıda) }
func progress(progressType: NFCOperationType, progress: Double) { // START, AUTHENTICATION, DG1, DG2, DG11, DG12, DG14, DG15, SOD, ACTIVE_AUTHENTICATON, CHIP_AUTHENTICATION, SUCCESS }
func error(error: Error) { // bkz. Hatalar }}3. Çip verisini doğrulayın
Bölüm başlığı “3. Çip verisini doğrulayın”let validation = IDValidationModel(dg1: passportModel.getDg1()!, dg2: passportModel.getDg2()!, sod: passportModel.getSod()!, dg11: passportModel.getDg11(), dg12: passportModel.getDg12(), dg14: passportModel.getDg14(), dg15: passportModel.getDg15(), nonce: passportModel.getNonce(), signedData: passportModel.getSignedData(), mseResp: passportModel.getCaMseResponse(), gaResp: passportModel.getCaGaResponse(), probeResp: passportModel.getCaProbeResponse(), accessProtocol: passportModel.getAccessProtocol()?.value)
let body = ValidationInputModel(validationInformation: validation, idType: "IDCARD", transactionId: transactionId)
IDServiceAPI.validateAndSaveIDCard(body: body) { result in switch result { case .success(let response): let controls = response.controlResults showNfcResult(controls) case .failure(let error): showError(error) }}Çip doğrulama (Chip Authentication)
Bölüm başlığı “Çip doğrulama (Chip Authentication)”Çip doğrulama ile çip, gerçek olduğunu ve kopyalanmadığını kanıtlar. Bunun için gereken anahtarlar uygulamada değil, Prove ID’de tutulur: SDK komutları hazırlamak için sizin ChipAuthenticationBackend nesnenize başvurur, siz de isteği Prove ID’ye iletirsiniz.
final class ChipAuthenticationBackendImpl: ChipAuthenticationBackend { var transactionId = ""
func prepareCA(dg14Bytes: String, completed: @escaping (ChipAuthenticationPlan?, Error?) -> Void) { let body = CAPrepareInputModel(transactionId: transactionId, dg14: dg14Bytes) IDServiceAPI.prepareCA(body: body) { result in switch result { case .success(let output): guard let mse = output.mseApdu, let ga = output.gaApdu, let probe = output.probeApdu else { completed(nil, NSError(domain: "ChipAuthentication", code: -1, userInfo: [NSLocalizedDescriptionKey: output.message ?? ""])) return } completed(ChipAuthenticationPlan(mseApdu: mse, gaApdu: ga, smProbeApdu: probe), nil) case .failure(let error): completed(nil, error) } } }}let backend = ChipAuthenticationBackendImpl() // güçlü bir referansla tutunbackend.transactionId = transactionId
PassportReader.DO_CHIP_AUTHENTICATION = truePassportReader.CHIP_AUTHENTICATION_BACKEND = backendÇip doğrulama yanıtları, çip verisiyle birlikte IDValidationModel içinde (mseResp, gaResp, probeResp) gönderilir.
Okuyucu ayarları
Bölüm başlığı “Okuyucu ayarları”| Ayar | Açıklama |
|---|---|
PassportReader.PACE_ENABLED |
Belge destekliyorsa çipe PACE ile erişir |
PassportReader.DO_CHIP_AUTHENTICATION |
Çip doğrulamayı çalıştırır |
PassportReader.CHIP_AUTHENTICATION_BACKEND |
Sizin ChipAuthenticationBackend nesneniz |
PassportReader.SUPPRESS_ACTIVE_AUTH |
Aktif kimlik doğrulama başarısız olsa da okumaya devam eder |
PassportReader.SUPPRESS_CHIP_AUTHENTICATION |
Çip doğrulama başarısız olsa da okumaya devam eder |
LocalNFCCommandTransmitter.NFC_START_MESSAGE |
Okuma başlarken iOS NFC penceresinde gösterilen metin |
PassportReaderEvent.logLevel |
SDK’nın log seviyesi (canlıda .none) |
PassportReaderEvent.listener |
SDK’nın log olaylarını alan EventListener |