iOS 11 Core Nfc - Any Sample Code

iOS 11 Core NFC - any sample code?

In the Apple Developer site, create a new App ID and make sure that NFC Tag Reading is enabled.

Dev portal capabilities

Add the following lines to your .plist file:

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

and these to the entitlements file:

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

It should look something like this in the corresponding files:

Sample Image

Also Core NFC can be enabled via the Capabilities tab in Xcode.

Sample Image

Objective-c

Import CoreNFC

#import <CoreNFC/CoreNFC.h>

and set the delegate:

@interface YourViewController : UIViewController <NFCNDEFReaderSessionDelegate>

In 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];
}

In the delegate callback:

- (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);
}
}
}

You must also add the didInvalidateWithError delegate callback or you'll not conform with protocol:

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

}

You can stop the reader with:

[session invalidateSession];

Swift 3/4

Import CoreNFC

import CoreNFC

and set the delegate:

class YourViewController: UIViewController, NFCNDEFReaderSessionDelegate

In viewDidLoad:

override func viewDidLoad() {
super.viewDidLoad()

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

In the delegate callback:

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

You can stop the reader with:

session.invalidateSession

Usage

After launching the view you should immediately see the iOS NFC reader dialog like so:

iOS NFC reader dialog

Once this dialog appears you have about a second to place the iPhone near the NFC tag you want to read. Otherwise, the field is deactivated (this seems to be a bug on Apple's end). I often needed to cancel and retry to get consistent readings. More details here.

iOS 11 Core NFC - No such module 'Core NFC'

No such module 'Core NFC' error occurs while running the app in the simulator other than the device.

Hope this helps someone...

NFC Tag Writer sample or tutorial for ios?

You cannot write to an NFC tag from iOS, only read. In the Core NFC documentation from Apple it's stated you can only read NFC NDEF tags, and only on iPhone 7 and 7 plus devices (assuming 8 and X are also supported)

https://developer.apple.com/documentation/corenfc

The apps you are finding in the App Store require you to use an external Bluetooth NFC reader.

Update iOS 13 -->

It is now possible to use the CoreNFC framework to write to NFC protocol specific tags such as ISO 7816, ISO 15693, FeliCa™, and MIFARE® tags.

See Apple's example: https://developer.apple.com/documentation/corenfc/creating_nfc_tags_from_your_iphone

iOS 11 - How does one read/parse the NDEF Message from CoreNFC?

For this, you will first need to make sure you have properly formatted NDEF tags. You can use an Android phone or one of these reader accessories along with an NDEF writing app.

Implement the following methods:

- (NSString *)getType:(NSData *)NDEFData {

NSString *firstByte = [self getFirstByte:NDEFData];

if ([firstByte isEqualToString:@"00"]) {
return @"None";
} else if ([firstByte isEqualToString:@"01"]) {
return @"http://www.";
} else if ([firstByte isEqualToString:@"02"]) {
return @"https://www.";
} else if ([firstByte isEqualToString:@"03"]) {
return @"http://";
} else if ([firstByte isEqualToString:@"04"]) {
return @"https://";
} else if ([firstByte isEqualToString:@"05"]) {
return @"tel:";
} else if ([firstByte isEqualToString:@"06"]) {
return @"mailto:";
} else if ([firstByte isEqualToString:@"07"]) {
return @"ftp://anonymous:anonymous@";
} else if ([firstByte isEqualToString:@"08"]) {
return @"ftp://ftp.";
} else if ([firstByte isEqualToString:@"09"]) {
return @"ftps://";
} else if ([firstByte isEqualToString:@"0A"]) {
return @"sftp://";
} else if ([firstByte isEqualToString:@"0B"]) {
return @"smb://";
} else if ([firstByte isEqualToString:@"0C"]) {
return @"nfs://";
} else if ([firstByte isEqualToString:@"0D"]) {
return @"ftp://";
} else if ([firstByte isEqualToString:@"0E"]) {
return @"dav://";
} else if ([firstByte isEqualToString:@"0F"]) {
return @"news:";
} else if ([firstByte isEqualToString:@"10"]) {
return @"telnet://";
} else if ([firstByte isEqualToString:@"11"]) {
return @"imap:";
} else if ([firstByte isEqualToString:@"12"]) {
return @"rtsp://";
} else if ([firstByte isEqualToString:@"13"]) {
return @"urn:";
} else if ([firstByte isEqualToString:@"14"]) {
return @"pop:";
} else if ([firstByte isEqualToString:@"15"]) {
return @"sip:";
} else if ([firstByte isEqualToString:@"16"]) {
return @"sips:";
} else if ([firstByte isEqualToString:@"17"]) {
return @"tftp:";
} else if ([firstByte isEqualToString:@"18"]) {
return @"btspp://";
} else if ([firstByte isEqualToString:@"19"]) {
return @"btl2cap://";
} else if ([firstByte isEqualToString:@"1A"]) {
return @"btgoep://";
} else if ([firstByte isEqualToString:@"1B"]) {
return @"tcpobex://";
} else if ([firstByte isEqualToString:@"1C"]) {
return @"irdaobex://";
} else if ([firstByte isEqualToString:@"1D"]) {
return @"file://";
} else if ([firstByte isEqualToString:@"1E"]) {
return @"urn:epc:id:";
} else if ([firstByte isEqualToString:@"1F"]) {
return @"urn:epc:tag:";
} else if ([firstByte isEqualToString:@"20"]) {
return @"urn:epc:pat:";
} else if ([firstByte isEqualToString:@"21"]) {
return @"urn:epc:raw:";
} else if ([firstByte isEqualToString:@"22"]) {
return @"urn:epc:";
} else if ([firstByte isEqualToString:@"23"]) {
return @"urn:nfc:";
}

return @"";

}

/*!
* gets the the NDEF content
*/
- (NSString *)getNDEFContent:(NSData *)data {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return [dataString substringFromIndex:2];
}

/*!
* gets the first byte of the input NSData
*/
- (NSString *)getFirstByte:(NSData *)data {
return [[self dataToHexString:data] substringToIndex:2];
}

/*!
* transforms NSData to NSString
*/
- (NSString *)dataToHexString:(NSData *)data;
{
// get the length of the data
NSUInteger bytesCount = data.length;
if (bytesCount) {
// string with all the Hex characters
const char *hexChars = "0123456789ABCDEF";
// put bytes into an array and initialize the response array
const unsigned char *dataBuffer = data.bytes;
char *chars = malloc(sizeof(char) * (bytesCount * 2 + 1));
char *s = chars;
// go through data bytes making the transformations so a hex will literally translate to a string, so for example 0x0A will translate to "0A"
for (unsigned i = 0; i < bytesCount; ++i) {
// get hexChars character at binary AND between the current byte and 0xF0 bitwise to the right by 4 index and assign it to the current chars pointer
*s++ = hexChars[((*dataBuffer & 0xF0) >> 4)];
// get hexChars character at binary AND between the current byte and 0x0F index and assign it to the current chars pointer
*s++ = hexChars[(*dataBuffer & 0x0F)];
dataBuffer++;
}
*s = '\0';
// chars to string
NSString *hexString = [NSString stringWithUTF8String:chars];
free(chars);
return hexString;
}
return @"";
}

And call the getType method:

[self getType:yourNDEFPayloadNSData]
  • I'm assuming that all the methods are in the same class and,

  • that the payload NSData is NDEF compliant, but I modeled the code based on the NFCNDEFPayload payload

how to get icManufacturerCode of NFC tag in iOS

The issue for iOS11 are related to the signature of classes and protocols on the part of Apple (protocol NFCTag have become enum for iOS13, if I don't confuse). However, you can use this code and it should work for all versions of iOS11+

extension YourViewController: __NFCReaderSessionDelegate {

func readerSessionDidBecomeActive(_ session: NFCReaderSession) {

}

func readerSession(_ session: NFCReaderSession, didInvalidateWithError error: Error) {

}

func readerSession(_ session: NFCReaderSession, didDetect tags: [__NFCTag]) {
for tag in tags {
let rfidTag = tag as! NFCISO15693Tag
print("- Is available: \(rfidTag.isAvailable)")
print("- Type: \(rfidTag.type)")
print("- IC Manufacturer Code: \(rfidTag.icManufacturerCode)")
print("- IC Serial Number: \(rfidTag.icSerialNumber)")
print("- Identifier: \(rfidTag.identifier)")
}
}
}

There are 2 required methods and one optional (it's from Obj-C), just to get icManufacturerCode.

According to documentation of Apple

use an instance of NFCNDEFReaderSession or NFCTagReaderSession. Only
one reader session of any type can be active in the system at a time



Related Topics



Leave a reply



Submit