CoreNFCについて
これまでApplePayに限られてきたiPhone上でのNFC(Near Field Communication=近距離通信技術)の利用が、
WWDC17での発表で、iOS11より「Core NFC」としてサービスが提供されることになりました。
Androidではすでに事例もあるように、何かにタグをつけて、デバイスを近づけるとタグ情報を得られるようなことが、iPhoneでもできるようになります。
しかしながら、CoreNFCを利用できるのはiPhone7/7Plus以上となります。
つまり検証もiPhone7/7Plus以上の端末でなければ、テストできませんのでご注意ください。。
NFCタグについて
今回はサンワサプライのNFCタグを使用しました。
値段はタグ10枚入りで約900円とお得です。
公式ドキュメントによると、Core NFCではNDEF(NFC Data Exchange Format)という形式のデータのみ受け取れます。書き込みは、Androidアプリの「NFC NDEF Writer」(無料)を使用しました。
実装
簡単なデモとして、日用品(洗剤, トイレットペーパーなど)にタグを貼り付け、在庫が切れたらタグを読み込んでもらい購入サイトに誘導するアプリを作ってみたいと思います。
処理的にはタグを読み込み、URLを取得し、WebViewで取得したwebページを表示するだけです。
▼ 開発環境
Xcode9 beta
MacOS Sierra 10.12.6
iPhone7 (iOS11 beta)
▼ NFC Tag Reading を有効にする
・Apple Developer Centerにログインし、ビルドで使用するAppIDを選択。
・App Services >「NFC Tag Reading」を有効にする。
▼ entitlementsファイルに値を追加する
・TARGET > Capabilities > NearField Communication Tag Reading > ONに設定
・作成された<ProjectName>.entitlementsファイルにcom.apple.developer.nfc.readersession.formatsキーと値を追加
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.nfc.readersession.formats</key> <array> <string>NDEF</string> </array> </dict> </plist> |
▼ Info.plistファイルに値を追加する
NFCReaderUsageDescriptionキーにPrivacy(使用目的)を設定。
※試してはいませんが、これを設定しない状態でNFCのSessionを走らせるとクラッシュする可能性があります。
※カメラではクラッシュします。
1 2 3 4 5 6 7 8 9 10 11 12 |
... <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> ...(省略)... // ここから <key>NFCReaderUsageDescription</key> <string>(ここになぜNFCを使用するのか目的を記述)</string> // ここまで追加 </dict> </plist> |
▼ NFCNDEFReaderSessionを使用してペイロードを取得し、商品ページをWebViewで表示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import UIKit import CoreNFC import WebKit class NFCReadViewController: UIViewController { var session: NFCNDEFReaderSession? @IBOutlet weak var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. startNFCSession() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } private func startNFCSession() { session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true) session?.alertMessage = "商品にスマホを近づけてください" session?.begin() } fileprivate func loadWebView(_ urlString: String) { guard let url = URL(string: urlString) else { //URL取得失敗 return } let request = URLRequest(url: url) DispatchQueue.main.async { webView.load(request) } } } // MARK: - NFCNDEFReaderSessionDelegate extension NFCReadViewController: NFCNDEFReaderSessionDelegate { func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { for message in messages { for record in message.records { // type, identifier, payloadが取得可能 if let urlString = String.init(data: record.payload, encoding: .utf8) { // load request loadWebView(urlString) } } } } func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) { print(#function, error) } } |
NFCNDEFReaderSessionについて
1 |
NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true) |
NFCNDEFReaderSessionの引数であるinvalidateAfterFirstReadは、初回のNDEFタグが正常に読み取られた後、セッションが自動的に無効になるかどうかを示すブール値となります。
– true(読み取りは一回のみ可能)
読み取りが完了したらセッションが自動的に無効になり、読み取り準備完了のダイアログが閉じられます。
– false(複数回読み取り可能)
セッションを無効にするかどうかはユーザーの意思に委ねられます。読み取り準備完了のダイアログの「完了」(初回読み取り前は「キャンセル」)をボタンを押下すると、セッションが無効となります。そのためアラートが表示されている限りは、連続した読み取りが可能です。
ちなみにですが、アラートのレイアウトはアラートボタンの上部にあるメッセージのみ変更可能のようです。
1 |
session?.alertMessage = "商品にスマホを近づけてください" |
動作確認
アプリを起動すると、読み取りセッションがスタートし読取準備のダイアログが表示されます。この状態でNFCタグをiPhone上部に近づけると読み取りが実行されます。
最後に
公式ドキュメントを読んでみると、現状書き込みには対応しておらず、読み込みのみとなっているようです。そのためタグにデータを書き込む際は、本記事で記述したようにAndroidアプリで書き込むのが無難かと思います。ただ今回のメジャーアップデートによりiOSでできることが格段に広がった印象です。他にもARKitなど魅力的な機能が多数追加されていますので、本記事以外にも試してみた記事を書けたらと思います。