{"id":2270,"date":"2017-06-06T09:06:08","date_gmt":"2017-06-06T15:06:08","guid":{"rendered":"http:\/\/jamesonquave.com\/blog\/?p=2270"},"modified":"2017-09-08T21:36:14","modified_gmt":"2017-09-09T03:36:14","slug":"core-nfc-tutorial-for-nfc-on-ios-devices","status":"publish","type":"post","link":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/","title":{"rendered":"Core NFC Tutorial for NFC on iOS Devices"},"content":{"rendered":"<p>With the release of iOS 11, for the first time third-party developers are able to use the NFC reader on devices iPhone 7 and higher. This could be used for passing along identification information and a whole host of other data exchange applications from door locks to subway passes.<\/p>\n<p>The technology used on iOS 11 is called Core NFC, and I&#8217;m going to go over how to use it in this tutorial in Swift 4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/nfc2.png\" alt=\"Core NFC Device communications on iOS\"><\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/SD6Rm4cGyko\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>Because Core NFC is currently read-only, functionality such as contactless payments will not be possible out of the box, there are however other applications iphone nfc tags applications where we can use the Core NFC reading capabilities for. So let me show you how it works.<\/p>\n<p>The first step to work with NFC is to enable it for your App ID in the Apple Developer Center. Create a new App ID and enable &#8220;NFC Tag Reading&#8221; as a capability for the app.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/entitlement.png\" alt=\"NFC Tag Reading App Service\"><\/p>\n<p>After you do this, I recommend creating a development\/distribution provisioning profile specifically for this app ID, so that the NFC reading capability will be present when you try to build.<\/p>\n<p>Next, in your Xcode project add the entitlement to your projectName.entitlements file. You&#8217;ll need to right click the file and select &#8220;Open As Source Code&#8221; to manually enter this key as shown:<\/p>\n<pre><code><div id=\"highlighter_127231\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"plain\">&lt;key&gt;com.apple.developer.nfc.readersession.formats&lt;\/key&gt;<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"plain\">&lt;array&gt;<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">&lt;string&gt;<\/code><code class=\"color2\">NDEF<\/code><code class=\"plain\">&lt;\/string&gt;<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"plain\">&lt;\/array&gt;<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>If you do not have an entitlements file, you can manually create one and point to it in the settings of the project. Under &#8220;Build Settings&#8221; look for the record &#8220;Code Signing Entitlements&#8221;, and punch in the relative path to your entitlements file. In my case it&#8217;s &#8220;CoreNFC-Tutorial\/CoreNFC-Tutorial.entitlements&#8221; because my project files are inside a sub-folder called &#8220;CoreNFC-Tutorial&#8221;.<\/p>\n<p>Next, we need to add the usage string to your Xcode project. Open your Info.plist file and add a new record, start typing and allow it to autocomplete &#8220;Privacy &#8211; NFC Scan Usage Description&#8221;. This message will be shown to users when NFC is used, so for the value enter something useful for the user such as &#8220;NFC is needed to unlock doors.&#8221;.<\/p>\n<p>Next, in our code we want to import the <code>CoreNFC<\/code> module.<\/p>\n<pre><code><div id=\"highlighter_343415\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">import<\/code> <code class=\"color2\">CoreNFC<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>Note: Core NFC is completely unavailable on the iOS simulator, and even importing the module will fail. So Core NFC is for device-only testing!<\/p>\n<p>I created an <code>NFCHelper.swift<\/code> to store all my NFC-related calls, and put everything in an NFCHelper class. In the <code>init<\/code> method of the class I created a session. Core NFC requires you utilize the <code>NFCNDEFReaderSession<\/code> class in order to start listening for NFC communications. (Note the class <code>NFCReaderSession<\/code> is abstract and should not be used directly)<\/p>\n<pre><code><div id=\"highlighter_10198\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">class<\/code> <code class=\"color2\">NFCHelper<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"functions\">init<\/code><code class=\"plain\">() {<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">session =<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">(delegate: <\/code><code class=\"keyword\">self<\/code><code class=\"plain\">,<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">queue: <\/code><code class=\"keyword\">nil<\/code><code class=\"plain\">,<\/code><\/div><div class=\"line number6 index5 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">invalidateAfterFirstRead: <\/code><code class=\"keyword\">true<\/code><code class=\"plain\">)<\/code><\/div><div class=\"line number7 index6 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">session.begin()<\/code><\/div><div class=\"line number8 index7 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number9 index8 alt2\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>Here we create the session, and pass in a nil dispatch queue. Doing so will cause NFCNDEFReaderSession to automatically create a serial dispatch queue.<\/p>\n<p>Creating a session, we can specify a delegate in our <code>NFCNDEFReaderSession<\/code> class. I would like to use the <code>NFCHelper<\/code> class as the delegate, so we must first adhere to the delegate protocol, <code>NFCNDEFReaderSessionDelegate<\/code>. This delegate is based on an Objective-C object, so we must first also adhere to NSObject. <code>NFCNDEFReaderSessionDelegate<\/code> has two delegate methods we must implement:<\/p>\n<pre><code><div id=\"highlighter_831286\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">func<\/code> <code class=\"plain\">readerSession(_ session: <\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">, didInvalidateWithError error: <\/code><code class=\"color2\">Error<\/code><code class=\"plain\">)<\/code><\/div><div class=\"line number2 index1 alt1\">&nbsp;<\/div><div class=\"line number3 index2 alt2\"><code class=\"keyword\">func<\/code> <code class=\"plain\">readerSession(_ session: <\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">, didDetectNDEFs messages: [<\/code><code class=\"color2\">NFCNDEFMessage<\/code><code class=\"plain\">])<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>These two callbacks are called when an NFC session has a validation error, or when NFC activity is detected. How we use the messages will depend on your specific application, but everything you need to know will be sent through the didDetectNDEFs callback in the form of records inside of messages. To get started, you can log the results of each message in a loop. These are <code>NFCNDEFPayload<\/code> objects, which contain an identifier, payload, type, and typeNameFormat.<\/p>\n<pre><code><div id=\"highlighter_682487\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">func<\/code> <code class=\"plain\">readerSession(_ session: <\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">, didDetectNDEFs messages: [<\/code><code class=\"color2\">NFCNDEFMessage<\/code><code class=\"plain\">]) {<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(<\/code><code class=\"string\">\"Did detect NDEFs.\"<\/code><code class=\"plain\">)<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Loop through all messages<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">for<\/code> <code class=\"plain\">message <\/code><code class=\"keyword\">in<\/code> <code class=\"plain\">messages {<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">for<\/code> <code class=\"plain\">record <\/code><code class=\"keyword\">in<\/code> <code class=\"plain\">message.records {<\/code><\/div><div class=\"line number6 index5 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(record.identifier)<\/code><\/div><div class=\"line number7 index6 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(record.payload)<\/code><\/div><div class=\"line number8 index7 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(record.type)<\/code><\/div><div class=\"line number9 index8 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"functions\">print<\/code><code class=\"plain\">(record.typeNameFormat)<\/code><\/div><div class=\"line number10 index9 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number11 index10 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number12 index11 alt1\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>To clean this up a little bit so I can actually integrate with the front-end of the app, I created a callback specific for my application. You may want to do something similar. I added a callback variable that the implementing view can work with:<\/p>\n<p>I call this when I get a payload from an NFC tag, or an error:<\/p>\n<pre><code><div id=\"highlighter_977590\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"keyword\">class<\/code> <code class=\"color2\">NFCHelper<\/code><code class=\"plain\">: <\/code><code class=\"color2\">NSObject<\/code><code class=\"plain\">, <\/code><code class=\"color2\">NFCNDEFReaderSessionDelegate<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">...<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">var<\/code> <code class=\"plain\">onNFCResult: ((<\/code><code class=\"color1\">Bool<\/code><code class=\"plain\">, <\/code><code class=\"color1\">String<\/code><code class=\"plain\">) -&gt; ())?<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">...<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>I also broke out my init function to open up a session using a method, so I can restart the session from a button on my ViewController. My final code for my <code>NFCHelper.swift<\/code> file is as follows:<\/p>\n<pre><code><div id=\"highlighter_598294\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"comments\">\/\/&nbsp; NFCHelper.swift<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"comments\">\/\/&nbsp; CoreNFC-Tutorial<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"comments\">\/\/&nbsp; Created by Jameson Quave on 6\/6\/17.<\/code><\/div><div class=\"line number6 index5 alt1\"><code class=\"comments\">\/\/&nbsp; Copyright \u00a9 2017 Jameson Quave. All rights reserved.<\/code><\/div><div class=\"line number7 index6 alt2\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number8 index7 alt1\">&nbsp;<\/div><div class=\"line number9 index8 alt2\"><code class=\"keyword\">import<\/code> <code class=\"color2\">Foundation<\/code><\/div><div class=\"line number10 index9 alt1\"><code class=\"keyword\">import<\/code> <code class=\"color2\">CoreNFC<\/code><\/div><div class=\"line number11 index10 alt2\">&nbsp;<\/div><div class=\"line number12 index11 alt1\"><code class=\"keyword\">class<\/code> <code class=\"color2\">NFCHelper<\/code><code class=\"plain\">: <\/code><code class=\"color1\">NSObject<\/code><code class=\"plain\">, <\/code><code class=\"color2\">NFCNDEFReaderSessionDelegate<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number13 index12 alt2\">&nbsp;<\/div><div class=\"line number14 index13 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">var<\/code> <code class=\"plain\">onNFCResult: ((<\/code><code class=\"color1\">Bool<\/code><code class=\"plain\">, <\/code><code class=\"color1\">String<\/code><code class=\"plain\">) -&gt; ())?<\/code><\/div><div class=\"line number15 index14 alt2\">&nbsp;<\/div><div class=\"line number16 index15 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">func<\/code> <code class=\"plain\">restartSession() {<\/code><\/div><div class=\"line number17 index16 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">session =<\/code><\/div><div class=\"line number18 index17 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">(delegate: <\/code><code class=\"keyword\">self<\/code><code class=\"plain\">,<\/code><\/div><div class=\"line number19 index18 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">queue: <\/code><code class=\"keyword\">nil<\/code><code class=\"plain\">,<\/code><\/div><div class=\"line number20 index19 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">invalidateAfterFirstRead: <\/code><code class=\"keyword\">true<\/code><code class=\"plain\">)<\/code><\/div><div class=\"line number21 index20 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">session.begin()<\/code><\/div><div class=\"line number22 index21 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number23 index22 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ MARK: NFCNDEFReaderSessionDelegate<\/code><\/div><div class=\"line number24 index23 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">func<\/code> <code class=\"plain\">readerSession(_ session: <\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">, didInvalidateWithError error: <\/code><code class=\"color2\">Error<\/code><code class=\"plain\">) {<\/code><\/div><div class=\"line number25 index24 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">guard <\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">onNFCResult = onNFCResult <\/code><code class=\"keyword\">else<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number26 index25 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">return<\/code><\/div><div class=\"line number27 index26 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number28 index27 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">onNFCResult(<\/code><code class=\"keyword\">false<\/code><code class=\"plain\">, error.localizedDescription)<\/code><\/div><div class=\"line number29 index28 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number30 index29 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">func<\/code> <code class=\"plain\">readerSession(_ session: <\/code><code class=\"color2\">NFCNDEFReaderSession<\/code><code class=\"plain\">, didDetectNDEFs messages: [<\/code><code class=\"color2\">NFCNDEFMessage<\/code><code class=\"plain\">]) {<\/code><\/div><div class=\"line number31 index30 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">guard <\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">onNFCResult = onNFCResult <\/code><code class=\"keyword\">else<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number32 index31 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">return<\/code><\/div><div class=\"line number33 index32 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number34 index33 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">for<\/code> <code class=\"plain\">message <\/code><code class=\"keyword\">in<\/code> <code class=\"plain\">messages {<\/code><\/div><div class=\"line number35 index34 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">for<\/code> <code class=\"plain\">record <\/code><code class=\"keyword\">in<\/code> <code class=\"plain\">message.records {<\/code><\/div><div class=\"line number36 index35 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">if<\/code><code class=\"plain\">(record.payload.count &gt; 0) {<\/code><\/div><div class=\"line number37 index36 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">if<\/code> <code class=\"keyword\">let<\/code> <code class=\"plain\">payloadString = <\/code><code class=\"color1\">String<\/code><code class=\"plain\">.<\/code><code class=\"functions\">init<\/code><code class=\"plain\">(data: record.payload, encoding: .utf8) {<\/code><\/div><div class=\"line number38 index37 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">onNFCResult(<\/code><code class=\"keyword\">true<\/code><code class=\"plain\">, payloadString)<\/code><\/div><div class=\"line number39 index38 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number40 index39 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number41 index40 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number42 index41 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number43 index42 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number44 index43 alt1\">&nbsp;<\/div><div class=\"line number45 index44 alt2\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>I also set up a simple UI in my ViewController to demonstrate usage of this class:<\/p>\n<pre><code><div id=\"highlighter_890951\" class=\"syntaxhighlighter nogutter highlightedCode \"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody><tr><td class=\"code\"><div class=\"container\"><div class=\"line number1 index0 alt2\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number2 index1 alt1\"><code class=\"comments\">\/\/&nbsp; ViewController.swift<\/code><\/div><div class=\"line number3 index2 alt2\"><code class=\"comments\">\/\/&nbsp; CoreNFC-Tutorial<\/code><\/div><div class=\"line number4 index3 alt1\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number5 index4 alt2\"><code class=\"comments\">\/\/&nbsp; Created by Jameson Quave on 6\/6\/17.<\/code><\/div><div class=\"line number6 index5 alt1\"><code class=\"comments\">\/\/&nbsp; Copyright \u00a9 2017 Jameson Quave. All rights reserved.<\/code><\/div><div class=\"line number7 index6 alt2\"><code class=\"comments\">\/\/<\/code><\/div><div class=\"line number8 index7 alt1\">&nbsp;<\/div><div class=\"line number9 index8 alt2\"><code class=\"keyword\">import<\/code> <code class=\"color1\">UIKit<\/code><\/div><div class=\"line number10 index9 alt1\">&nbsp;<\/div><div class=\"line number11 index10 alt2\"><code class=\"keyword\">class<\/code> <code class=\"color2\">ViewController<\/code><code class=\"plain\">: <\/code><code class=\"color1\">UIViewController<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number12 index11 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">var<\/code> <code class=\"plain\">helper: <\/code><code class=\"color2\">NFCHelper<\/code><code class=\"plain\">?<\/code><\/div><div class=\"line number13 index12 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">var<\/code> <code class=\"plain\">payloadLabel: <\/code><code class=\"color1\">UILabel<\/code><code class=\"plain\">!<\/code><\/div><div class=\"line number14 index13 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">var<\/code> <code class=\"plain\">payloadText = <\/code><code class=\"string\">\"\"<\/code><\/div><div class=\"line number15 index14 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">override<\/code> <code class=\"keyword\">func<\/code> <code class=\"plain\">viewDidLoad() {<\/code><\/div><div class=\"line number16 index15 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">super<\/code><code class=\"plain\">.viewDidLoad()<\/code><\/div><div class=\"line number17 index16 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Add a detect button<\/code><\/div><div class=\"line number18 index17 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">let<\/code> <code class=\"plain\">button = <\/code><code class=\"color1\">UIButton<\/code><code class=\"plain\">(type: .system)<\/code><\/div><div class=\"line number19 index18 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">button.setTitle(<\/code><code class=\"string\">\"Read NFC\"<\/code><code class=\"plain\">, <\/code><code class=\"keyword\">for<\/code><code class=\"plain\">: .normal)<\/code><\/div><div class=\"line number20 index19 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">button.titleLabel?.font = <\/code><code class=\"color2\">UIFont<\/code><code class=\"plain\">(name: <\/code><code class=\"string\">\"Helvetica\"<\/code><code class=\"plain\">, size: 28.0)<\/code><\/div><div class=\"line number21 index20 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">button.isEnabled = <\/code><code class=\"keyword\">true<\/code><\/div><div class=\"line number22 index21 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">button.addTarget(<\/code><code class=\"keyword\">self<\/code><code class=\"plain\">, action: #selector(didTapReadNFC), <\/code><code class=\"keyword\">for<\/code><code class=\"plain\">: .touchUpInside)<\/code><\/div><div class=\"line number23 index22 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">button.frame = <\/code><code class=\"color2\">CGRect<\/code><code class=\"plain\">(x: 60, y: 200, width: <\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.view.bounds.width - 120, height: 80)<\/code><\/div><div class=\"line number24 index23 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.view.addSubview(button)<\/code><\/div><div class=\"line number25 index24 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Add a label to display the payload in<\/code><\/div><div class=\"line number26 index25 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadLabel = <\/code><code class=\"color1\">UILabel<\/code><code class=\"plain\">(frame: button.frame.offsetBy(dx: 0, dy: 220))<\/code><\/div><div class=\"line number27 index26 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadLabel.text = <\/code><code class=\"string\">\"Press Read to see payload data.\"<\/code><\/div><div class=\"line number28 index27 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadLabel.numberOfLines = 100<\/code><\/div><div class=\"line number29 index28 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.view.addSubview(payloadLabel)<\/code><\/div><div class=\"line number30 index29 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number31 index30 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Called by NFCHelper when a tag is read, or fails to read<\/code><\/div><div class=\"line number32 index31 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">func<\/code> <code class=\"plain\">onNFCResult(success: <\/code><code class=\"color1\">Bool<\/code><code class=\"plain\">, message: <\/code><code class=\"color2\">String<\/code><code class=\"plain\">) {<\/code><\/div><div class=\"line number33 index32 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">if<\/code> <code class=\"plain\">success {<\/code><\/div><div class=\"line number34 index33 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadText = <\/code><code class=\"string\">\"\\(payloadText)\\n\\(message)\"<\/code><\/div><div class=\"line number35 index34 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number36 index35 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">else<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number37 index36 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadText = <\/code><code class=\"string\">\"\\(payloadText)\\n\\(message)\"<\/code><\/div><div class=\"line number38 index37 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number39 index38 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Update UI on main thread<\/code><\/div><div class=\"line number40 index39 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"color2\">DispatchQueue<\/code><code class=\"plain\">.main.async {<\/code><\/div><div class=\"line number41 index40 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.payloadLabel.text = <\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.payloadText<\/code><\/div><div class=\"line number42 index41 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number43 index42 alt2\">&nbsp;<\/div><div class=\"line number44 index43 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number45 index44 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"comments\">\/\/ Called when user taps Read NFC Button<\/code><\/div><div class=\"line number46 index45 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"keyword\">@objc<\/code> <code class=\"keyword\">func<\/code> <code class=\"plain\">didTapReadNFC() {<\/code><\/div><div class=\"line number47 index46 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"keyword\">if<\/code> <code class=\"plain\">helper == <\/code><code class=\"keyword\">nil<\/code> <code class=\"plain\">{<\/code><\/div><div class=\"line number48 index47 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">helper = <\/code><code class=\"color2\">NFCHelper<\/code><code class=\"plain\">()<\/code><\/div><div class=\"line number49 index48 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">helper?.onNFCResult = <\/code><code class=\"keyword\">self<\/code><code class=\"plain\">.onNFCResult(success:message:)<\/code><\/div><div class=\"line number50 index49 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number51 index50 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">payloadText = <\/code><code class=\"string\">\"\"<\/code><\/div><div class=\"line number52 index51 alt1\"><code class=\"undefined spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"plain\">helper?.restartSession()<\/code><\/div><div class=\"line number53 index52 alt2\"><code class=\"undefined spaces\">&nbsp;&nbsp;<\/code><code class=\"plain\">}<\/code><\/div><div class=\"line number54 index53 alt1\"><code class=\"plain\">}<\/code><\/div><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/code><\/pre>\n<p>From here you can integrate the rest of your app with your intended use-case. Whether it&#8217;s to identify visitors to an event, check out the stats on your Amiibo, or even process payments, the Core NFC API from Apple has finally opened up the possibilities for NFC integration on these new devices. What kind of NFC product are you working on? Let me know at <a href=\"jquave@gmail.com\">jquave@gmail.com<\/a>.<\/p>\n<p><a href=\"https:\/\/github.com\/jquave\/TagReader\">Full Source Code<\/a><\/p>\n<p><a href=\"https:\/\/youtu.be\/SD6Rm4cGyko\">Video Tutorial (YouTube)<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the release of iOS 11, for the first time third-party developers are able to use the NFC reader on devices iPhone 7 and higher. This could be used for passing along identification information and a whole host of other data exchange applications from door locks to subway passes. The technology used on iOS 11&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_links_to":"","_links_to_target":""},"categories":[25,91],"tags":[102,101,100],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Core NFC Tutorial for NFC on iOS Devices - Jameson Quave<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Core NFC Tutorial for NFC on iOS Devices - Jameson Quave\" \/>\n<meta property=\"og:description\" content=\"With the release of iOS 11, for the first time third-party developers are able to use the NFC reader on devices iPhone 7 and higher. This could be used for passing along identification information and a whole host of other data exchange applications from door locks to subway passes. The technology used on iOS 11...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/\" \/>\n<meta property=\"og:site_name\" content=\"Jameson Quave\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-06T15:06:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-09-09T03:36:14+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/nfc2.png\" \/>\n<meta name=\"author\" content=\"Jameson Quave\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jameson Quave\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/\",\"url\":\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/\",\"name\":\"Core NFC Tutorial for NFC on iOS Devices - Jameson Quave\",\"isPartOf\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\"},\"datePublished\":\"2017-06-06T15:06:08+00:00\",\"dateModified\":\"2017-09-09T03:36:14+00:00\",\"author\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc\"},\"breadcrumb\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/jamesonquave.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Core NFC Tutorial for NFC on iOS Devices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\",\"url\":\"https:\/\/jamesonquave.com\/blog\/\",\"name\":\"Jameson Quave\",\"description\":\"Using computer technology to educate, and improve lives.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc\",\"name\":\"Jameson Quave\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"caption\":\"Jameson Quave\"},\"sameAs\":[\"http:\/\/jamesonquave.com\"],\"url\":\"https:\/\/jamesonquave.com\/blog\/author\/jquave\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Core NFC Tutorial for NFC on iOS Devices - Jameson Quave","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/","og_locale":"en_US","og_type":"article","og_title":"Core NFC Tutorial for NFC on iOS Devices - Jameson Quave","og_description":"With the release of iOS 11, for the first time third-party developers are able to use the NFC reader on devices iPhone 7 and higher. This could be used for passing along identification information and a whole host of other data exchange applications from door locks to subway passes. The technology used on iOS 11...","og_url":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/","og_site_name":"Jameson Quave","article_published_time":"2017-06-06T15:06:08+00:00","article_modified_time":"2017-09-09T03:36:14+00:00","og_image":[{"url":"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/nfc2.png"}],"author":"Jameson Quave","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jameson Quave","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/","url":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/","name":"Core NFC Tutorial for NFC on iOS Devices - Jameson Quave","isPartOf":{"@id":"https:\/\/jamesonquave.com\/blog\/#website"},"datePublished":"2017-06-06T15:06:08+00:00","dateModified":"2017-09-09T03:36:14+00:00","author":{"@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc"},"breadcrumb":{"@id":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/jamesonquave.com\/blog\/core-nfc-tutorial-for-nfc-on-ios-devices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/jamesonquave.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Core NFC Tutorial for NFC on iOS Devices"}]},{"@type":"WebSite","@id":"https:\/\/jamesonquave.com\/blog\/#website","url":"https:\/\/jamesonquave.com\/blog\/","name":"Jameson Quave","description":"Using computer technology to educate, and improve lives.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc","name":"Jameson Quave","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","caption":"Jameson Quave"},"sameAs":["http:\/\/jamesonquave.com"],"url":"https:\/\/jamesonquave.com\/blog\/author\/jquave\/"}]}},"_links":{"self":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2270"}],"collection":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/comments?post=2270"}],"version-history":[{"count":11,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2270\/revisions"}],"predecessor-version":[{"id":2372,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/2270\/revisions\/2372"}],"wp:attachment":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/media?parent=2270"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/categories?post=2270"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/tags?post=2270"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}