iOS11でCore NFCを使って、タグのIDを読み取る

## 背景
iOS11で、Core NFCで、NDEFフォーマットされたタグを読み取ることができるようになった。
AndroidのNFC機能を使ってアプリを作っていたものとしては、NFCタグのIDを読み取れないと、面白くないということで、タグのIDを読み取ることはできないのか？と挑戦した結果読み取ることができました。

## 動作確認環境
Apple iPhone X (iOS 11.1)
XCode Version 9.1
Core NFCを使うまで各種設定は省略します（info.plistの設定などなど）

## 動作結果
ここでは、NDEFフォーマットで書き込みしたFelica-liteのタグを読み取って、その後２枚のType-Aタグを読み取った例を示します。
NDEFフォーマットで書き込みしないと、そもそも認識しませんのでご注意を！

```text:DebugConsole
2017-11-08 18:49:38.074386+0900 TestNFC[4847:694798] refreshPreferences: HangTracerEnabled: 0
2017-11-08 18:49:38.074420+0900 TestNFC[4847:694798] refreshPreferences: HangTracerDuration: 500
2017-11-08 18:49:38.074431+0900 TestNFC[4847:694798] refreshPreferences: ActivationLoggingEnabled: 0 ActivationLoggingTaskedOffByDA:0
didDetectNDEFs
01:27:00:54:f2:e8:88:db
3
goo.gl/OmhbM
didDetectNDEFs
04:6f:f3:c9:b7:02:80
5
didDetectNDEFs
04:e7:a4:b9:61:02:80
5
goo.gl/OmhbM
didInvalidateWithError: Session is invalidated due to maximum session timeout
```

## 検証コード

```swift:ViewController.swift
//
//  ViewController.swift
//  TestNFC
//
//  Created by Kazuyuki Eguchi on 2017/11/08.
//  Copyright © 2017年 Kazuyuki Eguchi. All rights reserved.
//

import UIKit
import CoreNFC

class ViewController: UIViewController , NFCNDEFReaderSessionDelegate {
    
    var session: NFCNDEFReaderSession?
    
    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        print("didInvalidateWithError: " + error.localizedDescription)
    }
    
    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        print("didDetectNDEFs")
        
        // UIDを取得する部分
        if(session.value(forKey: "_foundTags") != nil)
        {
            let foundTags : NSArray = session.value(forKey: "_foundTags") as! NSArray
            if　foundTags.count > 0　{
                let tag : NSObject = foundTags[0] as! NSObject
                let uid : Data = tag.value(forKey: "_tagID") as! Data
                let type : Int = tag.value(forKey: "_type") as! Int
                
                var uid_s : String = ""
                
                for (index,value) in uid.enumerated() {
                    var tmp = String(value, radix: 16);
                    
                    if tmp.count == 1 {
                        tmp = "0" + tmp;
                    }

                    // Felica Liteの場合
                    if type == 3 {
                        if index > 0 {
                            uid_s = uid_s + ":"
                        }
                        uid_s = uid_s + tmp
                    }
                    
                    // type-Aの場合
                    if type == 5 {
                        if index < 7 {
                            if index > 0 {
                                uid_s = uid_s + ":"
                            }
                            uid_s = uid_s + tmp
                        }
                    }
                    
                }
                
                print(uid_s)
                print(type)
            }
        }
        
        // DEFの内容を取得する処理
        for message in messages {
            for record in message.records {
                if let mes = String.init(data: record.payload, encoding: .utf8) {
                    print(mes)
                }
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
        session?.begin()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
```

## 考察

標準APIで用意されているわけで無く、session情報にタグの情報が含まれていたので、取り出してみた感じなので、バージョンアップとかで潰してくるかも！

あと、iPhoneの実機で動かす必要がありますが、有償のApple Developer契約をしないと、Core NFCを有効にできないので、その辺りもご注意を（これは、省略した作業で嵌まるので気づくと思いますが）！

なので、参考まで