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
890
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Core NFC の新機能 / What's new in Core NFC (WWDC20)
集まれSwift好き!Swift愛好会スピンオフ WWDC20セッション要約会 @ Online で発表した LT「Core NFC の新機能」です。
treastrain / Tanaka Ryoga
July 09, 2020
More Decks by treastrain / Tanaka Ryoga
See All by treastrain / Tanaka Ryoga
Swift Sequence の便利 API 再発見
treastrain
1
370
北海道と青森で iOS アプリデベロッパになった
treastrain
0
47
そろそろ FormatStyle
treastrain
1
3.6k
Mastering AsyncSequence - 使う・作る・他のデザインパターン(クロージャ、Delegate など)から移行する
treastrain
5
3.8k
Firebase Apple SDK 年間ダイジェスト: 2023年 / Firebase Apple SDK Annual Digest: 2023
treastrain
1
2k
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
11k
存在型に `any` を付けていないときにコンパイルエラーにする / How to produce a compile error when writing an existential type without the `any` keyword
treastrain
1
5.6k
Bitrise Pipelines に移行して、クレジットを節約しながら並列でビルド・テストを回す / Migrate to Bitrise Pipelines and save credits while run builds and tests in parallel
treastrain
0
2.9k
Other Decks in Programming
See All in Programming
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
170
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
240
Oxlintのカスタムルールの現況
syumai
6
1.1k
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.4k
Vite+ Unified Toolchain for the Web
naokihaba
0
300
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
200
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
110
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
260
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
240
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
660
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
130
Featured
See All Featured
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
エンジニアに許された特別な時間の終わり
watany
107
250k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Practical Orchestrator
shlominoach
191
11k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
The Cult of Friendly URLs
andyhume
79
6.9k
Color Theory Basics | Prateek | Gurzu
gurzu
0
360
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Paper Plane (Part 1)
katiecoart
PRO
0
8.9k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Ethics towards AI in product and experience design
skipperchong
2
310
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