Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Core NFC の新機能 / What's new in Core NFC (WWDC20)
Search
treastrain / Tanaka Ryoga
July 09, 2020
Programming
2
810
Core NFC の新機能 / What's new in Core NFC (WWDC20)
集まれSwift好き!Swift愛好会スピンオフ WWDC20セッション要約会 @ Online で発表した LT「Core NFC の新機能」です。
treastrain / Tanaka Ryoga
July 09, 2020
Tweet
Share
More Decks by treastrain / Tanaka Ryoga
See All by treastrain / Tanaka Ryoga
Mastering AsyncSequence - 使う・作る・他のデザインパターン(クロージャ、Delegate など)から移行する
treastrain
5
3.2k
Firebase Apple SDK 年間ダイジェスト: 2023年 / Firebase Apple SDK Annual Digest: 2023
treastrain
1
1.9k
Combine・sink(RxSwift・subscribe)では Task を作らないようにして async なメソッドを呼ぶ / Do not create a Task inside a Combine/sink (RxSwift/subscribe) closure when calling an async method there
treastrain
3
1.2k
その Swift コード、 こう書き換えてみないか / Polishing your Swift code with me!
treastrain
2
9.8k
存在型に `any` を付けていないときにコンパイルエラーにする / How to produce a compile error when writing an existential type without the `any` keyword
treastrain
1
5.3k
Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す / Migrate to Bitrise Pipelines and save credits while run builds and tests in parallel
treastrain
0
2.7k
詳解 Core NFC - NFC を用いた iOS App 開発のてびき / Demystify Core NFC - A guide to iOS App Dev using NFC
treastrain
5
4.8k
プロフィールページ(ポートフォリオサイト)を Swift-DocC で作れるか? / Can we create a profile page (portfolio site) in Swift-DocC?
treastrain
1
300
あらゆる情報を 楽に正しく String にフォーマットする 〜令和2021年から脱却せよ〜 / Easily and correctly format any information into a String
treastrain
6
2.2k
Other Decks in Programming
See All in Programming
Deep Dive into Kotlin Flow
jmatsu
1
360
OSS開発者という働き方
andpad
5
1.7k
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
130
Swift Updates - Learn Languages 2025
koher
2
490
Azure SRE Agentで運用は楽になるのか?
kkamegawa
0
2.4k
FindyにおけるTakumi活用と脆弱性管理のこれから
rvirus0817
0
530
1から理解するWeb Push
dora1998
7
1.9k
Improving my own Ruby thereafter
sisshiki1969
1
160
Zendeskのチケットを Amazon Bedrockで 解析した
ryokosuge
3
310
Introducing ReActionView: A new ActionView-compatible ERB Engine @ Rails World 2025, Amsterdam
marcoroth
0
710
複雑なドメインに挑む.pdf
yukisakai1225
5
1.2k
「待たせ上手」なスケルトンスクリーン、 そのUXの裏側
teamlab
PRO
0
560
Featured
See All Featured
Bash Introduction
62gerente
615
210k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.9k
The Art of Programming - Codeland 2020
erikaheidi
56
13k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
850
Balancing Empowerment & Direction
lara
3
620
Being A Developer After 40
akosma
90
590k
Faster Mobile Websites
deanohume
309
31k
Rails Girls Zürich Keynote
gr2m
95
14k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
Navigating Team Friction
lara
189
15k
Designing for Performance
lara
610
69k
Transcript
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE MPWF@TXJGU ू·Ε4XJGU͖ʂ4XJGUѪձεϐϯΦϑ88%$ηογϣϯཁձ!0OMJOF+VMZ $PSF/'$ʹؔ͢Δ৽ػೳ 8IBUTOFXJO$PSF/'$ USFBTUSBJO5BOBLB3ZPHB !USFBTUSBJO
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE USFBTUSBJO5BOBLB3ZPHB 4XJGU J04 XBUDI04 $PSF/'$ 044 ɹɹɹɹɹɹɹɹɹɹ!USFBTUSBJOɹIUUQTUSFUKQ
ߴઐʢʣେֶʢʣ৽ଔʢʣ ੜ·Εͯ͡Ίͯຊ֨తʹऔΓΜͩ ϓϩάϥϛϯάݴޠ4XJGU ࣗݾհ
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE +BQBO/'$3FBEFS J1IPOFͰిࢠϚωʔͷ ߴɾར༻ཤྺͷಡΈऔΓ J1IPOFͰಡΈऔͬͨཤྺΛ J$MPVEܦ༝ͰଞͷσόΠε͔Β֬ೝͰ͖Δ ݄ϦϦʔεɹμϯϩʔυ, !+BQBO/'$3FBEFS J1IPOFͰిࢠϚωʔͷߴΛνΣοΫ
J04"QQ
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE IUUQTHJUIVCDPNUSFBTUSBJO53&5+BQBO/'$3FBEFS +BQBO/'$3FBEFSͷίΞ෦Λ044Խͨ͠ϥΠϒϥϦ ӡస໔ڐূϚΠφϯόʔΧʔυͷҰ෦༰ͷಡΈऔΓ *OJUJBMDPNNJU݄ɹ4UBST!݄࣌ 53&5+BQBO/'$3FBEFS .*5-JDFODF 044-JCSBSZ
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE /FBS'JFME$PNNVOJDBUJPO ۙڑແઢ௨৴
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE ৗʹ༹͚ࠐΉ/'$ ͋ͳͨͷपΓʹ/'$ w ඇ৮ܾࡁ ΫϨδοτΧʔυͷίϯλΫτϨεܾࡁ ϓϦϖΠυܕͷిࢠϚωʔʢަ௨ܥɺҰൠతͳফඅܥʣ w ຊਓ֬ೝ ݸਓ൪߸ʢϚΠφϯόʔʣΧʔυɹɹӡస໔ڐূɹɹύεϙʔτ
ֶੜূɹɹࣾһূ w σʔλͷަ "OESPJE#FBN "OESPJE*$4d1JF
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE J1IPOFͰ/'$Λ͏ $PSF/'$
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE "QQ$MJQTͰ$PSF/'$Θͳ͍ J04Ͱ͑ΔίϯύΫτͳ"QQ w "QQ$MJQTΛ։͘ w /'$ w 23ίʔυ w
Ϛοϓʢۙͷݕࡧʣ w 4JSJ͔ΒͷఏҊ w 4BGBSJ w ϝοηʔδ w "QQ$MJQίʔυ w /'$ɾ23ίʔυͷத 6OJWFSTBM-JOLT w J04ଆ͕ಡΈऔͬͯॲཧ͢Δ $PSF/'$ͷ࣮ඞཁͳ͠
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE $PSF/'$ʹؔ͢Δ৽ػೳ 8IBUTOFXJO$PSF/'$ XXED w $PSF/'$ͷ֓ཁ 0WFSWJFX w 4XJGUͰͷߏจͷมߋ 4ZOUBYDIBOHFT
w *40λά͚ͷϝιουΛՃ *40BEEJUJPOT
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE $PSF/'$ʹؔ͢Δ৽ػೳ 8IBUTOFXJO$PSF/'$ XXED w $PSF/'$ͷ֓ཁ 0WFSWJFX w 4XJGUͰͷߏจͷมߋ 4ZOUBYDIBOHFT
w *40λά͚ͷϝιουΛՃ *40BEEJUJPOT
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE 3FTVMUΛͬͨ4XJGUߏจ .PEFSO4XJGUTZOUBYXJUI3FTVMU w J04ҎલͷNFCFeliCaTagͷྫ &YBNQMFPGNFCFeliCaTagCFGPSFJ04 detectedFeliCaTag.readWithoutEncryption( serviceCodeList: serviceCodeList,
blockList: blockList) { ( statusFlag1: Int, statusFlag2: Int, blockData: [Data], error: Error?) in if let error = error { // Handle error. return } // Handle status flag 1, status flag 2 and block data }
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE 3FTVMUΛͬͨ4XJGUߏจ .PEFSO4XJGUTZOUBYXJUI3FTVMU w J04Ҏ߱ͷNFCFeliCaTagͷྫ &YBNQMFPGNFCFeliCaTagBGUFSJ04 detectedFeliCaTag.readWithoutEncryption( serviceCodeList: serviceCodeList,
blockList: blockList) { ( response: Result<(NFCFeliCaStatusFlag, [Data]), Error>) in switch response { case .success((let statusFlag, let blockData)): // Handle NFCFeliCaStatusFlag object and block data case .failure(let error): // Handle Error object. } }
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE detectedFeliCaTag.readWithoutEncryption( serviceCodeList: serviceCodeList, blockList: blockList) { ( statusFlag1: Int,
statusFlag2: Int, blockData: [Data], error: Error?) in if let error = error { session.invalidate(errorMessage: error.localizedDescription) } guard statusFlag1 == 0x00, statusFlag2 == 0x00 else { session.invalidate( errorMessage: "εςʔλεϑϥά͕ΤϥʔΛ͍ࣔͯ͠·͢ɻ\(statusFlag1), \(statusFlag2)") return } let data = blockData.first! let balance = Int(data[11]) + Int(data[12]) << 8 session.alertMessage = "ߴ: ¥\(balance)" session.invalidate() } ަ௨ܥ*$ΧʔυͷߴΛಡΈऔΔ J04Ҏલͷ߹ɹcompletionHandler
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE detectedFeliCaTag.readWithoutEncryption( serviceCodeList: serviceCodeList, blockList: blockList) { ( response: Result<(NFCFeliCaStatusFlag,
[Data]), Error>) in switch response { case .success((let statusFlag, let blockData)): guard statusFlag.statusFlag1 == 0x00, statusFlag.statusFlag2 == 0x00 else { session.invalidate(errorMessage: "εςʔλεϑϥά͕ΤϥʔΛ͍ࣔͯ͠·͢ɻ\(statusFlag)") return } let data = blockData.first! let balance = Int(data[11]) + Int(data[12]) << 8 session.alertMessage = "ߴ: ¥\(balance)" session.invalidate() case .failure(let error): session.invalidate(errorMessage: error.localizedDescription) } } ަ௨ܥ*$ΧʔυͷߴΛಡΈऔΔ J04Ҏલͷ߹ɹresultHandler
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE Մಡੑ্ͷͨΊͷFOVNͷมߋ .PSFEFTDSJQUJWFFOVNT w FOVNͷ໊শมߋ 3FOBNFTPGUIFTFFOVNT w PollingRequestCodeNFCFeliCaPollingRequestCode w PollingTimeSlot
NFCFeliCaPollingTimeSlot w EncryptionId NFCFeliCaEncryptionId w NFCISO15693ɺNFCISO7816͚ʹ໊শมߋɾՃ͋Γ 0UIFSOFXFOVNT
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE ࠓΠϯύΫτগͳΊ J04Ͱͷ$PSF/'$ͷϝιουՃͱൺֱͯ͠ w J04Ͱͷ$PSF/'$ʮωΠςΟϒλάΞΫηεͷՃʯ J04·ͰܾΊΒΕͨϑΥʔϚοτʢ/%&'ʣͷΈ ωΠςΟϒϓϩτίϧʢ*40ɺ'FMJ$Bɺ.*'"3&ͳͲʣ͕͑ΔΑ͏ʹ ɹిࢠϚωʔͷಡΈऔΓɺνϟʔδ ɹϚΠφϯόʔΧʔυͷಡΈऔΓɺॻ͖ࠐΈ
w J04Ͱ4XJGUͰͷߏจมߋͱ*40λά͚ͷػೳՃ *40*&$ʹରԠ ਤॻؗͷຊͷλάͳͲ
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE ئ͍Θͣ "QQMF8BUDIͰ$PSF/'$͕͑ΔΑ͏ʹʜͳΒͳ͔ͬͨ USFBTUSBJO5BOBLB3ZPHB !USFBTUSBJO ͍ͬͪͭ͜ͰେৎͰ͢Αʜʁ"QQMF͞Μʜʜʁ 88%$ΑΖ͓͘͠ئ͍͠·͢Ͷʜʜʜʁ ޕޙu݄u5XFFU%FDL
$PQZSJHIUUSFBTUSBJO5BOBLB3ZPHBɹ"MMSJHIUTSFTFSWFE ࢀߟใ ͋Γ͕ͱ͏͍͟͝·ͨ͠ w ຊεϥΠυ4QFBLFS%FDLʹͯӾཡͰ͖·͢ IUUQTTQFBLFSEFDLDPNUSFBTUSBJO w ຊεϥΠυͰͷαϯϓϧίʔυΛ(JU)VC(JTUͰެ։͍ͯ͠·͢ IUUQTHJTUHJUIVCDPNUSFBTUSBJOGFDFGBCFFD w
88%$7JEFPT w $PSF/'$&OIBODFNFOUT88%$ IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED w 8IBUTOFXJO$PSF/'$88%$ IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED