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.
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:
Also Core NFC can be enabled via the Capabilities tab in Xcode.
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:
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
Iphone, Obtaining a List of Countries in an Nsarray
Uicollectionview Horizontal Paging Not Centered
How to Apply a Tintcolor to a Uiimage
How to Subclass Uitableviewcontroller in Swift
How to Deselect a Segment in Segmented Control Button Permanently Till Its Clicked Again
Wanted: How to Reliably, Consistently Select an Mkmapview Annotation
When Will Applicationwillterminate Be Called
Slservicetypefacebook Setinitialtext Is Not Working
What Do Horizontalaccuracy and Verticalaccuracy of a Cllocation Refer To
How to Create and Save Ekcalendar on iOS 6
Touchesbegan, Touchesended, Touchesmoved for Moving Uiview
App Submission Binary Does Not Show Up in Itunes Connect
How to Find the Purple Port for the Front Most Application in iOS 5 and Above
Ionic 2, Using Angular 2 Pipe Breaks on iOS-"Can't Find Variable: Intl"