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
850
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
そろそろ FormatStyle
treastrain
1
2.6k
Mastering AsyncSequence - 使う・作る・他のデザインパターン(クロージャ、Delegate など)から移行する
treastrain
5
3.6k
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.3k
その Swift コード、 こう書き換えてみないか / Polishing your Swift code with me!
treastrain
2
10k
存在型に `any` を付けていないときにコンパイルエラーにする / How to produce a compile error when writing an existential type without the `any` keyword
treastrain
1
5.4k
Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す / Migrate to Bitrise Pipelines and save credits while run builds and tests in parallel
treastrain
0
2.8k
詳解 Core NFC - NFC を用いた iOS App 開発のてびき / Demystify Core NFC - A guide to iOS App Dev using NFC
treastrain
5
5.1k
プロフィールページ(ポートフォリオサイト)を Swift-DocC で作れるか? / Can we create a profile page (portfolio site) in Swift-DocC?
treastrain
1
320
Other Decks in Programming
See All in Programming
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
0
990
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
0
710
Patterns of Patterns
denyspoltorak
0
1.3k
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
130
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
2.6k
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
500
ゆくKotlin くるRust
exoego
1
210
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
520
Python札幌 LT資料
t3tra
7
1.1k
Claude Codeの「Compacting Conversation」を体感50%減! CLAUDE.md + 8 Skills で挑むコンテキスト管理術
kmurahama
1
820
LLM Observabilityによる 対話型音声AIアプリケーションの安定運用
gekko0114
2
400
SourceGeneratorのススメ
htkym
0
160
Featured
See All Featured
Mind Mapping
helmedeiros
PRO
0
55
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Into the Great Unknown - MozCon
thekraken
40
2.2k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
570
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.4k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
64
How to build a perfect <img>
jonoalderson
1
4.9k
Crafting Experiences
bethany
1
42
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
170
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
47
Building a Scalable Design System with Sketch
lauravandoore
463
34k
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