IDTech iOS SDK Guide  1.1.166.045
API reference for VP3300
Sample Project Tutorial

Using Xcode 7.3.1, we will create a sample project that will interface with the VP3300 and will perform the following activities:

  • Auto-Connect and display connection status
  • Get Device Firmware
  • Start/Stop Transaction Request for CTLS/MSR (tap/swipe)
  • Start/Complete/Cancel EMV Transaction
  • Show LCD Display for EMV transaction
  • Automatically select first AID or first Language if prompted

Protocol Delegates:

  • Delegate to receive card swipes
  • Delegate to detect headphone plug changes
  • Delegate to detect device connected
  • Delegate to detect device disconnected
  • Delegate to receive EMV/CTLS tag data

Step 1: Create New Project

Create a new Single View Application in Xcode

new_project1_s.png

new_project2_s.png

Step 2: Import Frameworks

Import the Necessary Framework/Libraries

Step 3: Design Interface

Design the User Interface by editing the Main.storyboard file

mainstoryboard_structure_s.png

Open your storyboard and add items to so it contains the following buttons/fields:

  • Add a navigation bar at the top to display the application's name
  • Add a label to the top that will signify connection/disconnection status.
  • Add text views to communicate data from the VP3300 and for EMV LCD display information. Remove the Editable and Selectable behaviors if you don't want the keyboard to pop up if you accidentally select it.
  • Add buttons to execute the following functions:
    • Get Firmware
    • Start MSR / CTLS
    • Start ICC EMV
    • Complete ICC EMV
    • Cancel Transaction
      (Add constraints accordingly so layout maps to intended screen size)
      mainstoryboard_layout_s.png

Step 4: Configure the Bridging Header and View Controller Files

Create the bridging header file by performing the following:

In the bridging header file, perform the following:

In the view controller file, perform the following:

  • Amend the View Controller Interface
  • Create an IBOutlet for the two UITextView and link it as a Referencing Outlet to the UITextView on the storyboard
  • Create an IBOutlet for the UILabel and link it as a Referencing Outlet to the UILabel on the storyboard
  • Create the 5 IBAction for the buttons, and link them to the "Touch Up Inside" event on the storyboard buttons
    import UIKit
    class ViewController: UIViewController, IDT_VP3300_Delegate {
    @IBOutlet weak var connectionStatus: UILabel!
    @IBOutlet weak var lcdTextView: UITextView!
    @IBOutlet weak var logTextView: UITextView!
    @IBAction func getFirmware(sender: UIButton) {}
    @IBAction func startMSR_CTLS(sender: UIButton) {}
    @IBAction func startICCEMV(sender: UIButton) {}
    @IBAction func completeICCEMV(sender: UIButton) {}
    @IBAction func cancelTransaction(sender: UIButton) {}
    }

    Storyboard Source Code
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
    <dependencies>
    <deployment identifier="iOS"/>
    <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
    <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
    </dependencies>
    <scenes>
    <!--View Controller-->
    <scene sceneID="tne-QT-ifu">
    <objects>
    <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="VP3300_Tutorial" customModuleProvider="target" sceneMemberID="viewController">
    <layoutGuides>
    <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
    <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
    </layoutGuides>
    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    <subviews>
    <navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="etO-Zq-HWr">
    <rect key="frame" x="0.0" y="20" width="600" height="44"/>
    <items>
    <navigationItem title="VP3300 Tutorial" id="gtg-5k-9F0"/>
    </items>
    </navigationBar>
    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Disconnected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rZO-0f-qR3">
    <rect key="frame" x="0.0" y="64" width="600" height="21"/>
    <color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
    <fontDescription key="fontDescription" type="system" pointSize="17"/>
    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
    <nil key="highlightedColor"/>
    </label>
    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZFI-2h-07z">
    <rect key="frame" x="0.0" y="84" width="600" height="114"/>
    <subviews>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tU5-uw-pz7">
    <rect key="frame" x="8" y="8" width="112" height="30"/>
    <constraints>
    <constraint firstAttribute="width" constant="112" id="ewS-6U-IbJ"/>
    <constraint firstAttribute="height" constant="30" id="wJE-mi-v7f"/>
    </constraints>
    <state key="normal" title="Get Firmware"/>
    <connections>
    <action selector="getFirmware:" destination="BYZ-38-t0r" eventType="touchUpInside" id="jeG-VR-ZKR"/>
    </connections>
    </button>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TGp-e1-4bO">
    <rect key="frame" x="8" y="46" width="118" height="30"/>
    <constraints>
    <constraint firstAttribute="width" constant="118" id="8Yd-Gz-QRA"/>
    <constraint firstAttribute="height" constant="30" id="k2q-kI-Y0P"/>
    </constraints>
    <state key="normal" title="Start ICC EMV"/>
    <connections>
    <action selector="startICCEMV:" destination="BYZ-38-t0r" eventType="touchUpInside" id="9m1-BE-9sH"/>
    </connections>
    </button>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wSh-X8-jQA">
    <rect key="frame" x="452" y="8" width="140" height="30"/>
    <constraints>
    <constraint firstAttribute="width" constant="140" id="g8v-qe-2wp"/>
    <constraint firstAttribute="height" constant="30" id="rDD-ii-GJV"/>
    </constraints>
    <state key="normal" title="Start MSR / CTLS"/>
    <connections>
    <action selector="startMSR_CTLS:" destination="BYZ-38-t0r" eventType="touchUpInside" id="cDe-en-kHV"/>
    </connections>
    </button>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HHZ-Uc-sT9">
    <rect key="frame" x="234" y="84" width="132" height="30"/>
    <state key="normal" title="Cancel Transaction"/>
    <connections>
    <action selector="cancelTransaction:" destination="BYZ-38-t0r" eventType="touchUpInside" id="GXx-f7-Rgx"/>
    </connections>
    </button>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hio-sJ-hC4">
    <rect key="frame" x="441" y="46" width="151" height="30"/>
    <constraints>
    <constraint firstAttribute="height" constant="30" id="UDz-HE-wk5"/>
    <constraint firstAttribute="width" constant="151" id="h6B-ou-ihN"/>
    </constraints>
    <state key="normal" title="Complete ICC EMV"/>
    <connections>
    <action selector="completeICCEMV:" destination="BYZ-38-t0r" eventType="touchUpInside" id="qCC-FA-5Ny"/>
    </connections>
    </button>
    </subviews>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <constraints>
    <constraint firstItem="tU5-uw-pz7" firstAttribute="leading" secondItem="ZFI-2h-07z" secondAttribute="leading" constant="8" id="2Dm-Lo-nLb"/>
    <constraint firstItem="wSh-X8-jQA" firstAttribute="top" secondItem="ZFI-2h-07z" secondAttribute="top" constant="8" id="52h-Gk-Z0b"/>
    <constraint firstItem="HHZ-Uc-sT9" firstAttribute="top" secondItem="ZFI-2h-07z" secondAttribute="top" constant="84" id="8LN-Tw-JGa"/>
    <constraint firstItem="hio-sJ-hC4" firstAttribute="top" secondItem="wSh-X8-jQA" secondAttribute="bottom" constant="8" id="BYD-32-uzT"/>
    <constraint firstAttribute="trailing" secondItem="wSh-X8-jQA" secondAttribute="trailing" constant="8" id="F76-HQ-FNU"/>
    <constraint firstAttribute="trailing" secondItem="hio-sJ-hC4" secondAttribute="trailing" constant="8" id="Fdc-pe-qvL"/>
    <constraint firstItem="HHZ-Uc-sT9" firstAttribute="centerX" secondItem="ZFI-2h-07z" secondAttribute="centerX" id="SzC-4b-OJj"/>
    <constraint firstItem="TGp-e1-4bO" firstAttribute="top" secondItem="tU5-uw-pz7" secondAttribute="bottom" constant="8" id="f3n-e6-UUG"/>
    <constraint firstAttribute="height" constant="114" id="iHH-b7-rpI"/>
    <constraint firstItem="TGp-e1-4bO" firstAttribute="leading" secondItem="ZFI-2h-07z" secondAttribute="leading" constant="8" id="xwM-oH-jQU"/>
    <constraint firstItem="tU5-uw-pz7" firstAttribute="top" secondItem="ZFI-2h-07z" secondAttribute="top" constant="8" id="yjz-Nm-fce"/>
    </constraints>
    </view>
    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Y4B-gd-hVo">
    <rect key="frame" x="0.0" y="206" width="600" height="394"/>
    <subviews>
    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="EMV LCD Display" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8IP-lE-FQE">
    <rect key="frame" x="234" y="0.0" width="133" height="21"/>
    <constraints>
    <constraint firstAttribute="width" constant="133" id="H9G-5s-1ya"/>
    <constraint firstAttribute="height" constant="21" id="OcU-YA-QYt"/>
    </constraints>
    <fontDescription key="fontDescription" type="system" pointSize="17"/>
    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
    <nil key="highlightedColor"/>
    </label>
    <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MFI-aU-Awe">
    <rect key="frame" x="8" y="29" width="584" height="160"/>
    <color key="backgroundColor" white="0.66666666669999997" alpha="0.14835831930000001" colorSpace="calibratedWhite"/>
    <fontDescription key="fontDescription" type="system" pointSize="14"/>
    <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
    </textView>
    <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RTX-Hq-mMT">
    <rect key="frame" x="8" y="226" width="584" height="160"/>
    <color key="backgroundColor" white="0.66666666669999997" alpha="0.14835831930000001" colorSpace="calibratedWhite"/>
    <fontDescription key="fontDescription" type="system" pointSize="14"/>
    <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
    </textView>
    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Log" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="G5K-IS-8cP">
    <rect key="frame" x="286" y="197" width="29" height="21"/>
    <constraints>
    <constraint firstAttribute="width" constant="29" id="RTx-9r-dXr"/>
    <constraint firstAttribute="height" constant="21" id="tub-2e-uEi"/>
    </constraints>
    <fontDescription key="fontDescription" type="system" pointSize="17"/>
    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
    <nil key="highlightedColor"/>
    </label>
    </subviews>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <constraints>
    <constraint firstAttribute="trailing" secondItem="MFI-aU-Awe" secondAttribute="trailing" constant="8" id="0M8-q5-74Y"/>
    <constraint firstItem="G5K-IS-8cP" firstAttribute="top" secondItem="MFI-aU-Awe" secondAttribute="bottom" constant="8" id="3nN-pq-c7u"/>
    <constraint firstAttribute="bottom" secondItem="RTX-Hq-mMT" secondAttribute="bottom" constant="8" id="4k8-dp-CKK"/>
    <constraint firstItem="8IP-lE-FQE" firstAttribute="centerX" secondItem="Y4B-gd-hVo" secondAttribute="centerX" id="A1H-Xc-KUF"/>
    <constraint firstItem="RTX-Hq-mMT" firstAttribute="top" secondItem="G5K-IS-8cP" secondAttribute="bottom" constant="8" id="CB4-g5-bKw"/>
    <constraint firstItem="G5K-IS-8cP" firstAttribute="centerX" secondItem="Y4B-gd-hVo" secondAttribute="centerX" id="DUq-Oc-RKU"/>
    <constraint firstItem="MFI-aU-Awe" firstAttribute="top" secondItem="8IP-lE-FQE" secondAttribute="bottom" constant="8" id="EIn-ER-enh"/>
    <constraint firstAttribute="trailing" secondItem="RTX-Hq-mMT" secondAttribute="trailing" constant="8" id="H04-dI-fGz"/>
    <constraint firstItem="MFI-aU-Awe" firstAttribute="leading" secondItem="Y4B-gd-hVo" secondAttribute="leading" constant="8" id="JT5-MI-88R"/>
    <constraint firstItem="8IP-lE-FQE" firstAttribute="top" secondItem="Y4B-gd-hVo" secondAttribute="top" id="QDs-Pg-soH"/>
    <constraint firstItem="RTX-Hq-mMT" firstAttribute="leading" secondItem="Y4B-gd-hVo" secondAttribute="leading" constant="8" id="X2o-dk-ffd"/>
    <constraint firstItem="RTX-Hq-mMT" firstAttribute="height" secondItem="MFI-aU-Awe" secondAttribute="height" id="aOL-Ir-y48"/>
    </constraints>
    </view>
    </subviews>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
    <constraints>
    <constraint firstItem="etO-Zq-HWr" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="-20" id="569-PZ-U8Q"/>
    <constraint firstAttribute="trailingMargin" secondItem="rZO-0f-qR3" secondAttribute="trailing" constant="-20" id="7Hr-mA-xXY"/>
    <constraint firstItem="rZO-0f-qR3" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="-20" id="CDb-2X-s6Q"/>
    <constraint firstAttribute="trailingMargin" secondItem="Y4B-gd-hVo" secondAttribute="trailing" constant="-20" id="FoY-PQ-8gC"/>
    <constraint firstAttribute="trailingMargin" secondItem="ZFI-2h-07z" secondAttribute="trailing" constant="-20" id="HYU-Az-cXm"/>
    <constraint firstItem="Y4B-gd-hVo" firstAttribute="top" secondItem="ZFI-2h-07z" secondAttribute="bottom" constant="8" id="LZS-v7-y1M"/>
    <constraint firstItem="ZFI-2h-07z" firstAttribute="top" secondItem="etO-Zq-HWr" secondAttribute="bottom" constant="20" id="Pcm-zb-zXS"/>
    <constraint firstAttribute="trailingMargin" secondItem="etO-Zq-HWr" secondAttribute="trailing" constant="-20" id="S1d-up-ufn"/>
    <constraint firstItem="Y4B-gd-hVo" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="-20" id="fxv-DL-Ql8"/>
    <constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="Y4B-gd-hVo" secondAttribute="bottom" id="l4D-dJ-DrY"/>
    <constraint firstItem="etO-Zq-HWr" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="pfJ-Fb-EWV"/>
    <constraint firstItem="rZO-0f-qR3" firstAttribute="top" secondItem="etO-Zq-HWr" secondAttribute="bottom" id="vXY-dJ-IM4"/>
    <constraint firstItem="ZFI-2h-07z" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="-20" id="y5F-nP-7CB"/>
    </constraints>
    </view>
    <connections>
    <outlet property="connectionStatus" destination="rZO-0f-qR3" id="8PR-rE-l6S"/>
    <outlet property="lcdTextView" destination="MFI-aU-Awe" id="Hzq-Kn-xTJ"/>
    <outlet property="logTextView" destination="RTX-Hq-mMT" id="NRT-pZ-ik7"/>
    </connections>
    </viewController>
    <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
    </objects>
    <point key="canvasLocation" x="698" y="449"/>
    </scene>
    </scenes>
    </document>

Step 5: Finalize the View Controller File

In the view controller file, perform the following:

  • Set delegate and initialize IDT_VP3300 singleton object in the viewDidLoad method. Reference: Allocate/Initialize IDT_VP3300 Object
    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    }

  • Implement protocol delegate IDT_VP3300Delegate::deviceDisconnected() and IDT_VP3300Delegate::deviceConnected() to monitor connect/disconnect events and modify our connection label upon change. Reference: Implement Optional Delegate Protocols
    func setConnectionStatus(status: String, backgroundColor: UIColor) {
    connectionStatus.text = status;
    connectionStatus.backgroundColor = backgroundColor
    }
    func appendMessageToLog(message: String) {
    logTextView.text = "\n====================\n\(message)\(logTextView.text)"
    logTextView.scrollRangeToVisible(NSRange(location: 0, length: 0))
    }
    func deviceConnected() {
    setConnectionStatus("Connected", backgroundColor: UIColor.greenColor())
    appendMessageToLog("VP3300 Connected\nFramework Version: \(IDT_Device.SDK_version())")
    }
    func deviceDisconnected() {
    setConnectionStatus("Disconnected", backgroundColor: UIColor.redColor())
    }

  • Implement protocol delegate swipeMSRData:() to receive card swipe data. Reference: Implement Optional Delegate Protocols
    func swipeMSRData(cardData: IDTMSRData!) {
    NSLog("--MSR event received, type: \(cardData.event), data: \(cardData.encTrack1)")
    switch cardData.event {
    case EVENT_MSR_CARD_DATA:
    switch cardData.captureEncodeType {
    case CAPTURE_ENCODE_TYPE_ISOABA:
    appendMessageToLog("Encode Type: ISO/ABA")
    case CAPTURE_ENCODE_TYPE_AAMVA:
    appendMessageToLog("Encode Type: AA/MVA")
    case CAPTURE_ENCODE_TYPE_Other:
    appendMessageToLog("Encode Type: Other")
    case CAPTURE_ENCODE_TYPE_Raw:
    appendMessageToLog("Encode Type: Raw")
    case CAPTURE_ENCODE_TYPE_JIS_I:
    appendMessageToLog("Encode Type: CAPTURE_ENCODE_TYPE_JIS_I")
    case CAPTURE_ENCODE_TYPE_JIS_II:
    appendMessageToLog("Encode Type: CAPTURE_ENCODE_TYPE_JIS_II")
    default:
    appendMessageToLog("Encode Type: UNKWOWN")
    }
    switch cardData.captureEncryptType {
    case CAPTURE_ENCRYPT_TYPE_AES:
    appendMessageToLog("Encrypt Type: AES")
    case CAPTURE_ENCRYPT_TYPE_TDES:
    appendMessageToLog("Encrypt Type: TDES")
    case CAPTURE_ENCRYPT_TYPE_NO_ENCRYPTION:
    appendMessageToLog("Encrypt Type: NONE")
    default:
    appendMessageToLog("Encrypt Type: UNKNOWN")
    }
    appendMessageToLog("Full card data: \(cardData.cardData == nil ? "N/A" : cardData.cardData)")
    appendMessageToLog("Track 1: \(cardData.track1 == nil ? "N/A" : cardData.track1)")
    appendMessageToLog("Track 2: \(cardData.track2 == nil ? "N/A" : cardData.track2)")
    appendMessageToLog("Track 3: \(cardData.track3 == nil ? "N/A" : cardData.track3)")
    appendMessageToLog("Length Track 1: \(cardData.track1Length)")
    appendMessageToLog("Length Track 2: \(cardData.track2Length)")
    appendMessageToLog("Length Track 3: \(cardData.track3Length)")
    appendMessageToLog("Encoded Track 1: \(cardData.encTrack1 == nil ? "N/A" : cardData.encTrack1.description)")
    appendMessageToLog("Encoded Track 2: \(cardData.encTrack2 == nil ? "N/A" : cardData.encTrack2.description)")
    appendMessageToLog("Encoded Track 3: \(cardData.encTrack3 == nil ? "N/A" : cardData.encTrack3.description)")
    appendMessageToLog("Hash Track 1: \(cardData.hashTrack1 == nil ? "N/A" : cardData.hashTrack1.description)")
    appendMessageToLog("Hash Track 2: \(cardData.hashTrack2 == nil ? "N/A" : cardData.hashTrack2.description)")
    appendMessageToLog("Hash Track 3: \(cardData.hashTrack3 == nil ? "N/A" : cardData.hashTrack3.description)")
    appendMessageToLog("KSN: \(cardData.KSN == nil ? "N/A" : cardData.KSN.description)")
    appendMessageToLog("\nSessionID: \(cardData.sessionID == nil ? "N/A" : cardData.sessionID.description)")
    appendMessageToLog("\nReader Serial Number: \(cardData.RSN == nil ? "N/A" : cardData.RSN)")
    appendMessageToLog("\nRead Status: \(cardData.readStatus)")
    if cardData.unencryptedTags != nil {
    appendMessageToLog("Unencrypted Tags: \(cardData.unencryptedTags.description)")
    }
    if cardData.encryptedTags != nil {
    appendMessageToLog("Encrypted Tags: \(cardData.encryptedTags.description)")
    }
    if cardData.maskedTags != nil {
    appendMessageToLog("Masked Tags: \(cardData.maskedTags.description)")
    }
    NSLog("Track 1: \(cardData.track1 == nil ? "N/A" : cardData.track1)")
    NSLog("Track 2: \(cardData.track2 == nil ? "N/A" : cardData.track2)")
    NSLog("Track 3: \(cardData.track3 == nil ? "N/A" : cardData.track3)")
    NSLog("Encoded Track 1: \(cardData.encTrack1 == nil ? "N/A" : cardData.encTrack1.description)")
    NSLog("Encoded Track 2: \(cardData.encTrack2 == nil ? "N/A" : cardData.encTrack2.description)")
    NSLog("Encoded Track 3: \(cardData.encTrack3 == nil ? "N/A" : cardData.encTrack3.description)")
    NSLog("Hash Track 1: \(cardData.hashTrack1 == nil ? "N/A" : cardData.hashTrack1.description)")
    NSLog("Hash Track 2: \(cardData.hashTrack2 == nil ? "N/A" : cardData.hashTrack2.description)")
    NSLog("Hash Track 3: \(cardData.hashTrack3 == nil ? "N/A" : cardData.hashTrack3.description)")
    NSLog("SessionID: \(cardData.sessionID == nil ? "N/A" : cardData.sessionID.description)")
    NSLog("nReader Serial Number: \(cardData.RSN == nil ? "N/A" : cardData.RSN)")
    NSLog("Read Status: \(cardData.readStatus)")
    NSLog("KSN: \(cardData.KSN == nil ? "N/A" : cardData.KSN.description)")
    case EVENT_MSR_CANCEL_KEY:
    appendMessageToLog("(Event) MSR Cancel Key received: \(cardData.encTrack1)")
    case EVENT_MSR_BACKSPACE_KEY:
    appendMessageToLog("(Event) MSR Backspack Key received: \(cardData.encTrack1)")
    case EVENT_MSR_ENTER_KEY:
    appendMessageToLog("(Event) MSR Enter Key received: \(cardData.encTrack1)")
    case EVENT_MSR_UNKNOWN:
    appendMessageToLog("(Event) MSR unknown event, data: \(cardData.encTrack1)")
    case EVENT_MSR_TIMEOUT:
    appendMessageToLog("MSR Timeout")
    default:
    break
    }
    }

  • Implement protocol delegate plugStatusChange:() to automatically attempt connection. Reference: Implement Optional Delegate Protocols
    func plugStatusChange(deviceInserted: Bool) {
    if deviceInserted {
    appendMessageToLog("Device attached. Attempting to connect...")
    IDT_VP3300.sharedController().device_connectToAudioReader()
    } else {
    appendMessageToLog("Device removed.")
    }
    }

  • Implement protocol delegate emvTransactionData:() to report EMV transaction results. Reference: Implement Optional Delegate Protocols
    func emvTransactionData(emvData: IDTEMVData!, errorCode error: Int32) {
    NSLog("EMV_RESULT_CODE_V2_response = \(error)")
    appendMessageToLog("EMV transaction data response: \(IDT_VP3300.sharedController().device_getResponseCodeString(error))\n")
    if emvData == nil {
    appendMessageToLog("EMV TRANSACTION ERROR. Refer to EMV_RESULT_CODE_V2_response = \(error)")
    return;
    }
    if emvData.resultCodeV2 != EMV_RESULT_CODE_V2_NO_RESPONSE {
    appendMessageToLog("EMV_RESULT_CODE_V2_RESPONSE: \(emvData.resultCodeV2.rawValue)")
    }
    if emvData.resultCodeV2 == EMV_RESULT_CODE_V2_GO_ONLINE {
    appendMessageToLog("ONLINE REQUEST")
    }
    if emvData.resultCodeV2 == EMV_RESULT_CODE_V2_START_TRANS_SUCCESS {
    appendMessageToLog("Start success: authentication required")
    }
    if emvData.resultCodeV2 == EMV_RESULT_CODE_V2_APPROVED || emvData.resultCodeV2 == EMV_RESULT_CODE_V2_APPROVED_OFFLINE {
    appendMessageToLog("APPROVED");
    }
    if emvData.resultCodeV2 == EMV_RESULT_CODE_V2_MSR_SUCCESS {
    appendMessageToLog("MSR Data Captured")
    }
    if emvData.cardType == 0 {
    appendMessageToLog("CONTACT")
    }
    if emvData.cardType == 1 {
    appendMessageToLog("CONTACTLESS")
    }
    if emvData.unencryptedTags != nil {
    appendMessageToLog("Unencrypted Tags: \(emvData.unencryptedTags.description)")
    }
    if emvData.encryptedTags != nil {
    appendMessageToLog("Encrypted Tags: \(emvData.encryptedTags.description)")
    }
    if emvData.maskedTags != nil {
    appendMessageToLog("Masked Tags: \(emvData.maskedTags.description)")
    }
    if emvData.hasAdvise {
    appendMessageToLog("Response has advise request")
    }
    if emvData.hasReversal {
    appendMessageToLog("Response has reversal request")
    }
    }

  • Implement protocol delegate lcdDisplay:() to receive LCD messages, and automatically select 1st menu item/language when presented with choices. Normal operation would require a choice be made by card holder. Reference: Implement Optional Delegate Protocols
    func lcdDisplay(mode: Int32, lines: [AnyObject]!) {
    var str = ""
    if lines != nil {
    for s in lines {
    str += s as! String
    str += "\n"
    }
    }
    switch mode {
    case 0x10:
    lcdTextView.text = ""
    case 0x03:
    lcdTextView.text = str
    case 0x01, 0x02, 0x08:
    IDT_VP3300.sharedController().emv_callbackResponseLCD(mode, selection: 1)
    default:
    break
    }
    }

  • Implement the button press methods
    func displayReturnError(operation: String, rt: RETURN_CODE) {
    let message = "\(operation) ERROR: ID-\(rt.rawValue), Message: \(IDT_VP3300.sharedController().device_getResponseCodeString(Int32(rt.rawValue)))"
    appendMessageToLog(message)
    }
    @IBAction func getFirmware(sender: UIButton) {
    var result: NSString?
    let rt = IDT_VP3300.sharedController().device_getFirmwareVersion(&result)
    logTextView.text = ""
    if RETURN_CODE_DO_SUCCESS == rt {
    appendMessageToLog("Get firmware: \(result!)")
    } else {
    displayReturnError("Get firmware", rt: rt)
    }
    }
    @IBAction func startMSR_CTLS(sender: UIButton) {
    logTextView.text = ""
    if RETURN_CODE_DO_SUCCESS == rt {
    appendMessageToLog("Enabled MSR / CTLS")
    } else {
    displayReturnError("Start MSR / CTLS", rt: rt)
    }
    }
    @IBAction func startICCEMV(sender: UIButton) {
    let rt = IDT_VP3300.sharedController().emv_startTransaction(1.00, amtOther: 0, type: 0, timeout: 60, tags: nil, forceOnline: false, fallback: true)
    logTextView.text = ""
    if RETURN_CODE_DO_SUCCESS == rt {
    appendMessageToLog("Start Transaction Command Accepted")
    } else {
    displayReturnError("Start ICC EMV", rt: rt)
    }
    }
    @IBAction func completeICCEMV(sender: UIButton) {
    let rt = IDT_VP3300.sharedController().emv_completeOnlineEMVTransaction(true, hostResponseTags: IDTUtility.hexToData("8A023030"))
    logTextView.text = ""
    if RETURN_CODE_DO_SUCCESS == rt {
    appendMessageToLog("Complete Transaction Command Accepted")
    } else {
    displayReturnError("Complete ICC EMV", rt: rt)
    }
    }
    @IBAction func cancelTransaction(sender: UIButton) {
    logTextView.text = ""
    if RETURN_CODE_DO_SUCCESS == rt {
    appendMessageToLog("Canceled transaction")
    } else {
    displayReturnError("Cancel transaction", rt: rt)
    }
    }