Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计提醒

core-nfc核心 NFC

Agent Skill

core-nfc 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

26,928

周安装

1,140

GitHub Stars

467

下载量

8,712
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:core-nfc(核心 NFC)
来源仓库:https://github.com/dpearson2699/swift-ios-skills
仓库路径:skills/core-nfc
安装命令:
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill core-nfc
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill core-nfc

简介

通过 CoreNFC 框架实现 iPhone 的 NFC 标签读写功能。

  • 适用于近场通信、门禁系统与移动支付类应用开发。
  • 需配置 entitlements 与 Info.plist 权限描述字符串。
  • 安装方式:GitHub,命令为 npx skills add https://github.com/dpearson2699/swift-ios-skills --skill core-nfc。
  • core-nfc 属于开发类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

CoreNFC

Read and write NFC tags on iPhone using the CoreNFC framework. Covers NDEF reader sessions, tag reader sessions, NDEF message construction, entitlements, and background tag reading. Targets Swift 6.3 / iOS 26+.

Contents

Setup

Project Configuration

  1. Add the Near Field Communication Tag Reading capability in Xcode
  2. Add NFCReaderUsageDescription to Info.plist with a user-facing reason string
  3. Add the com.apple.developer.nfc.readersession.formats entitlement with the tag types your app reads (e.g., NDEF, TAG)
  4. For ISO 7816 tags, add supported application identifiers to com.apple.developer.nfc.readersession.iso7816.select-identifiers in Info.plist

Device Requirements

NFC reading requires iPhone 7 or later. Always check for reader session availability before presenting NFC UI.

import CoreNFC

guard NFCNDEFReaderSession.readingAvailable else {
    // Device does not support NFC or feature is restricted
    showUnsupportedMessage()
    return
}

Key Types

TypeRole
NFCNDEFReaderSessionScans for NDEF-formatted tags
NFCTagReaderSessionScans for ISO7816, ISO15693, FeliCa, MIFARE tags
NFCNDEFMessageCollection of NDEF payload records
NFCNDEFPayloadSingle record within an NDEF message
NFCNDEFTagProtocol for interacting with an NDEF-capable tag

NDEF Reader Session

Use NFCNDEFReaderSession to read NDEF-formatted data from tags. This is the simplest path for reading standard tag content like URLs, text, and MIME data.

import CoreNFC

final class NDEFReader: NSObject, NFCNDEFReaderSessionDelegate {
    private var session: NFCNDEFReaderSession?

    func beginScanning() {
        guard NFCNDEFReaderSession.readingAvailable else { return }

        session = NFCNDEFReaderSession(
            delegate: self,
            queue: nil,
            invalidateAfterFirstRead: false
        )
        session?.alertMessage = "Hold your iPhone near an NFC tag."
        session?.begin()
    }

    // MARK: - NFCNDEFReaderSessionDelegate

    func readerSessionDidBecomeActive(_ session: NFCNDEFReaderSession) {
        // Session is scanning
    }

    func readerSession(
        _ session: NFCNDEFReaderSession,
        didDetectNDEFs messages: [NFCNDEFMessage]
    ) {
        for message in messages {
            for record in message.records {
                processRecord(record)
            }
        }
    }

    func readerSession(
        _ session: NFCNDEFReaderSession,
        didInvalidateWithError error: Error
    ) {
        let nfcError = error as? NFCReaderError
        if nfcError?.code != .readerSessionInvalidationErrorFirstNDEFTagRead,
           nfcError?.code != .readerSessionInvalidationErrorUserCanceled {
            print("Session invalidated: \(error.localizedDescription)")
        }
        self.session = nil
    }
}

Reading with Tag Connection

For read-write operations, use the tag-detection delegate method to connect to individual tags:

func readerSession(
    _ session: NFCNDEFReaderSession,
    didDetect tags: [any NFCNDEFTag]
) {
    guard let tag = tags.first else {
        session.restartPolling()
        return
    }

    session.connect(to: tag) { error in
        if let error {
            session.invalidate(errorMessage: "Connection failed: \(error)")
            return
        }

        tag.queryNDEFStatus { status, capacity, error in
            guard error == nil else {
                session.invalidate(errorMessage: "Query failed.")
                return
            }

            switch status {
            case .notSupported:
                session.invalidate(errorMessage: "Tag is not NDEF compliant.")
            case .readOnly:
                tag.readNDEF { message, error in
                    if let message {
                        self.processMessage(message)
                    }
                    session.invalidate()
                }
            case .readWrite:
                tag.readNDEF { message, error in
                    if let message {
                        self.processMessage(message)
                    }
                    session.alertMessage = "Tag read successfully."
                    session.invalidate()
                }
            @unknown default:
                session.invalidate()
            }
        }
    }
}

Tag Reader Session

Use NFCTagReaderSession when you need direct access to the native tag protocol (ISO 7816, ISO 15693, FeliCa, or MIFARE).

final class TagReader: NSObject, NFCTagReaderSessionDelegate {
    private var session: NFCTagReaderSession?

    func beginScanning() {
        session = NFCTagReaderSession(
            pollingOption: [.iso14443, .iso15693],
            delegate: self,
            queue: nil
        )
        session?.alertMessage = "Hold your iPhone near a tag."
        session?.begin()
    }

    func tagReaderSessionDidBecomeActive(
        _ session: NFCTagReaderSession
    ) { }

    func tagReaderSession(
        _ session: NFCTagReaderSession,
        didDetect tags: [NFCTag]
    ) {
        guard let tag = tags.first else { return }

        session.connect(to: tag) { error in
            guard error == nil else {
                session.invalidate(
                    errorMessage: "Connection failed."
                )
                return
            }

            switch tag {
            case .iso7816(let iso7816Tag):
                self.readISO7816(tag: iso7816Tag, session: session)
            case .miFare(let miFareTag):
                self.readMiFare(tag: miFareTag, session: session)
            case .iso15693(let iso15693Tag):
                self.readISO15693(tag: iso15693Tag, session: session)
            case .feliCa(let feliCaTag):
                self.readFeliCa(tag: feliCaTag, session: session)
            @unknown default:
                session.invalidate(errorMessage: "Unsupported tag type.")
            }
        }
    }

    func tagReaderSession(
        _ session: NFCTagReaderSession,
        didInvalidateWithError error: Error
    ) {
        self.session = nil
    }
}

Writing NDEF Messages

Write NDEF data to a connected tag. Always check readWrite status first.

func writeToTag(
    tag: any NFCNDEFTag,
    session: NFCNDEFReaderSession,
    url: URL
) {
    tag.queryNDEFStatus { status, capacity, error in
        guard status == .readWrite else {
            session.invalidate(errorMessage: "Tag is read-only.")
            return
        }

        guard let payload = NFCNDEFPayload.wellKnownTypeURIPayload(
            url: url
        ) else {
            session.invalidate(errorMessage: "Invalid URL.")
            return
        }

        let message = NFCNDEFMessage(records: [payload])

        tag.writeNDEF(message) { error in
            if let error {
                session.invalidate(
                    errorMessage: "Write failed: \(error.localizedDescription)"
                )
            } else {
                session.alertMessage = "Tag written successfully."
                session.invalidate()
            }
        }
    }
}

NDEF Payload Types

Creating Common Payloads

// URL payload
let urlPayload = NFCNDEFPayload.wellKnownTypeURIPayload(
    url: URL(string: "https://example.com")!
)

// Text payload
let textPayload = NFCNDEFPayload.wellKnownTypeTextPayload(
    string: "Hello NFC",
    locale: Locale(identifier: "en")
)

// Custom payload
let customPayload = NFCNDEFPayload(
    format: .nfcExternal,
    type: "com.example:mytype".data(using: .utf8)!,
    identifier: Data(),
    payload: "custom-data".data(using: .utf8)!
)

Parsing Payload Content

func processRecord(_ record: NFCNDEFPayload) {
    switch record.typeNameFormat {
    case .nfcWellKnown:
        if let url = record.wellKnownTypeURIPayload() {
            print("URL: \(url)")
        } else if let (text, locale) = record.wellKnownTypeTextPayload() {
            print("Text (\(locale)): \(text)")
        }
    case .absoluteURI:
        if let uri = String(data: record.payload, encoding: .utf8) {
            print("Absolute URI: \(uri)")
        }
    case .media:
        let mimeType = String(data: record.type, encoding: .utf8) ?? ""
        print("MIME type: \(mimeType), size: \(record.payload.count)")
    case .nfcExternal:
        let type = String(data: record.type, encoding: .utf8) ?? ""
        print("External type: \(type)")
    case .empty, .unknown, .unchanged:
        break
    @unknown default:
        break
    }
}

Background Tag Reading

On iPhone XS and later, iOS can read NFC tags in the background without opening your app. To opt in:

  1. Add associated domains or universal links that match the URL on your tags
  2. Register your app for the tag's NDEF content type
  3. Include your app's bundle ID in the tag's NDEF record

When a user taps a compatible tag, iOS displays a notification that opens your app. Handle the tag data via NSUserActivity:

func scene(
    _ scene: UIScene,
    continue userActivity: NSUserActivity
) {
    guard userActivity.activityType ==
        NSUserActivityTypeBrowsingWeb else { return }

    if let message = userActivity.ndefMessagePayload {
        for record in message.records {
            processRecord(record)
        }
    }
}

Common Mistakes

DON'T: Forget the NFC entitlement

Without the com.apple.developer.nfc.readersession.formats entitlement, session creation crashes at runtime.

// WRONG -- entitlement not added, crashes
let session = NFCNDEFReaderSession(
    delegate: self, queue: nil, invalidateAfterFirstRead: true
)

// CORRECT -- add entitlement in Signing & Capabilities first
// Then the same code works:
let session = NFCNDEFReaderSession(
    delegate: self, queue: nil, invalidateAfterFirstRead: true
)

DON'T: Skip the readingAvailable check

Attempting to create an NFC session on an unsupported device (iPad, iPod touch, or iPhone 6s and earlier) crashes.

// WRONG
func scan() {
    let session = NFCNDEFReaderSession(
        delegate: self, queue: nil, invalidateAfterFirstRead: true
    )
    session.begin()
}

// CORRECT
func scan() {
    guard NFCNDEFReaderSession.readingAvailable else {
        showUnsupportedAlert()
        return
    }
    let session = NFCNDEFReaderSession(
        delegate: self, queue: nil, invalidateAfterFirstRead: true
    )
    session.begin()
}

DON'T: Ignore session invalidation errors

The session invalidates for multiple reasons. Distinguishing user cancellation from real errors prevents false error alerts.

// WRONG -- shows error when user cancels
func readerSession(
    _ session: NFCNDEFReaderSession,
    didInvalidateWithError error: Error
) {
    showAlert("NFC Error: \(error.localizedDescription)")
}

// CORRECT -- filter expected invalidation reasons
func readerSession(
    _ session: NFCNDEFReaderSession,
    didInvalidateWithError error: Error
) {
    let nfcError = error as? NFCReaderError
    switch nfcError?.code {
    case .readerSessionInvalidationErrorUserCanceled,
         .readerSessionInvalidationErrorFirstNDEFTagRead:
        break  // Normal termination
    default:
        showAlert("NFC Error: \(error.localizedDescription)")
    }
    self.session = nil
}

DON'T: Hold a strong reference to a stale session

Once a session is invalidated, it cannot be restarted. Nil out your reference and create a new session for the next scan.

// WRONG -- reusing invalidated session
func scanAgain() {
    session?.begin()  // Does nothing, session is dead
}

// CORRECT -- create a new session
func scanAgain() {
    session = NFCNDEFReaderSession(
        delegate: self, queue: nil, invalidateAfterFirstRead: false
    )
    session?.begin()
}

DON'T: Write without checking tag status

Writing to a read-only tag silently fails or produces confusing errors.

// WRONG -- writes without checking status
tag.writeNDEF(message) { error in
    // May fail on read-only tags
}

// CORRECT -- check status first
tag.queryNDEFStatus { status, capacity, error in
    guard status == .readWrite else {
        session.invalidate(errorMessage: "Tag is read-only.")
        return
    }
    tag.writeNDEF(message) { error in
        // Handle result
    }
}

Review Checklist

  • NFC capability added in Signing & Capabilities
  • NFCReaderUsageDescription set in Info.plist
  • com.apple.developer.nfc.readersession.formats entitlement configured with correct tag types
  • NFCNDEFReaderSession.readingAvailable checked before creating sessions
  • Session delegate set before calling begin()
  • Session reference set to nil after invalidation
  • didInvalidateWithError distinguishes user cancellation from actual errors
  • NDEF status queried before write operations
  • Tag capacity checked before writing large messages
  • ISO 7816 application identifiers listed in Info.plist if using NFCTagReaderSession
  • Background tag reading configured with associated domains if needed
  • Only one reader session active at a time

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude

34.06%
按下载量换算2,967

Codex

33.63%
按下载量换算2,930

Cursor

19.99%
按下载量换算1,742

Gemini CLI

9.92%
按下载量换算864

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills