treastrain / TRETJapanNFCReader

NFC (FeliCa) Reader for iOS 13 later Core NFC / Japanese e-Money prepaid or identification cards
https://japannfcreader.tret.jp
MIT License
450 stars 34 forks source link

FeliCaCardTransactionについて #11

Closed NeoDigi closed 5 years ago

NeoDigi commented 5 years ago

いつもありがとうございます。

最新のコミットにFeliCaCardTransactionというクラスが追加されたのですが、こちらは既に利用可能となっておりますでしょうか。可能でしたら使い方についてご教示頂けますでしょうか。 また、不可能な場合はいつ頃の実装完了になりますでしょうか。

お手数をおかけしますが、何卒よろしくお願いいたします。

treastrain commented 5 years ago

@NeoDigi

お問い合わせいただきありがとうございます。このまま日本語で回答させていただきます。

FeliCaCardTransaction プロトコルは 4c1524a にて TRETJapanNFCReader/FeliCa/FeliCaCard.swift にあったものが分離し、 TRETJapanNFCReader/FeliCa/FeliCaCardTransaction.swift へ移動したものとなります。 このファイルの分離より前から FeliCaCardTransaction プロトコルはすでに利用可能です。

現時点で FeliCaCardTransaction プロトコルは、カードの読み取り時に App 側で直接利用することはほとんどなく、これを継承するカードごとの利用履歴(例えば RakutenEdyCardTransactionNanacoCardTransaction など)を基本的に利用します。それらは現時点で原則、 TRETJapanNFCReader/FeliCa/****/****CardData.swift の後半に記載されています。

ここではnanacoカードの利用履歴、 NanacoCardTransaction を例に説明します。

/// nanacoカードの利用履歴
public struct NanacoCardTransaction: FeliCaCardTransaction {
    public let date: Date
    public let type: FeliCaCardTransactionType
    public let otherType: NanacoCardTransactionType?
    public let difference: Int
    public var balance: Int

    public init(date: Date, type: FeliCaCardTransactionType, otherType: NanacoCardTransactionType? = nil, difference: Int, balance: Int) {
        self.date = date
        self.type = type
        self.otherType = otherType
        self.difference = difference
        self.balance = balance
    }
}

/// nanacoカードから読み取る事ができるnanaco利用履歴のデータの種別
public enum NanacoCardTransactionType: String, Codable {
    /// 引き継ぎ
    case transfer
    /// ポイント交換によるチャージ
    case pointExchange
}

NanacoCardTransactionFeliCaCardTransaction プロトコルを継承していますので、datetypedifferencebalance があります。 date はその利用された日付、もしくは日時、 difference はその利用による差額(利用額 or チャージ額) balance はその利用後の残高 を示しています。 そして、typeFeliCaCardTransactionType であり、 支払い、チャージ、交通機関、その他、不明 のいずれかになります。このとき、FeliCaCardTransactionType.other となった場合にのみ、otherType: NanacoCardTransactionType? が nil ではなくなり、NanacoCardTransactionType のいずれかが入ります。

以上に挙げたように、FeliCaCardTransaction は各電子マネーカードの利用履歴に関する情報を持つためのプロトコルとなります。

ご希望の回答となったでしょうか。もし意図していない回答内容でしたら、再度 Comment いただきますようお願いいたします。

NeoDigi commented 5 years ago

早速のお返事ありがとうございます。 ちなみにこちらの利用目的としては、SuicaとPASMOのみのデータを読み取りたいと考えておりますが、次のようにカードを読み取る際に

func feliCaReaderSession(didRead feliCaCard: FeliCaCard) {
        let transitICCard = feliCaCard as! TransitICCard
}

TransitICCardData を含む TransitICCardのタイプを取得します。

ただし transactionsDataはすべて Dataタイプになっており、可能でしたらタイプを問わず利用履歴にあるあらゆるデータを取得したいと考えております。 以上の例で言いますと

func feliCaReaderSession(didRead feliCaCard: FeliCaCard) {
        let transitICCard = feliCaCard as! TransitICCard

    for tr in transitICCard.data.transactionsData! {
            // こちらでデータを取得
        }
}

このような使い方も可能でしょうか。 拙文で申し訳ございませんが、何卒よろしくお願い致します。

treastrain commented 5 years ago

@NeoDigi

Comment ありがとうございます。ご希望の使用方法について概ね承知しました。

このような使い方も可能でしょうか。

結論から申し上げますと可能です。

この TRETJapanNFCReader を用いた iOS App、Japan NFC Reader でどのように TransitICCardData を使用しているかを一部、記載いたします。

func feliCaReaderSession(didRead feliCaCard: FeliCaCard) {
    let transitICCard = feliCaCard as! TransitICCard
    let transitICCardData: TransitICCardData = transitICCard.data
    let transactionsData: [Data] = transitICCardData.transactionsData!

    for transactionData in transactionsData {
        // 交通系ICカードの利用履歴データを解析
    }
}

あくまで Japan NFC Reader の抜粋となりますが、 @NeoDigi さまの Comment 後半と内容は一致しているかと思われますので、そのような使い方が可能です。 なお、交通系ICカードの利用履歴データを解析 の部分でその利用の日付、入出場駅名、残高等の処理を Japan NFC Reader では行っていますが、その際に使用する駅名のデータベース等は、私自身が作成したものではないため、GitHub では非公開とさせていただいております(使用している駅名データベースは Japan NFC Reader の謝辞にもありますとおり、IC SFCard Fan を使用しています)。

その交通系ICカードの利用履歴を持つ struct は FeliCaCardTransaction を継承し、このように記述しています(こちらも GitHub 上では公開していないため、一部のみ記載させていただきます)。

struct TransitICCardTransaction: FeliCaCardTransaction {

    let type: FeliCaCardTransactionType
    let otherType: TransitICCardTransactionType // FeliCaCardTransactionType には当てはまらない type を定義した enum

    /// 日付
    let date: Date
    /// 入場駅名
    let enteredStationName: String
    /// 出場駅名
    let exitedStationName: String
    /// 残高
    let balance: Int
    /// 連番
    let sequentialNumber: String
    /// 利用額
    let difference: Int

    // ...
}

以上のように FeliCaCardTransaction を継承した struct を作成し、transactionsData: [Data] から変換すると使いやすいのではないかなと思います。

always-beta commented 4 years ago

@treastrain

Hi, I'm having trouble with parsing the Data into solid FeliCaCardTransaction objects (I can't read Japanese so translated this webpage into English but I might miss something, sorry if I'm asking duplicated questions).

From this thread, seems you answered that it is possible to convert transitICCard.data.transactionsData into solid FeliCaCardTransaction objects, but the library didn't directly expose the methods. Is my understanding correct? If yes, is there any place that can refer to how to parse it? Any little guide will be much appreciated!

Thank you!

treastrain commented 4 years ago

@always-beta Thanks.

From this thread, seems you answered that it is possible to convert transitICCard.data.transactionsData into solid FeliCaCardTransaction objects

The answer is YES. I will translate to English about the information you may want to know.

交通系ICカードの利用履歴データを解析 の部分でその利用の日付、入出場駅名、残高等の処理を Japan NFC Reader では行っていますが、その際に使用する駅名のデータベース等は、私自身が作成したものではないため、GitHub では非公開とさせていただいております(使用している駅名データベースは Japan NFC Reader の謝辞にもありますとおり、IC SFCard Fan を使用しています)。

The Japan NFC Reader processes the use date, entry/exit station names, balances, etc. in the analysis of Transit IC card transactions data, but the database of station code/name used at that time is NOT my own. Therefore, it is kept private on GitHub. (The station name database used uses IC SFCard Fan, as noted in the Japan NFC Reader acknowledgements.)

If it's written in Kotlin and published on GitHub, I think this will help you. metrodroid/src/commonMain/kotlin/au/id/micolous/metrodroid/transit/suica

always-beta commented 4 years ago

@treastrain Great, Thank you very much!