MacにUSB経由で接続したNFCタグリーダー/ライターの情報、およびそのリーダーに接触しているNFCタグの情報を取得するAppleScriptです(Apple Silicon Mac用、Intelバイナリはなし)。

▲音楽CD型のNFCタグ(おもちゃ) Apple Musicの配信先URLを記録しておくと、iPhoneにタッチするとApple Musicがオープンする仕組み
NFC関連の情報を取得するmacOS内のフレームワークは、CryptoTokenKitです。
最初は、これをAppleScriptObjCから直接呼び出すことを試みていたのですが、呼び出してオブジェクトを生成した段階でつまづいたので、ASOC経由で直接機能を呼び出すことには早々に見切りをつけました(↓できてもよさそうなのに)。
| AppleScript名:NFCカードリーダーの存在確認_v1.scpt |
| use AppleScript version "2.8" use scripting additions use framework "Foundation" use framework "CryptoTokenKit" — リーダーの接続確認(ダメ!) set cardManager to current application’s TKSmartCardSlotManager’s defaultManager() if cardManager = missing value then display alert "リーダーが見つかりません。接続を確認してください。" return end if set allSlots to cardManager’s slotNames() if (count of allSlots) > 0 then display notification "リーダーを認識しました: " & (item 1 of allSlots) with title "NFC Ready" else display alert "リーダーが見つかりません。接続を確認してください。" end if |
このため、CryptoTokenKitフレームワークの機能を呼び出す部分はSwiftで記述したコマンドライン・ツールを用意し、AppleScriptバンドル内に格納してdo shell scriptコマンド経由で呼び出すことにしてみました。
Xcodeプロジェクト化してSwiftのプログラムを直接呼び出す方式でもよかったのですが、確実に呼び出せることを重視して前述の方式に。
–> Download Script Bundle within nfc_reader_writer cli tool
NFCタグリーダー/ライターを操作
日本市場で実績があって入手しやすいNFCリーダー/ライターはソニーのRC-S300一択という状況なので、ほぼ決め打ちでこの機種を想定してもよいのですが、海外市場がどんな状況になっているのかはわかりません。

本プログラムではMacに接続されているNFCリーダー/ライターの製品名(readerName)、NFCタグがスキャン範囲内にあるか?(tagReady)、NFCタグリーダー/ライターが書き込み可能かどうか(canWrite)、NFCタグの属性データ(atr)を取得できます。
–> {{readerName:”SONY FeliCa Port/PaSoRi 4.0″, tagReady:true, atr:”3B8F8001804F0CA0000003060300030000000068″, canWrite:true}}
NFCタグリーダー/ライターが複数接続されている場合にも対処するようになっていますが、複数台のリーダーで動作確認は行なっていません。
かるくUSのAmazonでNFCリーダー/ライターを検索してみたところ、ほぼ同様の仕組みのデバイスが流通していることを確認しました。
現在までにできていること
一応、NFCタグリーダー/ライターの存在確認(本プログラム)、NFCタグへのデータ書き込み(URLだけで確認)、NFCタグからのデータ読み込み……と、ひととおり、Swift+AppleScriptの組み合わせで実現できています。
ただ、どう考えても全MacユーザーがNFCタグリーダー/ライターを購入して利用する姿は想像しにくいため(MacにNFCリーダー/ライターが標準搭載される未来はたぶん来ない。キーボードやマウスだと可能性はゼロではないかも)、iPhoneを併用して、これでNFCタグを読み込んだり、データ書き込みする利用スタイルを想定しています。つまり、iPhoneでNFCタグを読み取ると、Macに通知が飛んでMac側でAppleScriptによって処理を行う流れになります(そんなに難しくないので、ほぼ実現できる)。
iPhone上でショートカット.appを用いてNFCタグの読み込みに応じて実行されるアクションを作成し、iCloud Drive経由でテキストデータを書き込み。Mac側でFolder Actionを用いて内容を読み取る……という流れを想定しています(ただし、自分が使っているのがiPhone 7なのでまだ実現していません……このアクションにはiPhone X以降が必要とのこと)。
このため、読み込みについてはiPhoneでスキャン→Macで実行というスタイルを考えています。書き込みについてはMac側で、ということになるでしょう(iPhone側でもできるようですが、運用上ちょっと混乱しそうなので)。
つまり、本プログラムを核としたテストプログラムのほとんどは「無駄」になってしまいそうなところです。技術的な調査がひととおり行えた、という意味では意義はあるのかもしれません。難しくなさそうなのに、セキュリティでがんじがらめなのでちょっと残念さを感じます。
| AppleScript名:reader_list_v3.scptd |
| — – Created by: Takaaki Naganoya – Created on: 2026/03/09 — – Copyright © 2026 Piyomaru Software, All Rights Reserved — set rRes to getNFCReaderList() of me — {{readerName:"SONY FeliCa Port/PaSoRi 4.0", tagReady:true, atr:"3B8F8001804F0CA0000003060300030000000068", canWrite:true}} on getNFCReaderList() set mePath to POSIX path of (path to me) set listTool to quoted form of (mePath & "Contents/Resources/nfc_list") — plist文字列を取得 set xmlData to do shell script listTool — Property List Dataとしてパース tell application "System Events" set plistItems to make new property list item with data xmlData set readerList to value of plistItems end tell set outList to {} — 取得したリストをパース repeat with aReader in readerList — plistのキーに基づき値を取得 set rName to |name| of aReader set rStatus to status of aReader set rAtr to atr of aReader set rCanWrite to can_write of aReader if rStatus is "present" then set tmpRec to {readerName:rName, tagReady:true, atr:rAtr, canWrite:rCanWrite} else set tmpRec to {readerName:rName, tagReady:false, atr:rAtr, canWrite:rCanWrite} end if set the end of outList to tmpRec end repeat — 呼び出し元の想定に合わせて、最初のリーダーのレコードを返します if (count of outList) > 0 then return outList else return {readerName:"", tagReady:false, atr:"", canWrite:false} end if end getNFCReaderList |