iOS 11 Core NFC - любой пример кода?

Я только что установил первую бета-версию iOS 11 на iPhone 7 и хочу попробовать NFC. Там нет ничего об этом в настройках. Мне интересно, есть ли какой-нибудь пример кода, показывающий, как читать тег? Может кто-нибудь показать, как использовать Core NFC SDK, во фрагменте кода?

7 ответов

Решение

На сайте Apple Developer создайте новый идентификатор приложения и убедитесь, что NFC Tag Reading включен.

Возможности портала разработки

Добавьте следующие строки в ваш файл.plist:

<key>NFCReaderUsageDescription</key>
<string>NFC Tag!</string>

и это в файл прав:

<key>com.apple.developer.nfc.readersession.formats</key>
    <array>
        <string>NDEF</string>
    </array>

Это должно выглядеть примерно так в соответствующих файлах:

Также Core NFC может быть включен через вкладку Capabilities в Xcode.

Objective-C

Импортировать CoreNFC

#import <CoreNFC/CoreNFC.h>

и установите делегата:

@interface YourViewController : UIViewController <NFCNDEFReaderSessionDelegate>

В viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NFCNDEFReaderSession *session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT) invalidateAfterFirstRead:NO];
    [session beginSession];
}

В обратном вызове делегата:

- (void) readerSession:(nonnull NFCNDEFReaderSession *)session didDetectNDEFs:(nonnull NSArray<NFCNDEFMessage *> *)messages {

    for (NFCNDEFMessage *message in messages) {
        for (NFCNDEFPayload *payload in message.records) {
            NSLog(@"Payload data:%@",payload.payload);
        }
    }        
}

Вы также должны добавить didInvalidateWithError делегировать обратный вызов или вы не будете соответствовать протоколу:

- (void)readerSession:(nonnull NFCNDEFReaderSession *)session didInvalidateWithError:(nonnull NSError *)error {

}

Вы можете остановить читателя с помощью:

[session invalidateSession];

Свифт 3/4

Импортировать CoreNFC

import CoreNFC

и установите делегата:

class YourViewController: UIViewController, NFCNDEFReaderSessionDelegate

В viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()

        let session = NFCNDEFReaderSession(delegate: self,
                      queue: DispatchQueue(label: "queueName", attributes: .concurrent), invalidateAfterFirstRead: false)  
        session?.begin()
    }

В обратном вызове делегата:

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

Вы можете остановить читателя с помощью:

session.invalidateSession

использование

После запуска представления вы должны сразу увидеть диалог чтения iOS NFC следующим образом:

диалог чтения iOS NFC

Когда появится этот диалог, у вас есть около секунды, чтобы поместить iPhone рядом с тегом NFC, который вы хотите прочитать. В противном случае поле деактивируется (похоже, это ошибка Apple). Мне часто нужно было отменить и повторить попытку, чтобы получить согласованные показания. Подробнее здесь.

Чтобы исправить эту проблему, вы должны добавить com.apple.developer.nfc.readersession.formats введите в файл прав. Ключ должен быть связан с массивом включенных типов NFS. Например, вы можете добавить это в свои права.

<key>com.apple.developer.nfc.readersession.formats</key> <array> <string>NDEF</string> </array>

Это сработало для меня.

Обновлено для второй бета-версии Xcode.

Добавьте возможность NFC в свое приложение из Центра разработчиков. Идентификаторы -> Идентификаторы приложений -> включить "Чтение тегов NFC".

Если в вашем проекте нет файла разрешений, позвольте Xcode создать его для вас, просто активировав, а затем деактивировав любую возможность из Xcode -> Project Targets -> Capabilities. Вы найдете новый файл [AppName].entitlements в вашем навигаторе проекта. Щелкните правой кнопкой мыши по этому файлу и выберите "Открыть как -> Исходный код". Введите следующую запись вручную между <dict></dict>:

<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>NDEF</string>
</array>

Как только Xcode 9 позволяет включить чтение меток NFC из выбора возможностей, этот шаг становится устаревшим, потому что все, что вам нужно сделать, это включить его там. Текущая (первая) бета-версия не поддерживает это.

Вам также необходимо ввести описание использования для предупреждения о конфиденциальности, которое iOS покажет пользователю. (На данный момент (бета-версия 1) это предупреждение будет отображаться, когда устройство будет готово к сканированию, и отображает системный диалог, который будет содержать это сообщение. Тем не менее, это кажется неразрешенным.) Откройте Info.plist вашей цели и начните вводить текст. "Конфиденциальность", и вы можете прокрутить вниз до "Конфиденциальность - Описание использования NFC", чтобы выбрать его, нажав Return. Введите значимое объяснение для вашего пользователя в правом столбце.

Теперь вы должны иметь возможность импортировать CoreNFC в Swift:

import CoreNFC

Затем перейдите к документации Apple.

Важно: если компилятор возвращает ошибку с No such module 'CoreNFC' проверьте, выбрали ли вы устройство iOS 11 для сборки, а не симулятор. Это также должен быть iPhone 7 или 7 плюс. Это может измениться в будущей версии, но тестирование NFC будет полностью работать только с реальным оборудованием. (См. Core Bluetooth, где вы можете работать на симуляторе, но не тестировать реальные возможности.) Бета 2 больше не имеет этой проблемы. Тем не менее, фактическое оборудование в виде iPhone 7/p все еще требуется для фактического тестирования.

Просто для того, чтобы обогатить предыдущие ответы, важно учитывать эти NFCNDEFReaderSession учебный класс:

  • Сеанс чтения для обработки тегов формата обмена данными NFC (NDEF). Эта сессия требует "com.apple.developer.nfc.readersession.formats"право в вашем процессе. Кроме того, ваше приложение Info.plist должен содержать непустую строку описания использования.
  • Сеанс чтения NDEF автоматически сканирует и обнаруживает теги NFC Forum, содержащие действительное сообщение NDEF. Поддерживаются тэги NFC Forum с типом от 1 до 5 в формате NDEF. Модальный интерфейс системы будет представлен один раз -beginSession вызывается для информирования о начале сеанса; лист пользовательского интерфейса автоматически закрывается, когда сеанс признан недействительным либо пользователем, либо путем вызова -invalidateSession,
  • Открытый сеанс имеет ограничение по времени 60 секунд после -beginSession называется; -readerSession:didInvalidateWithError: вернусь NFCReaderSessionInvalidationErrorSessionTimeout ошибка при достижении лимита времени.
  • В системе разрешен только 1 активный сеанс чтения; -readerSession:didInvalidateWithError: вернусь NFCReaderSessionInvalidationErrorSystemIsBusy когда новый сеанс чтения инициируется -beginSession когда есть активный сеанс чтения.
  • -readerSession:didInvalidateWithError: вернусь NFCReaderSessionInvalidationErrorUserCanceled когда пользователь нажимает кнопку "Готово" в пользовательском интерфейсе.
  • -readerSession:didInvalidateWithError: вернусь NFCReaderSessionInvalidationErrorSessionTerminatedUnexpectedly когда клиентское приложение переходит в фоновое состояние.-readerSession:didInvalidateWithError: вернусь NFCReaderErrorUnsupportedFeature когда
    1. функция считывателя недоступна на оборудовании
    2. клиентское приложение не имеет необходимых прав.

Необходимо убедиться, что описание использования находится на месте, а также добавить возможность в приложение внутри Apple Developer Center. У меня есть учебник на основе моего опыта (Swift 4-based). Это доступно здесь: Core NFC Tutorial

Мои два цента:

1) под xcode 9.0 (бета 4 9M189t), если вы уже добавили возможности, нет необходимости добавлять вручную:

<key>com.apple.developer.nfc.readersession.formats</key>
    <array>
        <string>NDEF</string>
    </array>

это делается автоматически

2) без сбоев, если не используется iPhone 7 ИЛИ вы находитесь в симуляторе:

Вам позвонят:

func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        print(error.localizedDescription)
    }

он покажет: "Функция не поддерживается"

3) не пропустите:

self.nfcSession?.begin() // will trigger callback

так:

    final private func setup(){
    self.nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
    self.nfcSession?.alertMessage = "Put your NFC TAG over iPhone.."
    self.nfcSession?.begin() // will trigger callback

}

4) если пользователь отменяет, вы получите:

"Сессия недействительна при отмене пользователем"

в обратном вызове didInvalidateWithError.

Я добавил Core NFC в проект, используя ресурсы в этих ответах. Еще одна вещь, которая не была отмечена, это то, что даже если вы добавляете возможность вручную через права, Xcode, похоже, не смотрит на файл, если у вас не включена возможность. Вероятно, это связано с тем, что Xcode 9 Beta 1 не имеет Core NFC в качестве переключателя возможностей для множества примеров проектов людей. Так что обязательно включите хотя бы еще одну возможность, если у вас все еще есть проблемы! Я видел неожиданную ошибку завершения сразу же вернуться, пока я не сделал это.

Я бы оставил это как комментарий, но он не имеет достаточной репутации, чтобы сделать это. Думаю, это было достаточно важно, чтобы отметить.

Другие вопросы по тегам