Slide 1

Slide 1 text

iPhoneͰFeliCaΛಡΈऔͬͯΈͨ ాதୡ໵ (@tattn) #potatotips #64

Slide 2

Slide 2 text

ాத ୡ໵ / ͨͳͨͭ (@tattn) • Yahoo!৐׵Ҋ಺ • iOSΞϓϦΤϯδχΞ @tattn @tanakasan2525 @tattn Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved.

Slide 3

Slide 3 text

iOS13ͰFeliCaͷ ಡΈॻ͖͕Մೳʹʂ (CoreNFC)

Slide 4

Slide 4 text

SuicaͷσʔλΛྫʹ
 ಡΈࠐΈํΛ঺հ͠·͢ (৐߱ཤྺ)

Slide 5

Slide 5 text

FeliCaͷಡΈࠐΈखଓ͖ͷϑϩʔ IUUQTXXXTPOZDPKQ1SPEVDUTGFMJDBCVTJOFTTUFDITVQQPSUJOEFYIUNM begin() connect() requestService() readWithoutEncryption() λάͷϙʔϦϯά։࢝ λάʹίϚϯυΛૹΕΔΑ͏ʹ઀ଓ αʔϏεͷଘࡏ֬ೝ (σʔλͷ༗ແ) αʔϏε಺ͷσʔλಡΈࠐΈ NFCTagReaderSession NFCFeliCaTag IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPODPSFOGD

Slide 6

Slide 6 text

FeliCaͷಡΈࠐΈʹඞཁͳઃఆ • Info.plistʹPrivacyઃఆ/System CodeΛ௥Ճ • Capabilitiesʹ
 Near Field Communication Tag ReadingΛ௥Ճ Suicaͷ৔߹͸0003

Slide 7

Slide 7 text

Sessionͷ࡞੒ & ϙʔϦϯάͷ։࢝ let session = NFCTagReaderSession( pollingOption: NFCTagReaderSession.PollingOption.iso18092, delegate: self ) session.alertMessage = "iPhoneΛSuicaʹ͚͍ۙͮͯͩ͘͞" session.begin() FeliCaΛಡΈࠐΉ࣌͸ISO18092Λࢦఆ /** * @enum NFCPollingOption * * @constant NFCPollingISO14443 Support both Type A & B modulation. NFCTagTypeISO7816Compatible and NFCTagTypeMiFare tags will be discovered. * @constant NFCPollingISO15693 NFCTagTypeISO15693 tag will be discovered. * @constant NFCPollingISO18092 NFCTagTypeFeliCa tag will be discovered. */ public struct PollingOption : OptionSet { public init(rawValue: Int) public static var iso14443: NFCTagReaderSession.PollingOption { get } public static var iso15693: NFCTagReaderSession.PollingOption { get } public static var iso18092: NFCTagReaderSession.PollingOption { get } }

Slide 8

Slide 8 text

Tag ͷಡΈࠐΈ४උ public func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) { guard case .feliCa(let tag) = tags.first else { return } session.connect(to: tag) { error in guard error == nil else { return } // TagͷಡΈࠐΈ (࣍ϖʔδ) } } delegateͰݕग़ͨ͠λάΛड͚औͬͯ
 ઀ଓ͢Δ public enum NFCTag { case feliCa(NFCFeliCaTag) case iso7816(NFCISO7816Tag) case iso15693(NFCISO15693Tag) case miFare(NFCMiFareTag) }

Slide 9

Slide 9 text

ϒϩοΫσʔλͷಡΈࠐΈ let serviceCodeList = [Data([0x0f, 0x09])] let blockList = (0..

Slide 10

Slide 10 text

Suicaͷσʔλͷσίʔυ for data in dataList { let year = data[4] >> 1 let month = UInt16(bytes: data[4...5]) >> 5 & 0b1111 let day = data[5] & 0b11111 print("ར༻೔: \(year)/\(month)/\(day)") // 19/8/27 let entrance = UInt16(bytes: data[6...7]) let exit = UInt16(bytes: data[8...9]) print("ೖ৔Ӻ: \(entrance), ग़৔Ӻ: \(exit)") let balance = UInt16(bytes: data[10...11].reversed()) print("࢒ߴ: ", balance) } IUUQTXXXXEJDPSHX3"*-αΠόωن֨ *$Χʔυ year͕2000೥Λج४ʹ͍ͯ͠Δͷ͕໘ന͍

Slide 11

Slide 11 text

όΠτ഑ྻΛIntܕʹม׵͢Δ֦ு extension FixedWidthInteger { init(bytes: UInt8...) { self.init(bytes: bytes) } init(bytes: T) { let count = bytes.count - 1 self = bytes.enumerated().reduce(into: 0) { (result, item) in result += Self(item.element) << (8 * (count - item.offset)) } } } XCTAssertEqual(UInt16(bytes: 0x35, 0x0B), 13579) XCTAssertEqual(Int(bytes: 0x07, 0x5B, 0xCD, 0x15), 123456789)

Slide 12

Slide 12 text

ಡΈࠐΈɺͪΐͬͱ໘౗…

Slide 13

Slide 13 text

FeliCaΛಡΈࠐΉϥΠϒϥϦΛ࡞Γ·ͨ͠ https://github.com/tattn/NFCReader

Slide 14

Slide 14 text

NFCReader - ࢖͍ํ let reader = Reader() reader.read(didBecomeActive: { _ in print("ಡΈࠐΈ։࢝") }, didDetect: { reader, result in switch result { case .success(let suica): let balance = suica.boardingHistories.first?.balance ?? 0 reader.setMessage(balance) case .failure(let error): reader.setMessage("ಡΈࠐΈʹࣦഊ͠·ͨ͠") } }) ௒؆୯

Slide 15

Slide 15 text

NFCReader - ࢖͍ํ Reader() Reader() Reader() Reader() Reader() Reader() ৭ʑରԠͯ͠Έ·ͨ͠ ←Suica ←nanaco ←WAON ←্هͷશͯΛೝࣝ ←ࣗ࡞ͷλά ←Edy Pasmo, Kitaca, ICOCA, TOICAɺ manacaɺPiTaPaɺnimocaɺ SUGOCAɺ͸΍͔͚Μɺଞ ( )

Slide 16

Slide 16 text

·ͱΊɾײ૝ • CoreNFCΛ࢖ͬͯFeliCa (Suica) ΛಡΈࠐΉํ๏ɺ
 ࡞ͬͨϥΠϒϥϦΛ঺հ • Suicaͷ࢒ߴྖҬ͸2bytes͔͠༻ҙ͞Εͯͳ͍ͷͰ
 ೖۚͰ͖Δ্ݶΛ؆୯ʹ͸૿΍ͤͳ͍ࣄ΋Θ͔ͬͨ • FeliCaͷ࢓༷͸Sony͕೔ຊޠͰ
 ஸೡʹॻ͍͍ͯΔͷͰͱͯ΋Θ͔Γ΍͔ͬͨ͢

Slide 17

Slide 17 text

References • https://developer.apple.com/videos/play/wwdc2019/715 • https://developer.apple.com/documentation/corenfc • https://www.sony.co.jp/Products/felica/business/tech- support/index.html • https://www.wdic.org/w/RAIL/αΠόωن֨%20(ICΧʔυ) • http://www014.upp.so-net.ne.jp/SFCardFan/ • https://ja.osdn.net/projects/felicalib/wiki/FrontPage