From b2b3d3851071219b493e90482fdb3f8970b40ee9 Mon Sep 17 00:00:00 2001 From: Eric Rowe Date: Wed, 24 Jan 2018 11:18:57 -0700 Subject: [PATCH] Update to 1.4.1 --- CloverConnector.podspec | 2 +- .../DefaultCloverConnectorListener.swift | 2 +- .../DefaultCloverConnectorV2.swift | 42 +-- .../cloverconnector/DefaultCloverDevice.swift | 120 ++++---- .../cloverconnector/ICloverConnector.swift | 279 +++++++++--------- .../ICloverConnectorListener.swift | 275 +++++++++-------- .../CloverDeviceConfiguration.swift | 0 .../{ => Transport}/CloverTransport.swift | 0 .../CloverTransportObserver.swift | 0 .../WebSocketCloverTransport.swift | 2 +- .../WebSocketDeviceConfiguration.swift | 10 +- .../api/PrintJobStatusResponse.swift | 13 +- .../cloverconnector/api/PrintRequest.swift | 11 +- .../api/RetrievePrintersResponse.swift | 14 +- .../remotepaylib/CloverDeviceEvent.swift | 100 ++++--- .../Classes/remotepaylib/UiStateMessage.swift | 17 ++ Example/.jazzy.yaml | 4 +- .../CloverConnector.xcodeproj/project.pbxproj | 64 +++- .../CloverConnector-Example.xcscheme | 3 +- Example/CloverConnector/AppDelegate.swift | 6 +- .../AppIcon.appiconset/AppIcon.png | Bin 0 -> 226308 bytes .../AppIcon.appiconset/Contents.json | 3 +- .../CloverConnectorListener.swift | 56 ++-- Example/CloverConnector/Info.plist | 2 +- .../CloverConnector/MiscViewController.swift | 4 +- .../PrintTestViewController.swift | 193 +++++++----- .../RegisterViewController.swift | 24 +- .../CloverConnector/TestViewController.swift | 6 +- Example/CloverConnector/ViewController.swift | 12 +- .../Tests/TestStub/TestCloverTransport.swift | 45 +++ .../TestStub/TestDeviceConfiguration.swift | 45 +++ Example/Tests/TestSupport.swift | 195 ++++++++++++ ...erconnector_DefaultCloverConnectorV2.swift | 225 ++++++++++++++ ...nnector_WebSocketDeviceConfiguration.swift | 40 +++ .../Test_remotepaylib_TerminalMessage.swift | 81 +++++ Example/Tests/Tests.swift | 29 -- README.md | 11 +- 37 files changed, 1339 insertions(+), 596 deletions(-) rename CloverConnector/Classes/cloverconnector/{ => Transport}/CloverDeviceConfiguration.swift (100%) rename CloverConnector/Classes/cloverconnector/{ => Transport}/CloverTransport.swift (100%) rename CloverConnector/Classes/cloverconnector/{ => Transport}/CloverTransportObserver.swift (100%) rename CloverConnector/Classes/cloverconnector/{ => Transport/Web Socket}/WebSocketCloverTransport.swift (99%) rename CloverConnector/Classes/cloverconnector/{ => Transport/Web Socket}/WebSocketDeviceConfiguration.swift (93%) create mode 100644 Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/AppIcon.png create mode 100644 Example/Tests/TestStub/TestCloverTransport.swift create mode 100644 Example/Tests/TestStub/TestDeviceConfiguration.swift create mode 100644 Example/Tests/TestSupport.swift create mode 100644 Example/Tests/Test_cloverconnector_DefaultCloverConnectorV2.swift create mode 100644 Example/Tests/Test_cloverconnector_WebSocketDeviceConfiguration.swift create mode 100644 Example/Tests/Test_remotepaylib_TerminalMessage.swift delete mode 100644 Example/Tests/Tests.swift diff --git a/CloverConnector.podspec b/CloverConnector.podspec index 92487a2..34af96e 100644 --- a/CloverConnector.podspec +++ b/CloverConnector.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'CloverConnector' - s.version = '1.4.0' + s.version = '1.4.1' s.summary = 'Provides an api for communicating with a Clover Mini as a customer facing payment device.' s.description = <<-DESC diff --git a/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorListener.swift b/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorListener.swift index 3f5559a..26bf9ac 100644 --- a/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorListener.swift +++ b/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorListener.swift @@ -159,5 +159,5 @@ open class DefaultCloverConnectorListener : NSObject, ICloverConnectorListener { open func onPrintJobStatusResponse(_ printJobStatusResponse:PrintJobStatusResponse) {} - open func onRetrieveDeviceStatusResponse(_ _response: RetrieveDeviceStatusResponse) {} + open func onRetrieveDeviceStatusResponse(_ response: RetrieveDeviceStatusResponse) {} } diff --git a/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorV2.swift b/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorV2.swift index c49ef27..6f2f4c9 100644 --- a/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorV2.swift +++ b/CloverConnector/Classes/cloverconnector/DefaultCloverConnectorV2.swift @@ -40,6 +40,8 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { //MARK: Cleanup public func dispose() { + broadcaster.notifyOnDisconnect() //must notify listeners of disconnect before the listeners are removed + broadcaster.listeners.removeAllObjects() device?.dispose() device = nil @@ -86,17 +88,10 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { //MARK: TransactionRequest public func sale(_ saleRequest: SaleRequest) { if let _ = checkDevice(from: #function) { - if let _ = deviceObserver?.lastRequest { - // not using FinishCancel because that will clear the last request - let response = SaleResponse(success: false, result: .CANCEL) - response.reason = "Device busy" - response.message = "The Mini appears to be busy. If not, call resetDevice()" - broadcaster.notifyOnSaleResponse(response) - return - } else if saleRequest.amount <= 0 { + if saleRequest.amount <= 0 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Request validation error", message: "In Sale : SaleRequest - the request amount cannot be zero. ", requestInfo: TxStartRequestMessage.SALE_REQUEST) return - } else if saleRequest.externalId.characters.count == 0 || saleRequest.externalId.characters.count > 32 { + } else if saleRequest.externalId.count == 0 || saleRequest.externalId.count > 32 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Invalid argument.", message: "In Sale : SaleRequest - The externalId is invalid. The min length is 1 and the max length is 32. ", requestInfo: TxStartRequestMessage.SALE_REQUEST) return } else { @@ -118,16 +113,10 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { public func auth(_ authRequest: AuthRequest) { if let _ = checkDevice(from: #function) { - if let _ = deviceObserver?.lastRequest { - // not using FinishCancel because that will clear the last request - let response = AuthResponse(success: false, result: .CANCEL) - response.reason = "Device busy" - response.message = "The Mini appears to be busy. If not, resetDevice() must be called" - broadcaster.notifyOnAuthResponse(response) - } else if authRequest.amount <= 0 { + if authRequest.amount <= 0 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Request validation error", message: "In Auth : AuthRequest - the request amount cannot be zero. ", requestInfo: TxStartRequestMessage.AUTH_REQUEST) return - } else if authRequest.externalId.characters.count == 0 || authRequest.externalId.characters.count > 32 { + } else if authRequest.externalId.count == 0 || authRequest.externalId.count > 32 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Invalid argument.", message: "In Auth : AuthRequest - The externalId is invalid. The min length is 1 and the max length is 32. ", requestInfo: TxStartRequestMessage.AUTH_REQUEST) return } else { @@ -171,7 +160,7 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { if preAuthRequest.amount <= 0 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Request validation error", message: "In PreAuth : PreAuthRequest - the request amount cannot be zero. ", requestInfo: TxStartRequestMessage.PREAUTH_REQUEST) return - } else if preAuthRequest.externalId.characters.count == 0 || preAuthRequest.externalId.characters.count > 32 { + } else if preAuthRequest.externalId.count == 0 || preAuthRequest.externalId.count > 32 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Invalid argument.", message: "In PreAuth : PreAuthRequest - The externalId is invalid. The min length is 1 and the max length is 32. ", requestInfo: TxStartRequestMessage.PREAUTH_REQUEST) return } else { @@ -351,7 +340,7 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { if manualRefundRequest.amount <= 0 { deviceObserver?.onFinishCancel(false, result: ResultCode.FAIL, reason: "Invalid argument", message: "The amount must be greater than 0", requestInfo: TxStartRequestMessage.CREDIT_REQUEST) return - } else if manualRefundRequest.externalId.characters.count == 0 || manualRefundRequest.externalId.characters.count > 32 { + } else if manualRefundRequest.externalId.count == 0 || manualRefundRequest.externalId.count > 32 { deviceObserver?.onFinishCancel(false, result:ResultCode.FAIL, reason: "Invalid argument.", message: "In PreAuth : ManualRefundRequest - The externalId is invalid. The min length is 1 and the max length is 32. ", requestInfo: TxStartRequestMessage.CREDIT_REQUEST) return } @@ -575,7 +564,7 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { */ if let regex = try? NSRegularExpression(pattern: "\\(([^\\)]+)\\)", options: .caseInsensitive) { - let sanitizedFunctionName = regex.stringByReplacingMatches(in: funcName, options: .withTransparentBounds, range: NSMakeRange(0, funcName.characters.count), withTemplate: "") + let sanitizedFunctionName = regex.stringByReplacingMatches(in: funcName, options: .withTransparentBounds, range: NSMakeRange(0, funcName.count), withTemplate: "") return sanitizedFunctionName } @@ -1021,10 +1010,14 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { } func onUiState(_ uiState: UiState, uiText: String, uiDirection: UiState.UiDirection, inputOptions: [InputOption]?) { + guard let eventState = CloverDeviceEvent.DeviceEventState(rawValue:uiState.rawValue) else { + debugPrint("Unsupported UI event type: \(uiState)") + return + } if uiDirection == UiState.UiDirection.ENTER { - cloverConnector.broadcaster.notifyOnDeviceActivityStart(CloverDeviceEvent(eventState: uiState.rawValue, message: uiText, inputOptions: inputOptions)) + cloverConnector.broadcaster.notifyOnDeviceActivityStart(CloverDeviceEvent(eventState: eventState, message: uiText, inputOptions: inputOptions)) } else if uiDirection == UiState.UiDirection.EXIT { - cloverConnector.broadcaster.notifyOnDeviceActivityEnd(CloverDeviceEvent(eventState: uiState.rawValue, message: uiText)) + cloverConnector.broadcaster.notifyOnDeviceActivityEnd(CloverDeviceEvent(eventState: eventState, message: uiText)) } } @@ -1098,11 +1091,6 @@ class DefaultCloverConnectorV2 : NSObject, ICloverConnector { cloverConnector.broadcaster.notifyOnMessageFromActivity(messageFromActivity) } - func onResetDeviceResponse(_ result:ResultCode, reason: String?, state:ExternalDeviceState) { - let deviceResponse = ResetDeviceResponse(result: result, state: state) - cloverConnector.broadcaster.notifyOnResetDeviceResponse(deviceResponse) - } - func onRetrievePaymentResponse(_ result: ResultStatus, reason: String?, queryStatus qs: QueryStatus, payment: CLVModels.Payments.Payment?, externalPaymentId epi:String?) { let success = result == .SUCCESS let retrievePaymentResponse = RetrievePaymentResponse(success: success, result: success ? ResultCode.SUCCESS : ResultCode.CANCEL, queryStatus: qs, payment: payment, externalPaymentId: epi) diff --git a/CloverConnector/Classes/cloverconnector/DefaultCloverDevice.swift b/CloverConnector/Classes/cloverconnector/DefaultCloverDevice.swift index 84be11e..c307709 100644 --- a/CloverConnector/Classes/cloverconnector/DefaultCloverDevice.swift +++ b/CloverConnector/Classes/cloverconnector/DefaultCloverDevice.swift @@ -416,8 +416,20 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { self.doPrintText(request.text, printRequestId: request.printRequestId, printDeviceId: request.printDeviceId) } else if let image = request.images.first { //...but currently only support one image... self.doPrintImage(image, printRequestId: request.printRequestId, printDeviceId: request.printDeviceId) - } else if let imageURLString = request.imageURLS.first?.absoluteString { //...and one image URL - self.doPrintImage(imageURLString, printRequestId: request.printRequestId, printDeviceId: request.printDeviceId) + } else if let imageURL = request.imageURLS.first { //...and one image URL + self.download(imageURL: imageURL, completion: { [weak self] (image) in + guard let downloadedImage = image else { + debugPrint("Printing failed, couldn't download image: " + imageURL.absoluteString) + + let response = PrintJobStatusResponseMessage() + response.printRequestId = request.printRequestId + response.status = PrintJobStatus.ERROR.rawValue + self?.notifyRetrievePrintJobStatus(response) + return + } + + self?.doPrintImage(downloadedImage, printRequestId: request.printRequestId, printDeviceId: request.printDeviceId) + }) } else { //if we got here, it's because the printRequest either had nothing on it, or has a new, unhandled content type debugPrint("In doPrint: PrintRequest had no content or had an unhandled content type") @@ -660,91 +672,66 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { } @discardableResult - func sendCommandMessage(payload msgJSON:String, method:Method, version:Int = 1, attachment:String? = nil, attachmentEncoding:String? = nil, attachmentData:Data? = nil, attachmentUrl:String? = nil) -> String? { + func sendCommandMessage(payload msgJSON:String, method:Method, version:Int = 1, attachmentData:Data? = nil) -> String? { let rm:RemoteMessage = RemoteMessage() rm.method = method rm.type = RemoteMessageType.COMMAND rm.payload = msgJSON - rm.attachment = attachment - rm.attachmentEncoding = attachmentEncoding - - return sendRemoteMessage(rm, version: version, attachmentData: attachmentData, attachmentUrl: attachmentUrl, attachmentEncoding: attachmentEncoding) + + return sendRemoteMessage(rm, version: version, attachmentData: attachmentData) } - func sendRemoteMessage(_ remoteMsg:RemoteMessage, version:Int = 1, attachmentData: Data? = nil, attachmentUrl: String? = nil, attachmentEncoding: String? = nil) -> String? { + /// Sends a Remote Message on the Web Socket + /// + /// - Parameters: + /// - remoteMsg: RemoteMessage object to send. The attachment string of this object will be ignored. + /// - version: Version of the message object + /// - attachmentData: Attachment data to send. + /// - Returns: Remote Message Id of the transmitted message, or nil if the message is not sent. + func sendRemoteMessage(_ remoteMsg:RemoteMessage, version:Int = 1, attachmentData: Data? = nil) -> String? { guard let cloverConnector = cloverConnector else { return nil } remoteMsg.packageName = self.packageName remoteMsg.remoteApplicationID = config.remoteApplicationID remoteMsg.remoteSourceSDK = config.remoteSourceSDK remoteMsg.id = String(id) remoteMsg.version = version + remoteMsg.attachment = nil + remoteMsg.attachmentEncoding = nil + remoteMsg.attachmentUri = nil if remoteMsg.version > 1 { // we CAN send fragments - // there are 3 paths... - // 1. The attachment is already a string, so set change the Encoding from "BASE64" to "BASE64.ATTACHMENT" (or we could decode it, and then encode the chunks), or if the Encoding is nil, just write it...e.g. the attachment might be a large text snippet and not encoded - // 2. The attachmentData is binary, so we encode as "BASE64.FRAGMENT" - // 3. The attachmentUrl is provided, so we read and encode as "BASE64.FRAGMENT" - - - - let hasAttachmentURI = attachmentUrl != nil let hasAttachmentData = attachmentData != nil - let payloadTooLarge = ((remoteMsg.attachment?.characters.count ?? 0) + (remoteMsg.payload?.characters.count ?? 0)) > maxMessageSizeInChars - let shouldFrag = hasAttachmentURI || hasAttachmentData || payloadTooLarge + let payloadTooLarge = (remoteMsg.payload?.count ?? 0) > maxMessageSizeInChars + let shouldFrag = hasAttachmentData || payloadTooLarge + + if shouldFrag { // we NEED to fragment // if the payload size exceeds the max, then fail immediately - // note that this is not exact - data in a String will be a different length than the same data in Data thanks to the JSON conversion and multiple escaping done on messages, but there's enough pad in the max payload to account for this. - if (remoteMsg.attachment != nil && remoteMsg.attachment!.characters.count > cloverConnector.MAX_PAYLOAD_SIZE) || // passed in a formatted string, check for length (this isn't actually used anywhere...) - (attachmentData != nil && attachmentData!.count > cloverConnector.MAX_PAYLOAD_SIZE) { // passed in a data chunk, check for length + if (attachmentData != nil && attachmentData!.count > cloverConnector.MAX_PAYLOAD_SIZE) { debugPrint("Error sending message - payload size is greater than the maximum allowed") return nil } - // let's fragment the payload... var fragmentIndex = 0 + // Fragment the Payload var payloadStr = remoteMsg.payload ?? "" - while payloadStr.characters.count > 0 { + while payloadStr.count > 0 { // FRAGMENT Payload - let range = (payloadStr.startIndex ..< payloadStr.characters.index(payloadStr.startIndex, offsetBy: maxMessageSizeInChars < payloadStr.characters.count ? maxMessageSizeInChars : payloadStr.characters.count)) + let range = (payloadStr.startIndex ..< payloadStr.index(payloadStr.startIndex, offsetBy: maxMessageSizeInChars < payloadStr.count ? maxMessageSizeInChars : payloadStr.count)) let fPayload = String(payloadStr[range]) // debugPrint(fragment) payloadStr.removeSubrange(range) - - sendMessageFragment(remoteMessage:remoteMsg, payloadFragment: fPayload, attachmentFragment: nil, fragmentIndex: fragmentIndex, isLastMessage: payloadStr.characters.count == 0 && remoteMsg.attachment?.characters.count ?? 0 == 0 && remoteMsg.attachmentUri?.characters.count ?? 0 == 0 && attachmentData == nil) + sendMessageFragment(remoteMessage:remoteMsg, payloadFragment: fPayload, attachmentFragment: nil, fragmentIndex: fragmentIndex, isLastMessage: payloadStr.count == 0 && remoteMsg.attachment?.count ?? 0 == 0 && remoteMsg.attachmentUri?.count ?? 0 == 0 && attachmentData == nil) fragmentIndex += 1 } - - // now let's fragment the attachment or attachmentData - if var attach = remoteMsg.attachment { - - if remoteMsg.attachmentEncoding == "BASE64" { - // TODO: decode, chunk and then encode or - // set encoding to BASE64.ATTACHMENT - // in this case, change the encoding and chunk as-is - remoteMsg.attachmentEncoding = "BASE64.ATTACHMENT" // must reconstruct the entire attachment before decoding - while attach.characters.count > 0 { - // FRAGMENT Attachment - let range = (attach.startIndex ..< attach.characters.index(attach.startIndex, offsetBy: maxMessageSizeInChars < attach.characters.count ? maxMessageSizeInChars : attach.characters.count)) - - let aPayload = String(attach[range]) - - attach.removeSubrange(range) - - - sendMessageFragment(remoteMessage:remoteMsg, payloadFragment: nil, attachmentFragment: aPayload, fragmentIndex: fragmentIndex, isLastMessage: attach.characters.count == 0) - fragmentIndex += 1 - } - - } else { - // TODO: chunk as-as - } - } else if let data = attachmentData { + // Fragment the attachment + if let data = attachmentData { // Data Attachment, convert to Base64 and send var start = 0 let count = data.count @@ -753,16 +740,12 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { let chunkData = data.subdata(in: start.. count) fragmentIndex += 1 } } - } - - } else { // we DON'T need to fragment if let remoteMsg = Mapper().toJSONString(remoteMsg, prettyPrint: false) { @@ -775,7 +758,7 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { } else { // we cannot send fragments, v1 or attachments - if remoteMsg.attachment != nil || attachmentData != nil || attachmentUrl != nil { + if remoteMsg.attachment != nil || attachmentData != nil { Swift.debugPrint("Version 1 of remote message doesn't support attachments", stderr) } @@ -808,8 +791,6 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { fRemoteMessage.attachment = fAttachment fRemoteMessage.fragmentIndex = index fRemoteMessage.lastFragment = lastFragment - // fRemoteMessage.fragmentTotal = payloadFragments + attachmentFragments - // if let remoteMsg = Mapper().toJSONString(fRemoteMessage, prettyPrint: false) { Swift.debugPrint("Sending Fragment " + String(index) + (lastFragment ? " " : "")) @@ -1172,3 +1153,24 @@ class DefaultCloverDevice : CloverDevice, CloverTransportObserver { } } } + +extension DefaultCloverDevice { + func download(imageURL: URL, completion: @escaping (ImageClass?)->()) { + let session = URLSession(configuration: .default) + let downloadTask = session.dataTask(with: imageURL) { (data, response, error) in + guard error == nil else { + debugPrint("Image download failed: " + error!.localizedDescription) + completion(nil) + return + } + + if let imageData = data, let image = ImageClass(data: imageData) { + completion(image) + } else { + completion(nil) + } + } + + downloadTask.resume() //kick off the download + } +} diff --git a/CloverConnector/Classes/cloverconnector/ICloverConnector.swift b/CloverConnector/Classes/cloverconnector/ICloverConnector.swift index f018cdf..2e7072b 100644 --- a/CloverConnector/Classes/cloverconnector/ICloverConnector.swift +++ b/CloverConnector/Classes/cloverconnector/ICloverConnector.swift @@ -1,10 +1,9 @@ import Foundation /// -/// Interface to the Clover remote-pay API. +/// The CloverConnector API serves as the interface for connecting to a Clover device. /// -/// Defines the interface used to interact with remote pay -/// adapters. +/// This document defines the available methods. /// public protocol ICloverConnector : AnyObject { @@ -18,238 +17,244 @@ public protocol ICloverConnector : AnyObject { var MAX_PAYLOAD_SIZE:Int { get } - - func addCloverConnectorListener(_ cloverConnectorListener:ICloverConnectorListener) -> Void - func removeCloverConnectorListener(_ cloverConnectorListener:ICloverConnectorListener) -> Void - - /// - /// Must be called to initialize the connection to the Clover device before calling any other methods - /// on ICloverConnector + /// Adds a Clover Connector listener. /// - func initializeConnection() -> Void - /** - Request a sale operation. - parameter: SaleRequest - */ - func sale ( _ saleRequest:SaleRequest ) -> Void - + /// - Parameter cloverConnectorListener: The connection listener. + func addCloverConnectorListener(_ cloverConnectorListener:ICloverConnectorListener) -> Void + /// Removes a Clover Connector listener. /// - /// Request an authorization operation. - /// - func auth ( _ authRequest:AuthRequest ) -> Void + /// - Parameter cloverConnectorListener: The connection listener. + func removeCloverConnectorListener(_ cloverConnectorListener:ICloverConnectorListener) -> Void + /// Initializes the connection and starts communication with the Clover device. + /// This is called after the connector is created and listeners have been added to it. + /// initializeConnection() must be called before calling any other method, + /// other than those that add or remove listeners. + func initializeConnection() -> Void - /// - /// Request a preauth operation. - /// + /// Requests a Sale transaction (purchase). + /// + /// - Parameter saleRequest: A SaleRequest object containing basic information for the + /// transaction. + func sale ( _ saleRequest:SaleRequest ) -> Void + + /// Requests an Auth transaction. The tip for an Auth can be adjusted through the + /// TipAdjustAuth() call until the batch Closeout is processed. + /// **Note:** The MerchantInfo.SupportsAuths boolean must be set to true. + /// - Parameter authRequest: The request details. + func auth ( _ authRequest:AuthRequest ) -> Void + + /// Initiates a PreAuth transaction (a pre-authorization for a certain amount). This + /// transaction lets the merchant know whether the account associated with a card has + /// sufficient funds, without actually charging the card. When the merchant is ready + /// to charge a final amount, the POS will call CapturePreAuth() to complete the + /// Payment. + /// **Note:** The MerchantInfo.SupportsPreAuths boolean must be set to true. + /// - Parameter preAuthRequest: The request details. func preAuth ( _ preAuthRequest:PreAuthRequest ) -> Void - - /// - /// Request a preauth be captured. - /// + /// Marks a PreAuth Payment for capture by a Closeout process. After a PreAuth is + /// captured, it is effectively the same as an Auth Payment. **Note:** Should only be + /// called if the request's PaymentID is from a PreAuthResponse. + /// - Parameter capturePreAuthRequest: The request details. func capturePreAuth ( _ capturePreAuthRequest:CapturePreAuthRequest ) -> Void + /// Adjusts the tip for a previous Auth transaction. This call can be made until + /// the Auth Payment has been finalized by a Closeout. + /// **Note:** Should only be called if the request's PaymentID is from an + /// AuthResponse. + /// - Parameter authTipAdjustRequest: The request details. + func tipAdjustAuth ( _ authTipAdjustRequest:TipAdjustAuthRequest ) -> Void - /// - /// Request a tip adjustment to an auth. - /// - func tipAdjustAuth ( _ authTipAdjustRequest:TipAdjustAuthRequest ) -> Void - - - /// - /// Request a payment be voided. - /// + /// Voids a transaction. + /// - Parameter voidPaymentRequest: A VoidRequest object containing basic information needed to void the transaction. func voidPayment ( _ voidPaymentRequest:VoidPaymentRequest ) -> Void - - /// - /// Request a payment be refunded. /// + /// Refunds the full or partial amount of a Payment. + /// - Parameter refundPaymentRequest: The request details. func refundPayment ( _ refundPaymentRequest:RefundPaymentRequest ) -> Void - - /// - /// Request an amount be refunded. - /// + /// Initiates a Manual Refund transaction (a “Refund” or credit + /// that is not associated with a previous Payment). + /// - Parameter manualRefundRequest: A ManualRefundRequest object with the request + /// details. func manualRefund ( _ manualRefundRequest:ManualRefundRequest ) -> Void - - /// - /// Request a cancel be sent to the device. - /// - /// Use resetDevice() or invokeInputOption() with the screen appropriate options instead. - /// + /// Sends a "cancel" button press to the Clover device. /// + /// Use resetDevice() or invokeInputOption() instead. @available(*, deprecated) func cancel () -> Void - - /// - /// Request a closeout. + /// Sends a request to the Clover server to close out all transactions. /// + /// - Parameter closeoutRequest: The request details. func closeout ( _ closeoutRequest:CloseoutRequest ) -> Void - - /// - /// Request receipt options be displayed for a payment. - /// + /// Displays the customer-facing receipt options (print, email, etc.) for a Payment on + /// the Clover device. + /// - Parameter orderId: The ID of the Order associated with the receipt. + /// - Parameter paymentId: The ID of the Payment associated with the receipt. func displayPaymentReceiptOptions(orderId:String, paymentId: String) -> Void - - /// - /// Accept a signature verification request. - /// + /// If a signature is captured during a transaction, this method accepts the signature + /// as entered. + /// - Parameter signatureVerifyRequest: The accepted VerifySignatureRequest the device passed to onVerifySignatureRequest(). func acceptSignature ( _ signatureVerifyRequest:VerifySignatureRequest ) -> Void - - /// - /// Reject a signature verification request. - /// + /// If a signature is captured during a transaction, this method rejects the signature + /// as entered. + /// - Parameter signatureVerifyRequest: The rejected VerifySignatureRequest() the device passed to onVerifySignatureRequest(). func rejectSignature ( _ signatureVerifyRequest:VerifySignatureRequest ) -> Void - - - /// - /// Request to vault a card. - /// + + /// Asks the Clover device to capture card information and request a payment token + /// from the payment gateway. The payment token can be used for future Sale and Auth + /// requests in place of the card details. The merchant account must be configured to + /// allow payment tokens. + /// **Note:** The MerchantInfo.SupportsVaultCards boolean must be set to true. + /// - Parameter vaultCardRequest: The VaultCardRequest details, including the card + /// entry methods allowed to capture the payment token. If the card entry methods are + /// null, the default values (CARD_ENTRY_METHOD_MAG_STRIPE, + /// CARD_ENTRY_METHOD_ICC_CONTACT, and CARD_ENTRY_METHOD_NFC_CONTACTLESS) + /// will be used. func vaultCard ( _ vaultCardRequest:VaultCardRequest ) -> Void - /// - /// Request to print some text on the default printer. + /// Prints custom messages in plain text through the Clover Mini's built-in printer. /// @available(*, deprecated: 1.4.0, message: "use print(_ request:PrintRequest) instead") func printText ( _ lines:[String] ) -> Void /// - /// Request to print an image on the default printer. - /// - /// The size of the image should be limited, and the optimal - /// width of the image is 384 pixels. - /// - /// The img parameter type is implementation specific to the - /// adapter. + /// Prints an image on paper receipts through the Clover Mini's built-in printer. /// - /// - // remove so there isn't a dependency on UIKit and it will work on MacOS @available(*, deprecated: 1.4.0, message: "use print(_ request:PrintRequest) instead") func printImage ( _ image:ImageClass ) -> Void - /// - /// Request to print an image based on a url - /// + /// Prints an image from the web on paper receipts through the Clover device's + /// built-in printer. + /// + /// - Parameter url: The URL for the image to print. @available(*, deprecated: 1.4.0, message: "use print(_ request:PrintRequest) instead") func printImageFromURL(_ url:String) -> Void - /// Request to print - /// - /// - Parameter request: PrintRequest object that contains the information and content needed to print + /// Sends a print request using the PrintRequest object. + /// Used to print text, images, and images from a URL using the specified printer. + /// - Parameter request: The PrintRequest details. func print(_ request:PrintRequest) -> Void - /// Request to retreive available printers + /// Queries available printers attached to the Clover device. /// - /// - Parameter request: RetrievePrintersRequest object that contains additional information to be applied during the request + /// - Parameter request: The RetrievePrintersRequest details. func retrievePrinters(_ request:RetrievePrintersRequest) -> Void - /// Request the status of a given print job + /// Queries the status of a print job. /// - /// - Parameter request: PrintJobStatusRequest object defining the print job to be queried + /// - Parameter request: A PrintJobStatusRequest object containing the request + /// details. func retrievePrintJobStatus(_ request:PrintJobStatusRequest) -> Void - /// Request that the cash drawer connected to the device be opened. - /// - /// - Parameter request: OpenCashDrawerRequest object defining the reason the cash drawer is being opened, and an optional device identifier + /// Opens the first cash drawer found connected to the Clover device. + /// The reason for opening the cash drawer must be set on OpenCashDrawerRequest. + /// - Parameter request: The OpenCashDrawerRequest object defining the reason + /// the cash drawer is being opened, and an optional device identifier. func openCashDrawer(_ request: OpenCashDrawerRequest) -> Void /// - /// Request that the cash drawer connected to the device be opened. Deprecated + /// Opens the cash drawer connected to the Clover device. Deprecated. /// @available(*, deprecated: 1.4.0, message: "use openCashDrawer(_ request: OpenCashDrawerRequest) instead") func openCashDrawer (reason: String) -> Void /// - /// Request to place a message on the device screen. - /// - func showMessage ( _ message:String ) -> Void - + /// Displays a string-based message on the Clover device's screen. + /// - Parameter message: The string message to display. + func showMessage ( _ message:String ) -> Void /// - /// Request to display the default welcome screen on the device. + /// Displays the welcome screen on the Clover device. /// func showWelcomeScreen () -> Void - /// - /// Request to display the default thank you screen on the device. + /// Displays the thank you screen on the Clover device. /// func showThankYouScreen () -> Void - - /// - /// Request to display an order on the device. - /// + /// Displays an Order and associated lineItems on the Clover device. Will replace an + /// Order that is already displayed on the device screen. + /// - Parameter order: The Order to display. func showDisplayOrder ( _ order:DisplayOrder ) -> Void - - /// - /// Request to display an order on the device. - /// + /// Removes the DisplayOrder object from the Clover device's screen. + /// + /// - Parameter order: The Order to remove. func removeDisplayOrder ( _ order:DisplayOrder ) -> Void - /// - /// sends a reset request to the device if the POS and device get out of sync. - /// + /// Sends a request to reset the Clover device back to the welcome screen. Can be used + /// when the device is in an unknown or invalid state from the perspective of the POS. + /// **Note:** This request could cause the POS to miss a transaction or other + /// information. Use cautiously as a last resort. func resetDevice ( ) -> Void - /// - /// - /// + /// Sends a keystroke to the Clover device that invokes an input option (OK, + /// CANCEL, DONE, etc.) on the customer's behalf. + /// InputOptions are on the CloverDeviceEvent passed to onDeviceActivityStart(). + /// - Parameter inputOption: The input option to invoke. func invokeInputOption( _ inputOption:InputOption ) -> Void + /// Requests card information (specifically Track 1 and Track 2 card data). /// - /// Used to request card information. Specifically track1 and track2 information - /// + /// - Parameter request: The ReadCardDataRequest details. func readCardData( _ request:ReadCardDataRequest ) -> Void - /// - /// If payment confirmation is required during a Sale, this method accepts the payment - /// + /// If Payment confirmation is required during a transaction due to a Challenge, + /// this method accepts the Payment. A Challenge may be triggered + /// by a potential duplicate Payment or an offline Payment. + /// - Parameter payment: The Payment to accept. func acceptPayment( _ payment:CLVModels.Payments.Payment ) -> Void - /// - /// If payment confirmation is required during a Sale, this method rejects the payment - /// + /// If Payment confirmation is required during a transaction due to a Challenge, + /// this method rejects the Payment. A Challenge may be triggered + /// by a potential duplicate Payment or an offline Payment. + /// - Parameter payment: The Payment to reject. + /// - Parameter challenge: The Challenge that resulted in Payment rejection. func rejectPayment( _ payment:CLVModels.Payments.Payment, challenge:Challenge ) -> Void /// - /// Used to request a list of pending payments that have been taken offline, but - /// haven't processed yet. will trigger an onRetrievePendingPaymentsResponse callback + /// Retrieves a list of unprocessed Payments that were taken offline + /// and are pending submission to the server. /// func retrievePendingPayments() -> Void - /** - * Disposes the connector and any connections created by the connector. - */ + /// Disposes the connection to the Clover device. After this is called, the + /// connection to the device is severed, and the CloverConnector object is no longer + /// usable. Instantiate a new CloverConnector object in order to call + /// initializeConnection(). func dispose() -> Void + /// Starts a Custom Activity on the Clover device. /// - /// start an custom activity on the device - /// + /// - Parameter request: The CustomActivityRequest details. func startCustomActivity(_ request:CustomActivityRequest) -> Void + /// Sends a message to a Custom Activity running on a Clover device. /// - /// send a message to a currently running custom activity - /// + /// - Parameter request: The MessageToActivity request with the message to send to the + /// Custom Activity. func sendMessageToActivity(_ request:MessageToActivity) -> Void + /// Sends a message requesting the current status of the Clover device. /// - /// request the current status of the device - /// + /// - Parameter request: The RetrieveDeviceStatusRequest details. func retrieveDeviceStatus(_ _request: RetrieveDeviceStatusRequest) -> Void - /// - /// request the payment for a given external id - /// + /// Requests the Payment information corresponding to the externalPaymentId + /// passed in. + /// Only valid for Payments made in the past 24 hours on the Clover device queried. + /// - Parameter request: The RetrievePaymentRequest details. func retrievePayment(_ _request: RetrievePaymentRequest) -> Void + } diff --git a/CloverConnector/Classes/cloverconnector/ICloverConnectorListener.swift b/CloverConnector/Classes/cloverconnector/ICloverConnectorListener.swift index 0bc6c5f..7cf02fb 100644 --- a/CloverConnector/Classes/cloverconnector/ICloverConnectorListener.swift +++ b/CloverConnector/Classes/cloverconnector/ICloverConnectorListener.swift @@ -1,210 +1,205 @@ -/** - * Autogenerated by Avro - * - * DO NOT EDIT DIRECTLY - */ import Foundation //import CloverSDKRemotepay /* - * Interface to the Clover remote-pay API. + * The CloverConnector API serves as the interface for connecting to a Clover device. * - * Defines the interface used to interact with remote pay - * adapters. + * This document defines the available methods. */ public protocol ICloverConnectorListener : AnyObject { - /* - * Response to a sale request. - */ - func onSaleResponse ( _ response:SaleResponse ) -> Void - - - /* - * Response to an authorization operation. - */ + /// Called at the completion of a Sale() request. The SaleResponse contains a + /// ResultCode and a Success boolean. A successful Sale transaction will also have + /// the payment object, which can be for the full or partial amount of the Sale + /// request. + /// **Note:** A Sale transaction may come back as a tip-adjustable Auth, depending on + /// the payment gateway. The SaleResponse has a boolean isSale flag that + /// indicates whether the sale is final, or will be finalized during closeout. + /// - Parameter response: The response to the transaction request. + func onSaleResponse ( _ response:SaleResponse ) -> Void + + /// Called in response to an Auth() request. **Note:** An Auth transaction may come + /// back as a final Sale, depending on the payment gateway. The AuthResponse has + /// a boolean isAuth flag that indicates whether the Payment can still be + /// tip-adjusted. + /// - Parameter authResponse: The response to the transaction request. func onAuthResponse ( _ authResponse:AuthResponse ) -> Void - - /* - * Response to a preauth operation. - */ + /// Called in response to a PreAuth() request. **Note:** The boolean isPreAuth flag + /// in the PreAuthResponse indicates whether CapturePreAuth() can be called + /// for the returned Payment. If the isPreAuth flag is false and the isAuth flag is + /// true, then the payment gateway coerced the PreAuth() request to an Auth. + /// The payment will need to be voided or it will be automatically captured at + /// closeout. + /// - Parameter preAuthResponse: The response to the transaction request. func onPreAuthResponse ( _ preAuthResponse:PreAuthResponse ) -> Void - /* - * Response to a preauth being captured. - */ - func onCapturePreAuthResponse ( _ capturePreAuthResponse:CapturePreAuthResponse ) -> Void - - - /* - * Response to a tip adjustment for an auth. - */ - func onTipAdjustAuthResponse ( _ tipAdjustAuthResponse:TipAdjustAuthResponse ) -> Void - - - /* - * Response to a payment be voided. - */ + /// Called in response to a CapturePreAuth() request. + /// Contains the new Amount and TipAmount if successful. + /// - Parameter capturePreAuthResponse: The response to the transaction request. + func onCapturePreAuthResponse ( _ capturePreAuthResponse:CapturePreAuthResponse ) -> Void + + /// Called in response to a tip adjustment for an Auth transaction. + /// Contains the tipAmount if successful. + /// - Parameter tipAdjustAuthResponse: The response to the transaction request. + func onTipAdjustAuthResponse ( _ tipAdjustAuthResponse:TipAdjustAuthResponse ) -> Void + + /// Called in response to a voidPayment() request. Contains a + /// [ResultCode](https://clover.github.io/remote-pay-ios/1.4.0/docs/Enums/ResultCode.html) + /// and a Success boolean. If successful, the response will also contain the + /// paymentId for the voided Payment. + /// - Parameter voidPaymentResponse: The response to the transaction request. func onVoidPaymentResponse ( _ voidPaymentResponse:VoidPaymentResponse ) -> Void - /* - * Response to a payment being refunded. - */ + /// Called in response to a RefundPayment() request. Contains a + /// [ResultCode](https://clover.github.io/remote-pay-ios/1.4.0/docs/Enums/ResultCode.html) + /// and a Success boolean. The response to a successful transaction will contain the + /// Refund. The Refund includes the original paymentId as a reference. + /// - Parameter refundPaymentResponse: The response to the transaction request. func onRefundPaymentResponse ( _ refundPaymentResponse:RefundPaymentResponse ) -> Void + /// Called in response to a manualRefund() request. Contains a + /// [ResultCode](https://clover.github.io/remote-pay-ios/1.4.0/docs/Enums/ResultCode.html) + /// and a Success boolean. If successful, the ManualRefundResponse will have + /// a Credit object associated with the relevant Payment information. + /// - Parameter manualRefundResponse: The response to the transaction request. + func onManualRefundResponse ( _ manualRefundResponse:ManualRefundResponse ) -> Void - /* - * Response to an amount being refunded. - */ - func onManualRefundResponse ( _ manualRefundResponse:ManualRefundResponse ) -> Void - - - /* - * Response to a closeout. - */ + /// Called in response to a Closeout() request. + /// - Parameter closeoutResponse: The response to the transaction request. func onCloseoutResponse ( _ closeoutResponse:CloseoutResponse ) -> Void - - /* - * Receives signature verification requests. - */ + /// Called when the Clover device requests verification for a user's on-screen + /// signature. The Payment and Signature will be passed in. + /// - Parameter signatureVerifyRequest: The verification request. func onVerifySignatureRequest ( _ signatureVerifyRequest:VerifySignatureRequest ) -> Void - - /* - * Response to vault a card. - */ + /// Called in response to a vaultCard() request. Contains a + /// [ResultCode](https://clover.github.io/remote-pay-ios/1.4.0/docs/Enums/ResultCode.html) + /// and a Success boolean. If successful, the response will contain a VaultedCard + /// object with a token value that's unique for the card and merchant. The token + /// can be used for future Sale() and Auth() requests. + /// - Parameter vaultCardResponse: The response to the request. func onVaultCardResponse ( _ vaultCardResponse:VaultCardResponse ) -> Void - /* - * - */ - + /// Called when the Clover device transitions to a new screen or activity. + /// The CloverDeviceEvent passed in will contain an event type, a description, + /// and a list of available InputOptions. + /// - Parameter deviceEvent: The device event. func onDeviceActivityStart( _ deviceEvent: CloverDeviceEvent ) -> Void + /// Called when the Clover device transitions away from a screen or activity. + /// The CloverDeviceEvent passed in will contain an event type and description. + /// **Note:** The start and end events are not guaranteed to process in order. + /// The event type should be used to make sure these events are paired. + /// - Parameter deviceEvent: The device event. func onDeviceActivityEnd( _ deviceEvent: CloverDeviceEvent ) -> Void + /// Called when an error occurs while trying to send messages to the Clover + /// device. + /// - Parameter deviceErrorEvent: The device error event. func onDeviceError( _ deviceErrorEvent: CloverDeviceErrorEvent ) -> Void - /* - * called when the device is initially connected - */ + /// Called when the Clover device is initially connected, but not ready to + /// communicate. func onDeviceConnected () -> Void - - /* - * called when the device is ready to communicate - */ + /// Called when the Clover device is ready to communicate and respond to requests. + /// - Parameter merchantInfo: The merchant information to associate with the device. func onDeviceReady (_ merchantInfo: MerchantInfo) -> Void - - /* - * called when the device is disconnected, or not responding - */ + /// Called when the Clover device is disconnected from the CloverConnector or not + /// responding. func onDeviceDisconnected () -> Void - /** - * Called when the Clover device requires confirmation for a payment - * e.g. Duplicates or Offline - * @param request - */ - + /// Called when the Clover device encounters a Challenge at the payment gateway + /// and requires confirmation. A Challenge is triggered by a potential + /// duplicate Payment (DUPLICATE_CHALLENGE) or an offline Payment + /// (OFFLINE_CHALLENGE). The device sends a ConfirmPaymentRequest() + /// asking the merchant to reply by sending either an AcceptPayment() or + /// RejectPayment() call. + /// + /// Note that duplicate Payment Challenges are raised when multiple Payments + /// are made with the same card type and last four digits within the same hour. + /// For this reason, we recommend that you do not programmatically call + /// CloverConnector.RejectPayment() on all instances of DUPLICATE_CHALLENGE. + /// For more information, see [Working with + /// Challenges](https://docs.clover.com/build/working-with-challenges/). + /// - Parameter request: The request for confirmation. func onConfirmPaymentRequest(_ request:ConfirmPaymentRequest) -> Void - /** - * Called when a customer selects a tip amount on the Clover device screen - * @param message - */ - func onTipAdded(_ message:TipAddedMessage) -> Void + /// Called when a customer selects a tip amount on the Clover device's screen. + /// - Parameter message: The TipAddedMessage. + func onTipAdded(_ message:TipAddedMessage) -> Void - - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a receipt for a ManualRefund - * @param printManualRefundReceiptMessage - */ + /// Called when a user requests a paper receipt for a Manual Refund. Will only be + /// called if disablePrinting = true on the ManualRefund() request. + /// - Parameter printManualRefundReceiptMessage: A callback that asks the POS to print a receipt for a ManualRefund. Contains a Credit object. func onPrintManualRefundReceipt(_ printManualRefundReceiptMessage:PrintManualRefundReceiptMessage) -> Void - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a receipt for a declined ManualRefund - * @param printManualRefundDeclineReceiptMessage - */ + + /// Called when a user requests a paper receipt for a declined Manual Refund. Will + /// only be called if disablePrinting = true on the ManualRefund() request. + /// - Parameter printManualRefundDeclineReceiptMessage: The PrintManualRefundDeclineReceiptMessage. func onPrintManualRefundDeclineReceipt(_ printManualRefundDeclineReceiptMessage:PrintManualRefundDeclineReceiptMessage) -> Void - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a receipt for a payment - * @param printPaymentReceiptMessage - */ + /// Called when a user requests a paper receipt for a Payment. Will only be called if + /// disablePrinting = true on the Sale(), Auth(), or PreAuth() request. + /// - Parameter printPaymentReceiptMessage: The message. func onPrintPaymentReceipt(_ printPaymentReceiptMessage:PrintPaymentReceiptMessage) - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a receipt for a declined payment - * @param printPaymentDeclineReceiptMessage - */ + /// Called when a user requests a paper receipt for a declined Payment. Will only be + /// called if disablePrinting = true on the Sale(), Auth(), or PreAuth() request. + /// - Parameter printPaymentDeclineReceiptMessage: The message. func onPrintPaymentDeclineReceipt(_ printPaymentDeclineReceiptMessage:PrintPaymentDeclineReceiptMessage) - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a merchant copy of a payment receipt - * @param printPaymentMerchantCopyReceiptMessage - */ + /// Called when a user requests a merchant copy of a Payment receipt. Will only be + /// called if disablePrinting = true on the Sale(), Auth(), or PreAuth() request. + /// - Parameter printPaymentMerchantCopyReceiptMessage: The message. func onPrintPaymentMerchantCopyReceipt(_ printPaymentMerchantCopyReceiptMessage:PrintPaymentMerchantCopyReceiptMessage) -> Void - /** - * Will only be called if disablePrinting = true on the Sale, Auth, PreAuth or ManualRefund Request - * Called when a user requests to print a receipt for a payment refund - * @param printRefundPaymentReceiptMessage - */ + /// Called when a user requests a paper receipt for a Payment Refund. Will only be + /// called if disablePrinting = true on the Sale(), Auth(), PreAuth() or + /// ManualRefund() request. + /// - Parameter printRefundPaymentReceiptMessage: The message. func onPrintRefundPaymentReceipt(_ printRefundPaymentReceiptMessage:PrintRefundPaymentReceiptMessage) -> Void - /// Called in response to a retrievePrinters() request + /// Called in response to a retrievePrinters() request. /// - /// - Parameter retrievePrintersResponse: Response object containing an array of the printers being passed back + /// - Parameter retrievePrintersResponse: The response to the request. func onRetrievePrintersResponse(_ retrievePrintersResponse:RetrievePrintersResponse) -> Void - /// Called to update the status of a print job + /// Called in response to a retrievePrintJobStatus() request. /// - /// - Parameter printJobStatusResponse: Object containing the print job identifier and that job's status + /// - Parameter printJobStatusResponse: The response to the request. func onPrintJobStatusResponse(_ printJobStatusResponse:PrintJobStatusResponse) -> Void - /** - * Called in response to a retrievePendingPayment(...) request. - * @param retrievePendingPaymentResponse - */ + /// Called in response to a retrievePendingPayment() request. + /// - Parameter retrievePendingPaymentResponse: The response to the request. func onRetrievePendingPaymentsResponse(_ retrievePendingPaymentResponse:RetrievePendingPaymentsResponse) -> Void - /* - * called in response to a readCardData request - */ + /// Called in response to a readCardData() request. + /// - Parameter readCardDataResponse: The response to the request. func onReadCardDataResponse(_ readCardDataResponse:ReadCardDataResponse) -> Void - /* - * called in response to a custom activity finishing - */ + /// Called when a Custom Activity finishes normally. + /// - Parameter customActivityResponse: The CustomActivityResponse. func onCustomActivityResponse(_ customActivityResponse:CustomActivityResponse) -> Void - /* - * called in response to a device reset request - */ + /// Called in response to a ResetDevice() request. + /// - Parameter response: The response to the request. func onResetDeviceResponse(_ response:ResetDeviceResponse) -> Void - /* - * called when a custom activity sends a message to the POS - */ + /// Called when a Custom Activity sends a message to the POS. + /// - Parameter response: The message. func onMessageFromActivity(_ response:MessageFromActivity) -> Void - /* - * called in response to a retrieve payment request - */ + /// Called in response to a RetrievePayment() request. + /// - Parameter response: The response to the request. func onRetrievePaymentResponse(_ response:RetrievePaymentResponse) -> Void - /* - * called in response to a retrieveDeviceStatus request - */ - func onRetrieveDeviceStatusResponse(_ _response: RetrieveDeviceStatusResponse) -> Void + /// Called in response to a RetrieveDeviceStatus() request. + /// - Parameter response: The response to the request. + func onRetrieveDeviceStatusResponse(_ response: RetrieveDeviceStatusResponse) -> Void } diff --git a/CloverConnector/Classes/cloverconnector/CloverDeviceConfiguration.swift b/CloverConnector/Classes/cloverconnector/Transport/CloverDeviceConfiguration.swift similarity index 100% rename from CloverConnector/Classes/cloverconnector/CloverDeviceConfiguration.swift rename to CloverConnector/Classes/cloverconnector/Transport/CloverDeviceConfiguration.swift diff --git a/CloverConnector/Classes/cloverconnector/CloverTransport.swift b/CloverConnector/Classes/cloverconnector/Transport/CloverTransport.swift similarity index 100% rename from CloverConnector/Classes/cloverconnector/CloverTransport.swift rename to CloverConnector/Classes/cloverconnector/Transport/CloverTransport.swift diff --git a/CloverConnector/Classes/cloverconnector/CloverTransportObserver.swift b/CloverConnector/Classes/cloverconnector/Transport/CloverTransportObserver.swift similarity index 100% rename from CloverConnector/Classes/cloverconnector/CloverTransportObserver.swift rename to CloverConnector/Classes/cloverconnector/Transport/CloverTransportObserver.swift diff --git a/CloverConnector/Classes/cloverconnector/WebSocketCloverTransport.swift b/CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketCloverTransport.swift similarity index 99% rename from CloverConnector/Classes/cloverconnector/WebSocketCloverTransport.swift rename to CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketCloverTransport.swift index 389239c..371ff7e 100644 --- a/CloverConnector/Classes/cloverconnector/WebSocketCloverTransport.swift +++ b/CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketCloverTransport.swift @@ -330,7 +330,7 @@ class WebSocketCloverTransport: CloverTransport { @discardableResult override func sendMessage(_ message: String) -> Int { // debugPrint("Sending raw message: " + message) - debugPrint("Sending raw message: " + String(message.characters.count)) + debugPrint("Sending raw message: " + String(message.count)) if let socket = socket { socket.write(string: message) } diff --git a/CloverConnector/Classes/cloverconnector/WebSocketDeviceConfiguration.swift b/CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketDeviceConfiguration.swift similarity index 93% rename from CloverConnector/Classes/cloverconnector/WebSocketDeviceConfiguration.swift rename to CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketDeviceConfiguration.swift index 2305486..06cb9e2 100644 --- a/CloverConnector/Classes/cloverconnector/WebSocketDeviceConfiguration.swift +++ b/CloverConnector/Classes/cloverconnector/Transport/Web Socket/WebSocketDeviceConfiguration.swift @@ -29,11 +29,7 @@ public class WebSocketDeviceConfiguration : NSObject, CloverDeviceConfiguration public var maxCharInMessage:Int = 50000 - public var remoteSourceSDK:String { - get { - return "com.cloverconnector.ios.ws:1.3.1-RC2" - } - } + public private(set) var remoteSourceSDK:String = "com.cloverconnector.ios.ws" deinit { debugPrint("deinit WebSocketDeviceConfiguration") @@ -46,6 +42,10 @@ public class WebSocketDeviceConfiguration : NSObject, CloverDeviceConfiguration self.posSerialNumber = posSerial self.pairingAuthToken = pairingAuthToken self.pairingConfig = pairingDeviceConfiguration + + if let version = Bundle.allFrameworks.filter({$0.bundleIdentifier != nil && $0.bundleIdentifier!.hasSuffix("CloverConnector")}).first?.infoDictionary?["CFBundleShortVersionString"] { + remoteSourceSDK = "com.cloverconnector.ios.ws:\(version)" + } } public func getTransport() -> CloverTransport? { diff --git a/CloverConnector/Classes/cloverconnector/api/PrintJobStatusResponse.swift b/CloverConnector/Classes/cloverconnector/api/PrintJobStatusResponse.swift index 9f85940..e84e17d 100644 --- a/CloverConnector/Classes/cloverconnector/api/PrintJobStatusResponse.swift +++ b/CloverConnector/Classes/cloverconnector/api/PrintJobStatusResponse.swift @@ -6,8 +6,9 @@ // import Foundation +import ObjectMapper -public class PrintJobStatusResponse: NSObject { +public class PrintJobStatusResponse: BaseResponse { public fileprivate(set) var printRequestId: String? public fileprivate(set) var status: PrintJobStatus @@ -16,6 +17,8 @@ public class PrintJobStatusResponse: NSObject { guard let status = status else { self.status = .ERROR + super.init() + self.success = false //we expect a status from the server, so consider the query a failure if we don't have it return } @@ -36,6 +39,14 @@ public class PrintJobStatusResponse: NSObject { default: self.status = .ERROR } + + super.init() + self.success = true //the request is considered successful if we got a status + } + + required public init?(map:Map) { //shouldn't init through here, so default to failure if we do + self.status = .ERROR + super.init(success: false, result: .FAIL) } } diff --git a/CloverConnector/Classes/cloverconnector/api/PrintRequest.swift b/CloverConnector/Classes/cloverconnector/api/PrintRequest.swift index bd63e7c..0c4eae7 100644 --- a/CloverConnector/Classes/cloverconnector/api/PrintRequest.swift +++ b/CloverConnector/Classes/cloverconnector/api/PrintRequest.swift @@ -5,11 +5,14 @@ import Foundation public class PrintRequest: NSObject { - //Private data source for the print request. These should not be modifiable externally, because for now we want to enforce the encompassed print data via constructors - public fileprivate(set) var images = [ImageClass]() - public fileprivate(set) var imageURLS = [URL]() - public fileprivate(set) var text = [String]() + //Private data source for the print request. These should not be modifiable externally, because for now we want to enforce the encompassed print data via constructors + internal fileprivate(set) var images = [ImageClass]() + internal fileprivate(set) var imageURLS = [URL]() + internal fileprivate(set) var text = [String]() + + /// Optional identifier to give to the print job, so it can later be queried public var printRequestId: String? + /// Optional identifier to speciy which printer to use public var printDeviceId: String? diff --git a/CloverConnector/Classes/cloverconnector/api/RetrievePrintersResponse.swift b/CloverConnector/Classes/cloverconnector/api/RetrievePrintersResponse.swift index fc14fb8..c8cf4ae 100644 --- a/CloverConnector/Classes/cloverconnector/api/RetrievePrintersResponse.swift +++ b/CloverConnector/Classes/cloverconnector/api/RetrievePrintersResponse.swift @@ -6,11 +6,23 @@ // import Foundation +import ObjectMapper -public class RetrievePrintersResponse: NSObject { +public class RetrievePrintersResponse: BaseResponse { public fileprivate(set) var printers: [CLVModels.Printer.Printer]? init(_ printers: [CLVModels.Printer.Printer]?) { + //success status isn't explicitly provided by the server, so we consider it a "success" if printers array is non-nil + if printers != nil { + super.init(success: true, result: .SUCCESS) + } else { + super.init(success: false, result: .ERROR) + } + self.printers = printers } + + required public init?(map:Map) { + super.init(success: false, result: .FAIL) //shouldn't init here, so default to failure if we do + } } diff --git a/CloverConnector/Classes/remotepaylib/CloverDeviceEvent.swift b/CloverConnector/Classes/remotepaylib/CloverDeviceEvent.swift index 5117967..ddac61b 100644 --- a/CloverConnector/Classes/remotepaylib/CloverDeviceEvent.swift +++ b/CloverConnector/Classes/remotepaylib/CloverDeviceEvent.swift @@ -11,62 +11,64 @@ import ObjectMapper public class CloverDeviceEvent:NSObject, Mappable { - public enum DeviceEventState { + public enum DeviceEventState:String { // payment flow - case start - case failed - case fatal - case try_AGAIN - case input_ERROR - case pin_BYPASS_CONFIRM - case canceled - case timed_OUT - case declined - case voided - case configurnig - case processing - case remove_CARD - case processing_GO_ONLINE - case processing_CREDIT - case processing_SWIPE - case select_APPLICATION - case pin_PAD - case manual_CARD_NUMBER - case manual_CARD_CVV - case manual_CARD_CVV_UNREADABLE - case manual_CARD_EXPIRATION - case select_ACCOUNT - case cashback_CONFIRM - case cashback_SELECT - case contactless_TAP_REQUIRED - case voice_REFERRAL_RESULT - case confirm_PARTIAL_AUTH - case packet_EXCEPTION - case confirm_DUPLICATE_CHECK + case START = "START" + case FAILED = "FAILED" + case FATAL = "FATAL" + case TRY_AGAIN = "TRY_AGAIN" + case INPUT_ERROR = "INPUT_ERROR" + case PIN_BYPASS_CONFIRM = "PIN_BYPASS_CONFIRM" + case CANCELED = "CANCELED" + case TIMED_OUT = "TIMED_OUT" + case DECLINED = "DECLINED" + case VOIDED = "VOIDED" + case CONFIGURING = "CONFIGURING" + case PROCESSING = "PROCESSING" + case REMOVE_CARD = "REMOVE_CARD" + case PROCESSING_GO_ONLINE = "PROCESSING_GO_ONLINE" + case PROCESSING_CREDIT = "PROCESSING_CREDIT" + case PROCESSING_SWIPE = "PROCESSING_SWIPE" + case SELECT_APPLICATION = "SELECT_APPLICATION" + case PIN_PAD = "PIN_PAD" + case MANUAL_CARD_NUMBER = "MANUAL_CARD_NUMBER" + case MANUAL_CARD_CVV = "MANUAL_CARD_CVV" + case MANUAL_CARD_CVV_UNREADABLE = "MANUAL_CARD_CVV_UNREADABLE" + case MANUAL_CARD_EXPIRATION = "MANUAL_CARD_EXPIRATION" + case SELECT_ACCOUNT = "SELECT_ACCOUNT" + case CASHBACK_CONFIRM = "CASHBACK_CONFIRM" + case CASHBACK_SELECT = "CASHBACK_SELECT" + case CONTACTLESS_TAP_REQUIRED = "CONTACTLESS_TAP_REQUIRED" + case VOICE_REFERRAL_RESULT = "VOICE_REFERRAL_RESULT" + case CONFIRM_PARTIAL_AUTH = "CONFIRM_PARTIAL_AUTH" + case PACKET_EXCEPTION = "PACKET_EXCEPTION" + case CONFIRM_DUPLICATE_CHECK = "CONFIRM_DUPLICATE_CHECK" // verify CVM flow - case verify_SIGNATURE_ON_PAPER - case verify_SIGNATURE_ON_PAPER_CONFIRM_VOID - case verify_SIGNATURE_ON_SCREEN - case verify_SIGNATURE_ON_SCREEN_CONFIRM_VOID - case add_SIGNATURE - case signature_ON_SCREEN_FALLBACK - case return_TO_MERCHANT - case signature_REJECT - case add_SIGNATURE_CANCEL_CONFIRM - + case VERIFY_SIGNATURE_ON_PAPER = "VERIFY_SIGNATURE_ON_PAPER" + case VERIFY_SIGNATURE_ON_PAPER_CONFIRM_VOID = "VERIFY_SIGNATURE_ON_PAPER_CONFIRM_VOID" + case VERIFY_SIGNATURE_ON_SCREEN = "VERIFY_SIGNATURE_ON_SCREEN" + case VERIFY_SIGNATURE_ON_SCREEN_CONFIRM_VOID = "VERIFY_SIGNATURE_ON_SCREEN_CONFIRM_VOID" + case ADD_SIGNATURE = "ADD_SIGNATURE" + case SIGNATURE_ON_SCREEN_FALLBACK = "SIGNATURE_ON_SCREEN_FALLBACK" + case RETURN_TO_MERCHANT = "RETURN_TO_MERCHANT" + case SIGNATURE_REJECT = "SIGNATURE_REJECT" + case ADD_SIGNATURE_CANCEL_CONFIRM = "ADD_SIGNATURE_CANCEL_CONFIRM" + // add tip flow - case add_TIP - + case ADD_TIP = "ADD_TIP" + // receipt options flow - case receipt_OPTIONS - + case RECEIPT_OPTIONS = "RECEIPT_OPTIONS" + // tender handling flow - case handle_TENDER + case HANDLE_TENDER = "HANDLE_TENDER" + + // starting custom activity, called from RTKA + case STARTING_CUSTOM_ACTIVITY = "STARTING_CUSTOM_ACTIVITY" } -// public var eventState:DeviceEventState? - public var eventState:String? + public var eventState:DeviceEventState? public var code:Int? public var message:String? public var inputOptions:[InputOption]? @@ -79,7 +81,7 @@ public class CloverDeviceEvent:NSObject, Mappable { super.init() } - public init(eventState:String?, message:String?, inputOptions:[InputOption]? = nil) { + public init(eventState:DeviceEventState?, message:String?, inputOptions:[InputOption]? = nil) { self.eventState = eventState self.message = message self.inputOptions = inputOptions diff --git a/CloverConnector/Classes/remotepaylib/UiStateMessage.swift b/CloverConnector/Classes/remotepaylib/UiStateMessage.swift index fc35b85..1c78bd2 100644 --- a/CloverConnector/Classes/remotepaylib/UiStateMessage.swift +++ b/CloverConnector/Classes/remotepaylib/UiStateMessage.swift @@ -10,6 +10,7 @@ import Foundation import ObjectMapper public enum UiState :String{ + // payment flow case START = "START" case FAILED = "FAILED" case FATAL = "FATAL" @@ -41,6 +42,8 @@ public enum UiState :String{ case PACKET_EXCEPTION = "PACKET_EXCEPTION" case CONFIRM_DUPLICATE_CHECK = "CONFIRM_DUPLICATE_CHECK" case FORCE_ACCEPTANCE = "FORCE_ACCEPTANCE" + + // verify CVM flow case VERIFY_SIGNATURE_ON_PAPER = "VERIFY_SIGNATURE_ON_PAPER" case VERIFY_SIGNATURE_ON_PAPER_CONFIRM_VOID = "VERIFY_SIGNATURE_ON_PAPER_CONFIRM_VOID" case VERIFY_SIGNATURE_ON_SCREEN = "VERIFY_SIGNATURE_ON_SCREEN" @@ -50,12 +53,26 @@ public enum UiState :String{ case RETURN_TO_MERCHANT = "RETURN_TO_MERCHANT" case SIGNATURE_REJECT = "SIGNATURE_REJECT" case ADD_SIGNATURE_CANCEL_CONFIRM = "ADD_SIGNATURE_CANCEL_CONFIRM" + + // add tip flow case ADD_TIP = "ADD_TIP" + + // receipt options flow case RECEIPT_OPTIONS = "RECEIPT_OPTIONS" + + // tender handling flow case HANDLE_TENDER = "HANDLE_TENDER" + // for DCPOS language selection case SELECT_LANGUAGE = "SELECT_LANGUAGE" + // for DCPOS final approved screen case APPROVED = "APPROVED" + + // offline payments case OFFLINE_PAYMENT_CONFIRM = "OFFLINE_PAYMENT_CONFIRM" + // custom activity, optionally called from custom activity + case CUSTOM_ACTIVITY = "CUSTOM_ACTIVITY" + // starting custom activity, called from RTKA + case STARTING_CUSTOM_ACTIVITY = "STARTING_CUSTOM_ACTIVITY" public enum UiDirection:String { case ENTER = "ENTER" diff --git a/Example/.jazzy.yaml b/Example/.jazzy.yaml index 6895601..3080bab 100644 --- a/Example/.jazzy.yaml +++ b/Example/.jazzy.yaml @@ -3,11 +3,11 @@ theme: fullwidth podspec: ../CloverConnector.podspec module: CloverConnector theme: apple -output: ../1.4.0/docs +output: ../1.4.1/docs clean: true github-url: https://github.com/clover/remote-pay-ios swift-version: 4.0 -copyright: 'Copyright © 2017 Clover Network, Inc. All rights reserved.' +copyright: 'Copyright © 2018 Clover Network, Inc. All rights reserved.' custom_categories: - name: API children: diff --git a/Example/CloverConnector.xcodeproj/project.pbxproj b/Example/CloverConnector.xcodeproj/project.pbxproj index 4295877..2cfb08c 100644 --- a/Example/CloverConnector.xcodeproj/project.pbxproj +++ b/Example/CloverConnector.xcodeproj/project.pbxproj @@ -50,6 +50,12 @@ 7EEB720D1EAFFA81008E641D /* SimpleTestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EEB720C1EAFFA81008E641D /* SimpleTestViewController.swift */; }; A49F5B4A199432BBE7EAF0C4 /* Pods_CloverConnector_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60BF16A62156B0D50E349B58 /* Pods_CloverConnector_Tests.framework */; }; DA6BFE5D963C68DE0967E1A7 /* Pods_CloverConnector_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95D7B135DBBE64C88249EB84 /* Pods_CloverConnector_Example.framework */; }; + E33CF77A1F97F02C00C41BF8 /* Test_cloverconnector_DefaultCloverConnectorV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33CF7791F97F02C00C41BF8 /* Test_cloverconnector_DefaultCloverConnectorV2.swift */; }; + E33CF7801F98128B00C41BF8 /* TestDeviceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33CF77F1F98125200C41BF8 /* TestDeviceConfiguration.swift */; }; + E33CF7811F98128D00C41BF8 /* TestCloverTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33CF77E1F98125200C41BF8 /* TestCloverTransport.swift */; }; + E33CF7841F9814D700C41BF8 /* Test_remotepaylib_TerminalMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33CF7831F9814D700C41BF8 /* Test_remotepaylib_TerminalMessage.swift */; }; + E33CF7851F98150C00C41BF8 /* TestSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33CF7821F9814CA00C41BF8 /* TestSupport.swift */; }; + E3E4094A1F97B6A000DC7F10 /* Test_cloverconnector_WebSocketDeviceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3E409491F97B6A000DC7F10 /* Test_cloverconnector_WebSocketDeviceConfiguration.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -139,6 +145,12 @@ 96C5AB5C4427777EBE65CA2A /* Pods-CloverConnector_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CloverConnector_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CloverConnector_Example/Pods-CloverConnector_Example.release.xcconfig"; sourceTree = ""; }; CDC378D57D87133CA0103944 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; DA004E9F68C5A4678FD062F7 /* Pods-CloverConnector_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CloverConnector_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CloverConnector_Tests/Pods-CloverConnector_Tests.debug.xcconfig"; sourceTree = ""; }; + E33CF7791F97F02C00C41BF8 /* Test_cloverconnector_DefaultCloverConnectorV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test_cloverconnector_DefaultCloverConnectorV2.swift; sourceTree = ""; }; + E33CF77E1F98125200C41BF8 /* TestCloverTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCloverTransport.swift; sourceTree = ""; }; + E33CF77F1F98125200C41BF8 /* TestDeviceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDeviceConfiguration.swift; sourceTree = ""; }; + E33CF7821F9814CA00C41BF8 /* TestSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSupport.swift; sourceTree = ""; }; + E33CF7831F9814D700C41BF8 /* Test_remotepaylib_TerminalMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test_remotepaylib_TerminalMessage.swift; sourceTree = ""; }; + E3E409491F97B6A000DC7F10 /* Test_cloverconnector_WebSocketDeviceConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test_cloverconnector_WebSocketDeviceConfiguration.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -235,6 +247,8 @@ isa = PBXGroup; children = ( 607FACE91AFB9204008FA782 /* Supporting Files */, + E33CF7861F98EFEF00C41BF8 /* cloverconnector */, + E33CF7871F98F03900C41BF8 /* remotepaylib */, ); path = Tests; sourceTree = ""; @@ -242,6 +256,8 @@ 607FACE91AFB9204008FA782 /* Supporting Files */ = { isa = PBXGroup; children = ( + E33CF77D1F98125200C41BF8 /* TestStub */, + E33CF7821F9814CA00C41BF8 /* TestSupport.swift */, ); name = "Supporting Files"; sourceTree = ""; @@ -317,6 +333,32 @@ name = Frameworks; sourceTree = ""; }; + E33CF77D1F98125200C41BF8 /* TestStub */ = { + isa = PBXGroup; + children = ( + E33CF77E1F98125200C41BF8 /* TestCloverTransport.swift */, + E33CF77F1F98125200C41BF8 /* TestDeviceConfiguration.swift */, + ); + path = TestStub; + sourceTree = ""; + }; + E33CF7861F98EFEF00C41BF8 /* cloverconnector */ = { + isa = PBXGroup; + children = ( + E33CF7791F97F02C00C41BF8 /* Test_cloverconnector_DefaultCloverConnectorV2.swift */, + E3E409491F97B6A000DC7F10 /* Test_cloverconnector_WebSocketDeviceConfiguration.swift */, + ); + name = cloverconnector; + sourceTree = ""; + }; + E33CF7871F98F03900C41BF8 /* remotepaylib */ = { + isa = PBXGroup; + children = ( + E33CF7831F9814D700C41BF8 /* Test_remotepaylib_TerminalMessage.swift */, + ); + name = remotepaylib; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -381,8 +423,8 @@ }; 607FACE41AFB9204008FA782 = { CreatedOnToolsVersion = 6.3.1; - DevelopmentTeam = UVY366B5KZ; - LastSwiftMigration = 0800; + DevelopmentTeam = Q993233M8T; + LastSwiftMigration = 0900; TestTargetID = 607FACCF1AFB9204008FA782; }; }; @@ -584,6 +626,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E33CF7811F98128D00C41BF8 /* TestCloverTransport.swift in Sources */, + E33CF7841F9814D700C41BF8 /* Test_remotepaylib_TerminalMessage.swift in Sources */, + E3E4094A1F97B6A000DC7F10 /* Test_cloverconnector_WebSocketDeviceConfiguration.swift in Sources */, + E33CF7851F98150C00C41BF8 /* TestSupport.swift in Sources */, + E33CF7801F98128B00C41BF8 /* TestDeviceConfiguration.swift in Sources */, + E33CF77A1F97F02C00C41BF8 /* Test_cloverconnector_DefaultCloverConnectorV2.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -770,11 +818,9 @@ isa = XCBuildConfiguration; baseConfigurationReference = DA004E9F68C5A4678FD062F7 /* Pods-CloverConnector_Tests.debug.xcconfig */; buildSettings = { - DEVELOPMENT_TEAM = UVY366B5KZ; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); + CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = Q993233M8T; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -783,6 +829,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CloverConnector_Example.app/CloverConnector_Example"; }; @@ -792,7 +839,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 459E230E62D068EDFEB5E92E /* Pods-CloverConnector_Tests.release.xcconfig */; buildSettings = { - DEVELOPMENT_TEAM = UVY366B5KZ; + CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = Q993233M8T; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", diff --git a/Example/CloverConnector.xcodeproj/xcshareddata/xcschemes/CloverConnector-Example.xcscheme b/Example/CloverConnector.xcodeproj/xcshareddata/xcschemes/CloverConnector-Example.xcscheme index ec64790..c246bdc 100644 --- a/Example/CloverConnector.xcodeproj/xcshareddata/xcschemes/CloverConnector-Example.xcscheme +++ b/Example/CloverConnector.xcodeproj/xcshareddata/xcschemes/CloverConnector-Example.xcscheme @@ -41,7 +41,8 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" language = "" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> diff --git a/Example/CloverConnector/AppDelegate.swift b/Example/CloverConnector/AppDelegate.swift index f3e204a..32a6b19 100644 --- a/Example/CloverConnector/AppDelegate.swift +++ b/Example/CloverConnector/AppDelegate.swift @@ -70,8 +70,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PairingDeviceConfiguratio var endpoint = url if let components = URLComponents(string: url), let _ = components.url { //Make sure the URL is valid, and break into URL components - self.token = components.queryItems?.first(where: { $0.name == "authenticationToken"})?.value //we can skip the pairing code if we already have an auth token - + if let token = components.queryItems?.first(where: { $0.name == "authenticationToken"})?.value { + self.token = token //we can skip the pairing code if we already have an auth token + } + endpoint = components.scheme ?? "wss" endpoint += "://" endpoint += components.host ?? "" diff --git a/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/AppIcon.png b/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/AppIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..cdfd1458a95c2fbb37c774a500c1f5e3eee9c49d GIT binary patch literal 226308 zcmeFZg;$)-vNt*q2<{Nv-CcvbYjB6)?(PuW-5r9vJ0ZBc1eZaAI|1fS-gCZv_Wkbp z5AL3|X3f)2S6g*g^{=a{CsJ8a3JD$$9smF!$w-T<0sv6pM<@X7NAOPoA$hEEz&T25y8r+P7=OPIfUF!GFoCw!7cEyU1$jPG2RkO?uMQ?=OrCa*U}^w> z-;)pgXlLeXOyX&0YwyD6DM0oQ1t0kN?`vi)sc^x*~7zw$%CEA!P$bDm6w;7nT3s+jg1jZ!RX>; z?`rJHXzxP)UzPlydc@6KOr5P9U9BAKN&ePrY~tYNDnLf|x1oQ1{;Qv^R_6cHlD*4+ z4+}g%=D#`2tV}G-|Ee2Yl>hHrJ|$->GjPj)>lb9@|A+Gb_3pph;b;Ea_`h}Lzef7c zTkuc?;rW^W#Wq2B`9W%J06-WZBQEmA6XJKzS~3N1>sI(`Tg)#yo3kvxiv$l+FNtCm z4h%E41#&a*mA(p(p7A^JOz}CI$VGkgp0@Jxt_MAnmB-JH;-2DW8W!qq9%kykc_+IU zjywcU1pV5MjS2i2Bsl)R^@58-2cG@!O$rG2!v_jHjWQMeZ#{yb2k624tAGFA z+20V58i3yeQtoK6|69dc5IcPTHnRUIX@r7W4{3xV*cfg3KLh`t?0$H_%D<)ljSoJ7 zfmi^at3-YAe`ndhXf*)s$p3F{{&&{u2Qb%GL*jpv;r)yF-#A|n+3)s$&%-}-{X`^2 z(EUWdU$N)@tr!1O5(`lK;eS&9#=Hjrm}?I^<(ka0qUoimt@p0NU>% zoR0xIJg~(5dM#uJ@*lJ($OPFzU+Xs7vM{;^{6(p@Y%`Jmp|0oNNhp2W9xA3^N*s)S z<6(OZ?Vv8;A;WlA57Y5TH!X05@-K$J%POPP=5MD$`p-NA%CUZFs=H6)SJ72_d;D7Q z8o2YBPDX&%b_XcT!vaq!;z!|ud8nPv(O7yDlv!rjeT%`GG&-$Oh zuyqRs3=OwXxP{E11f8IwcsliCj43e}B2htw9Lw}NEj=akES$e9O7LgZl0%)4} z*V3r=k{w0AVn#TBzXEifJMR5fC0uxzY4LB@lPrh>18Fx7Uwfzrs32~ccQ@$pLbC4Z zFNbHFhP99G^m=9xZa>28*foDKJGtRaYGEZ1Gs4*>ggVs-G&As3zp?@!N&3s*-g11%uMA*qae^HJUinn}urxfQ&^_6=ug;nOq?lq7(1`IekDzPN z8|Fri&mL~;VCMfbtq+hv-T_aokl`dgVtqQ7B4@x7&42^DlYpqlWwV~zgqC`qC8bUH z9X^Ad*6lsDp>Z!RNJ)~vry!ePv{f~zEy;tGM~cZh7PA#Y7K2nrVwiTgFt!zeR(xpC z)T)^I59d4X0GR^Ws?M=w-q3CCOAN-5ib?!!Pyb|-NX@*6?sR9`T-755epQRE_nv11 zx312ewbvPTFZz=-8{+>u5beC7YCV>3l#roEzo)Zz8Xs#&WOMa6^=8(cafBtfjq?UY zaiz?PV&5dXw&pW`aTar`Ehcytpk!1X(-p``P*~@!d-liTMZVvYB6vF}zrk?h`{Gz} zQJv4cQW|rA=l6H{0%O5bng96ccJhD$F?TP2;{n@M4MpE-?DxG14NHp+cQR&xju9@( zCQQPpcf`S%Xgu-zN{Qr^MSV@8ZhEOvGxB%Eh)6i=WYhZp;Gx=6o} z_BK>}&Hf(Io>EW?47;7WE7Jx2qP5L^c89g8v^Y> zei-+CR>P7nsqfvCCwIXJX6VC^%Jn#FlTt}z$`vzoU|jSP*(H4DnQvY*eK!I2bsGQs z+?R2QE5B{FUoAkk1uaxEkI=8nFez+`xF?FmshzRzr<{E2T@?$q<#Dyy1!T6X@WYg` zu!~AwN*!^k2={5sax!E9mTo}ISSQCgq7hxz3wNMy+X|> zIbE%Lv&u6cPMp)I*30?A4HB`pqS0Gt%jY+a47%R`3};`;_jCDuKMo#m4U~+AZ)g&+ zD-iLzEU6V;@3fERg8mpb4~4C)x}*Z?+CHBebTEOcZArDS6>IQ)L<0tOR=(AGhT%RjOPSrW?8h^n!E!^pR73YN}85sI=2bRolG;Z08?eEBuKIv zv`9v)bbbmd$OjBxo+I1&s1*s=$h(XO$aq2j9Jw!`Ah{nE)L|<8t7o%#mTS+TX`D`t z?{X5O^5AqN^Kk-BmC`3TWSZ{0y%Kv3x)qhMXH<23X~{H7QD?3Qd^CkhiK!*X8eFCg z2qSzpKV`OGNO~2>n$p8R)*>(`Zn^iB=-%k9_C8qyHavIMi~Pt8By(7ic5 z^XW5E-qrPbg&4wbm0i&~h2m=Yav#3XR4iuVj*}YqrPLjii|>w3`#mfZ&#%DaM9mS@ zdZR_mm#Qm#(4tEkwlndk+b*zmN)uAyZ~7UielnuTi1M32&K-8Eq!VK-{ja$o=n^8x z8zgokAssrNa?#M;I!jc`t}^bi*Ddb7ueGTTlx&m1!|4n=>5Id=Ob>oh9R%g8W(Cyf z!(n#hAv-Y&$yxPmh+LSz$9ims1>zsmdes5*8zsE@=1xE zh#JIyV>oB7??|Osf$ORd(@yeKK4s{rrblnh0$s?p`U_ZHQU6|MWZrBVY&F`(X>*aD};g+2^LB?-YZD&jS)H zd>2C&j#M%I;pBiqr0c$ysY%6z?ZJz$Q@s&>sE_D$l`}5d%aeLglEE^!AB_?DrZn(4 zyiZ)caEcix?r!Cu_IU*mR{F~{Yj8t(W(E%1qSTo#?^sQ>XH0gqP+;xh4#tViEI7h= zLAe@I?PEKty?}N259GeI^=LwpHLeW!7LA*;Gm^Bz-8w1goGfuZXQ=uA$Q79FcR{5N zIt!3y(YIt@dlTh4c_Wmt;!R~jZfg|gt~$^OP45XdsTQgvt#HgQ9yg?{ww`2k7!FG% z)jp8bzNjC8xW_F$mU7b#axo_!%(o3Me1Dma*^EgX;37UD;N{4P;5PMrsGb%dlj!S+ zb0K`j^I8c4hP`EdOZH5qD(}*LX3F-kANd~Oa`D^1VdNq8ueQSYtF5SB{M*o;08sEw zNJRv`*rYEQeipODq6T&ePpHD=-?O;1?1xnl#qV7SSm8sBkDDE7ITB6^rqOJl>7`a{ zGn6uDCVFjq-lp|_A2p^FrW8%nq|PPR&|=aFlzrzZ$QpGRRR5jq zT0x7+qd<{68GN0BL(!||rxu!<@Zu5UAm-Y;WY_kcxGna#=RXqUA-pq{cRYofME|Bt zV5XARRvFGnXp7~&5M;@3m{aE*+t^9n$$^=B+Sb+Z$Z>&`3op_7GXARf(350XYKRHB z6n)e1p6zhZu3i%Fy?PMZl%)0@R>P0<>MTb{7Izwz)6Id5SRnmo!{sMam4KzP6CMr* z1g)A(CxL_Zbg+J8uLyhi?=9*(LPM3L2e9oBEYe_(^};CUmY_W`p{-I@cUj3rFm$W4 zaK^YEBs0X=V3v?JG8ekeWkk|uocQ)qQ25*fBUS=%B7-EWrDFZ@IQ~>@qvKPKh=gbe zA!UbfSR?K89OOOZRYP{-9U=qWy(tHs+EKsg&_Hlyj`Q}$k*+dMjPz|ymCBOVQl^)s z&@{2u8%&;U$5dC(%NHwZMpxZ=`{(7&7?jjm%*;nWSKa;jxpH!u&itjjl;xsKZ5L)a zQ>3Ome*qaf=ED4^oZt=7y9tF{%+`f_EE8!_N=tpmXa#V46X<967a+7VLUzEc--(ri zXz!vv-*J>)>V5P>wS#>jku4-|hS3pOed+cty3@dS(j-+Sh=?oIytx6%%PyzA3=nfl zp2*yC`z&Ski&r|NwahqD(5$fCJ3Nn)_%-#_C5Hd3B-Dfbx4s3~UywmYvJsjpQ}>*q_)$95jP!ezDuEe2%n*r43xaP9^VJ=gyCWeWvwb;M zC?IT6RoxKUn4Ic^bQ{%d(HWlVv&75o^an4LH0@G;Sd{e;*HvD`;nRA?nTHw`ycRRZ zNOWOY$PAQ5SbA*v+^r6qJw?`wmo($rCK_CzkqO--yI69jlsu!U7v(M#`%uq`N!D~Z z@MP`4%UX|XzUukx&f6*P-T&rtMG%cS?3&m_1>%hZnVms(vSer+p7SXY3ae?G#Tl8`OwWq`na>QsRgO%D*kQmu7}%q=PImt>xt zp_YMkOhI$bYk}^V$VKUGm7F4vc_=<7h7qExn5@kpOp%m@jiFiiBT3; z91PjHr6>_p-4yL$b2TYDg3OPB!o5j00XTJaKeck1K_s;&W}hT8lZbvWJ5AOFPJ4iu zdTe7Qc9c}xD3u;^Rrr1rmL+dR;?#iQi(m}eCk99yGpiAr=%o2BElwj+NqTneFtec5 zCiSq$+pa%q&Y2BUW~0kUsrnyYW5|r%*X*rzpfpfbAyF;Z@=MY+nfJ49g*f}tBm!}C zuiI?;BJVnXGx`O7%V=o49&E%|p0!4pa+nw5$`_AmO+z25<^pJx}<4OJt$Jqx7UsxW)ELBwhc|680En<)joF5SmKNbKMiD^z)dDBAN z$<@#$YtR%g&7}I*5y&B*zGbS;dIxAfF~8Bi%s;H0>S$WA;FOqZ1AY}2mE81-h9XSyG&jg}thoxq$g%BUB)rR&@nG~PJHV-f0nC`Efw7H%7qt)tIp z4?~{$q=W3_p7$-;*xI0Fp}9kvS>n&egrYZZ`fT5eERW#k6(AF3^yi1r`#8~WJ+11G zOzE3m7lpl`iC&=d>^uHRn_smERL6^#jhV}L+@`b+mla1&)~5 zl=#Ft@girM@lMt2vVUDhNp0(i6hdVsbfxl>%i6fd)?bc_I2E4{xuWs z)W9BGP(SirgOL&O^OE6`&`&*=T$fOy2GdTZx>jL~%EOZ+%n!P{u14^*QufZ%2FF;E zYIhazpY@|OI3>#YW-At4xjNJ1q@=87@k5p21w^0nWdKa@fX?88hJsBX=U65g?M z)enff1ZVihws>#p<01jOLBcp^Q)Vk-600-Y1}JFClsJ!ce0WyRBY)Lz@L%-{?cTQt z`wKnjEW+{L67?5JH9V?c*wdNjhj;j)QvRd27i^n^xcQ)?t4B>C+43y(D>+s;FN&kH zL;B3`pb#9|Oekyowt&2MiO2L4r%PkLv$1CMLc`C4LVui;J^?m=C<9`?;syo)__vx! z@AkZK=>gMdS?n9CH=pJ%9+ZBTN2J5KhY^n}AH_;WeqrLm1Q`3%N=4cr1U^voeuz1G zKH%TP{?_;VjpJ?Pgn9n#&ZFaZ|I)L}%k2aCvuZ+QC6h{ef5xzMX1(c;KHitRh_TGn(72)`T(}M7v{}vjT)hOI^|H+{m4fLaT^7Rki;fg=c=!#UR+|$Sa z`XETT801$5sP+TY&kJ)k#8kkHi}{g{@NVDFcKPS^Nt-Jg6EukiHbRk8NFqo^%rTgl zz}3(4FH~)*vlL_hkg}?*0DzKls_M!N&ptDTZmv|pOr~{+ZCg0=dldp^KJnvYJ-iaTEtxBFjKjIh`#oweINR2(WGQ$U3wEzj+ zFVpwOeM}eDC>ecH17G@!nw9N!wF+3F6#~qnt$g(1Kv~vK-%l(wZ$Rt|5khA8ZOHRx zKr#l>v?8@=UVpT*UCa#NvqnQSQxHWI8 zVi&@4f>${BE)dbYN6M1NY*7Wg5d}>-cj8Sn-;~Gh-<7yf!T5*AHa%2KKBC~G3*y7R zz~)b|#O83Z#D~^nEU$Er`KSAlV94_3C*vO0f0l(=molmRcGDVjDSs*>J`nPX?3d1YCNC;lboB`n6w}DGYTbHZkXLk`_1`$ z3as*GV1nj*xfun$yJ!kJiS0_Uy_zOV(|2(oNqe%0_Hs@PcjuLYN%9U0k&C$Su8FNu zbVNH|hli}$80S9G3g23@smf09k))-YiEDorwVaml*L6c%)0xDbO26V;80S3wBfT$8 z{{A>zudSeH0;&A-&4jPBU;BwTJ(hu4TyxRJ{{?)Y5`2LCk<3s(q;soI2`O@ z&84=(I^XT9eG;M%RggKqdQtUFQiIZUp250#!nGD}R=w9zXF`_yTHwRI{Pv!v#Hw;{ z(wR-1FNxh!dd2iUD$M~q2rMjDf?#vumEiYhT=FYqSg7ktSZ)2XaS_WAc5PsSOie^h z2DRjznPQy~$Aw(Om-*#rMAP;3NcKJ%xmT-a-k;Cb{n7`SOQQ8`VgH zq{%H*Gox!K$68DLTZ&|I<8ekN7TLl4a?#ezctPuC?ZF-Tr3kg^C_M3u8J3$XG#iBssNe8BOyNYA zC%>(2jSFnsyy-y{;JK-pxP4@x?v2Z3ezO5vQF5h7+J0C1odsfP)f|QwNKZ_UPb<{v zuM0h10cX5#nou7svW#ncWubtnFZt0}TZc>BO9B&Z{z>nhZws!g%k#eIFQ)Lg3!|=t zRbw=WS%a?Mm7!RQ2>mq6ViSp9%6`4cS~0%RJc3~BQANv)kxJ@`?xn2wc@i3RZWpjL zzT|XZ-kGId8DjPMGK_x`IgMUvt4t0o7k`bAN+=*8lkie|ckW%`-5Miw{Z80yL23iQ zgeKR{Q}9l%R~EaDcQId_yao5;Mqi9-C^u8<282ROJEDdKtH!CeSK1zkiKJkx zcj+4B8IkAzjmGly04pg^kIC0iw02HN&NP!Zd9)X{wRvW0eCtn8vD$aWkW3=V6h3a0 z?sAZMzEn0}OB)h?Q|U@``In+f<1xnZCVEQsVulaLb+7#aQCPlDa1h02KXzH1%v~AZ z+WOX!npX@+bJih42Od>7$)n@DZ0It^+L~?|Z2$bi>aBlN1Y<18Q+uPR6P8G_tMHM0 zP3b0_4U@IqU(vY8m(D^1k;Jpghx2==lD$f%pZ4 z*na&IACuY<9aYB?k005)p>ouPizLqe35L~hWUBo7e`u{F7pK@;a0EHQ;8KxXnbU-@ z2vqilO$qSpcwct8c2oTQOYBh8i8zd7A%Tfw{*US&NE7z$#xY65F#4km92~B3xm=9> zUfYS=ZQ%<(ExER8>t};M$pe`T!6(9>AZP&f@(9W9aMgE-v&js;^Ct7?%#{ z?Gh=^G+#dEDrvtg%Ph-f6^I=OLw$eVqWGyqBA!){ya36$cQfKeHIPA)YcPFCmUrKmS-oUqqvM zAi7M*Mio-3%=lu)urXv(#rNyBdbGe>Z&k7d^G^|wN5;fvnIdq`nbSpkzcla zGkLgYpvTovjv^LjfAOqw+Cc+g+f5#Q5&~yL0gw=Ovpwz6v#^jkgr%kG%k-n^gNH97 zhzu|n3VWvc3IEJnj4GnX-WmT)NzU>l4I2O((+-et336KF36C^O`9^+iLR(&uW^e5= zxEJD;GsB5w#7|uM=eDp6g5XTohPT}HyFNU??@miGTAW+vj37QlCk%i9D2<;r>{Ezq zT`Na#%tagJ@%WU<(|8WLWS{wjatJ4d_SEh9nrRDAt3G zrm|Y=FG8qGQgr4Ut%TsgA^7qMut&1@j5JJnLlr8Ib@<2K@@*UlM(N$mV54|9v$Ov+ z*ggayt!3->(uzDzZ4-<*pr#CtTaAyf=_$D9C4kHilVJUP&QQQz3NYdj#(NvCT2j&k z{rOE?>XnX5q_LX?7MOF8puh#c^kXM=)&Bdn?CrefWI6%L$aS7-sDzRWT_(2lN9!12 zW7xgXSZm$%s?KST%I(1jJ&bf$`*mrTM?u(B>YL9Vrnal0H@TT6Y7F#qUwd$lkPF~z5Sg4rD@>Jj<1p&uRvCx zY(NEC8^%<{PbX8&BhYV_Ahp=({sRb{1$JkF^%$f>l{BQh?zqOI`9s7+kb)H#Zj{za zswvnI1ZK-GCn#qdO{%I^y)2I1(#^I-nCg9X6*-SE$ixb;2{DedNG{--{hVU-3kPPZ zA!mO1Hg^C$JwO3^_8~ntAlZNI&B=SwuOQV-aY2A_0lR8qR0>|v4CRVGL`)m5VhyqY zUv|+`OGpB);J^i_&ZbZHWyCvgrES?s4m6y5syFf~KOI0T#0pPz=;@+0Hc#bp@9G&> z^J_}e;XUo~;5ET~+SIG|SDjD?lTNBX3yL~aUc8lg5!B|37XU=SWa z8Cd2g4KbU2AKc1fc4h6KYM^9rwjn4FvI82Hf!wb9zCr_%B!Iw^e2=^mFt0+xI zmr5sWB|)L+<9!I!@&E=e1N$FbixmR9x3OOa9}_1n^lEY`#t{254%>7{55|Cbq5NZh zx6@>Aw@3M<7O^0@o(oHP^JSaYX3*FBg<|3+CTFo?#@LXpdX+TE%06PV59Xk@P54X$ zb_?(N(3*ws$L?tS1D_VLB<+~2#yg*Zj#dwRcpQ0s0v*R$XBnSkDglM3AbDZ-a&b3(9m*8<0?RFUZf}X4>Y4b$17|!qtl*NwgC?O!Jkz<5&BQ=8@xk6@CGvGSa z)ABji+QxZPDY`GzUt<8pT8omz18n{u zVi!$Y^9i4KF+Q4JnA4EpVwtC8bnM;HOX1!3Z41e1)R5>DDjiBsismmH+vp@N(DrRq zq|Z(@@Dob~SHXFo{1*MvYY%x|HdgUOi2lB7fyMPUih8Ht|q>z}XQ5JP4W`Gj4BZMtO~O z*NuB(Ia}Vs+$VJivRcpQr261>-Yu$Q`j(L~uzAZK#eNg(IRn|8IifAO|qpm|Nk>mRH=7UTd6 zqMUl<8T4(Khn&1F%rKKQd|H+|cVbcD`4M~)JXcIr!$J0A*oEcvAk2EiS$S7knJ7CS z?38dYpP6^1BL0v?eUsEu*s@EYZ1Y+Ax;c|VIpf%9$XR_Un@w%>v+;#nL_OcWgm3FB ze!2Lq`Co@&pm5K*gjf~cRvDpad=XY%JS)5|oK^?%#CcY8kr|9#F=+Jmjk1gus6(ZZ zw<(2wjJy%Pt3tHv&tTyXd+nKNp=)`VToEb;B|bmw#1JevF&=k_b6*gEy23yyw>|7i ziwVo>Af)h-#pn<0|=h2e_f(m+tEh=Rd_e8{9E3 zC#v0mZPaGBJH04WkE?n-COeJh2vE0R}xY{!+Eyu)maIK>s} z5VudLRmV^`rCBwsH;3&lNv3Bl&jEI1WHp0I^yhW=BgNnIaBAX?0wzRM)#OGQ4}Th# zCFy)qLQXExcW~WEMHhCVTp@bKjvY2>w`3?&rLxQ{IV!3+e1EC>!29|ckC5|YNKneh zEOzC?d;O>Y7rpUXRbf5eH+zh}=N69>MHaGczi&o5CPPRcb&zvbakP1tl7c6HB1$Qe z7~tS9sa)031B{BO*cN;#r4(kUW)79>bE&daua;h|Ud~Uwyjx#eRIzX^x0L#%rEWgW zj(if|W~Z-n_KRD`H*BTJQO4{?MCZ<6#tUtobi~%+5OwzCCse1XeKQ3wmvC~_w{!cx zsxz{y#W3m@$m&oYvJ#1nY1Z5M8uUf2LJFVY8F+DxJg*wGO$*Od_53S|eU?odqLJ=5 zA2wj$_Gh_r0sV=FZQ(b}UXwIus)?KOIjIv|hGo=`w>OP==N6ILX-Voh!8cd_ECL#Md)6n@(sa6+YfPM$PoJz!B+%-$58?eQf%-7 z7ywlqqu$#tXH2+JoJm=}WIa(hqx7gjs&b#yRTkGPAbuB4E?^!)$Vd5JP|;K*a8U88 z60jDfN-}+qxXkc6@WbiO9O{7(tV14pKDNJZ#{ojawTkf98{5PCe+W%KeQloMbs7xm z9C`_hK*~!h*TJ(QyS2%*movbSSXj4{H7Pr0pCcV=A6|*AKs?KfX7i(6U$%ZHeQUfg zp{+YNNkDGS>rPX!ww^w?`Oa={q%nf-!j_(bPV!kU7-vMMYYnrTbhnSTmyxZ6@@Afsc~~A30beDKa#}$u6`C6=IFQ|88yeCVW!d7RdNtrX zjIRZOxiMTncPQ!lo~bL`0>&rO%4A;@oVSTJGahR)LQK_|Ze@%7u$2pNh+cl_cFQ~4 zn>=LCFJ!tHG#pGVuPy4!kU6m{6n1^q3sRZ_K!l#gwn2C`6iMVS`#od=>!HPgY_REk z8wt`{ule@ar;17|v?R*9f)d+ot4yG2T$-j_ML`Nr^-zWep)?Qb=2&boU60fJL{1wn zS5A90xXF~Z4DD1|GGF>Cpn%eR=Id6#q7Xbds(`e*p$IVzAS)2cA^GTJDN7t`G|F1m zNb667wj?k_Q-1@gUm0~{fHSuszOCiMH~%L=+{S9NMXgt0@ZA2ow~C1SDn?W-`Nqd2 z4C0!)8>5pWg&4+nzTl2jNF}}GNkkafW%2;Be&M^P4k-|Dfdc`nq8AN%V=yiDGTFF` z+D-zf3Ii&65a#HYO1`UUqb2OKZkEs#SLj}A`hE4RFM6UKq5E^DIuscY)1UV@ATLi7 zfDPI})4~u|T=k%36rq9IJ37KP(U#PukS~Nx*d`!s_Ro$e@x6;KP7)S$U^v_{6vd9R zjXBD~YjKFjGtE>WlC6p}*Pql-8^OYRG}eL$UHckBnaq+O3LEVt+Cqps>w|M@ffYnD z=&b+?Qg}vEHo%j|j!;SW)~;+6>0jeno`GXpK{I}H@jHHb$jiOjjJ}$9)*)fy(F-y4 zFVpZC8tUf{v7M}wxLT%>%hVB-KLFJ*;t(@NQhtj_TR}`fx$`kKh>f)_fTk4S8u2)LS#QcIEcB%s-jM`n>&5hdOBeU+ zdgg6b&vbF%LFPQ~X5fM%2)p4PapdW+$I0!-ZN7?QPY!O{Yj)x!bnJW1LX=~5-FE-3 z_b<5Eb?R6&w+~tK=sm|{bar!xx)#J7zHO+}65%}M)B5A^HPq1%y#kPLht@?W7C@_R z-&CeAZ8{VDv1lTBuU6>ARNu$i0;`uee9;3I)iEKzLY4;;<{sRs;3hU%$NvtIW|9)z z(p%?_x&)BdQ~$kJMoql_^HmWQRtLQVN{9S(oENILVRBM4rZ+;EixaPo6`2PW?klOX zOpt>3wO)}!(xchsb{@MsNUM!m=MgXYXofGu-Q)SY3-eq1Ba1+a*WudE7pkO*xMg=h(jah*-EQ3 z4l`;z#ZM!%eS-89_^k9;#ynrV7IFu+7RkJ9lhsJPG?W4Ot@12om}#M#899&)hc-w0RUe( z7UbusDrKHy>9;bXgI7tjN{b(VPrr-cYkUPCzbVD`x4=RzO$<@sFiN1SELn+(3goQ@ zZ-E^=pG5-rsy<1^#ReUd#G48digjicG0XVUCAlrxxdPwZQ7rtczI|DrQuNt6b4}mB zuymtx7_(rj<3Ep_OM(VWP#U8JvQy?j4F4KqdtoNaklDiT2uH5vmcPFFJ}LPWpG~Jj zm6d&*xOL>5`%S4=2+C+3zG+xDxKIKD6>+*%8N}2PSTRDn;wh*|-L&s2m|T7|{=6M; zj$+E8?8d5rZ3OiVZP0O#G7Mrw8S>Y+3^}t|tr<rwDM^R!=B92|6Acf>sX@;a*I#8#s1aSO~6IE>j`SZTKp(tDe;jJ+YX5I#+ z=iGF7Bc3RPV_yLC@jS#QtE@bZMfN+*d&U%`)4pE2Xn&(1Ub6_P-_GpY*!ETaL1x(7S z!&2qX`R^IA0?5C8psqFUrdn5lVxbHas)qXdihDB9O=>xmBM*ga4d;dZaq)9|>uh#v z8&-^9v!nkOtgksNW~W$#tl>bz-BdFfWcBl``?SA{4E@y_8Y5v$aEB&| zZELHHAh)b+s`6N3k^GOeI70RA-TYc+=>U~8Di*0cZup%)7F$+s@UNU-=mhcwQSx9e zWsnrG10O;mh3{EYv}GCFKCFjaG_pgN(s`*cVVd#XbDAbbE1zzB#u`nG?Wg{G7a;!$ z#`R&FFldqoQxyicQd$I72fwjCZf-ON3lTN6)H$ZLTTdPcjGh?dzMY7alm$*n`aG9# z+UL2)^ReX; zVB7G%>jr`)VRoB%i~vJv4EA-?XtZ$$<*Zeq-#!{rLLBGtnU8cvJTLoIGqjJWu$yF? zPE&9zPg#T zc{J~USE!^5^Unl*YpLUzt~9hoPJVSg?++kIB(xb=3<&G)tWctTGZr= znZGIu%yGVb4E8oWN0Vb+r(8KdenqQy&bFmTYyuTusEiZ6WljX3%K|2!(Uzs@Ee$4t z=@WSO2eaP3`Qqj-jH z>>WFNs1_y<2XDxF2t&_`afbf9{;;i!rE$J;^>^ePun_(f<*m2M9}AktLvWuuBGo^X z>2Ma@vVBgswQ_^As&ka(or9P1{5U%3`=Bo3%>$PcNmcm0H_*V!Yk*u2 ztAO}hv*0u`6l6sbmmo5~7{-f9Y@xo>f2$!v2_DsuHN3FX*Bo;QON|h$MFS9@%HiI_ zZ1A}>L~rx?FN!A>4yQUm{Fwe3&boRKl*pIieu_r!8{XtJS%XMwD8G;@`HJ=~Hk;nm zUj${;d2u%RfBp-A$=ri<#K>jJVh(oFgz94~Ed)AO9^>>OLxn&me$wmK2;~FjVFj1(5E+rgxpy+jiC{i_C@i3XZnSQ*w(Y^jgV=6#QV2Kw0is zGjRa>9mW%6phjpagyP$x`xp$D9qc;|=Jk;hi7ce$Lb&~%+JS@523+LCdA)OsS7)eg zd9$IW5nyw6INY>~77||L%)1R*yZ1W`77;1+oqb=->aD#cN(dfJlXoMFh*7zJA{Rfh zS8%y8@4)S}*P_TP9K+Cl#9Wlw2j;BVEZc$L1)V3-l$FAvWgo59o5yHimT194{o*N> zEjZw>&P_;Q)_HtDs%G(%2_n>bP8%okQVWXYj*HaJ51-#Ngrw=0O%g^6*A{sdug(mi z%n?LGYM>#DK=+EUJF1Ci=T6_BP*xS$_vIpLn|bB$XYO4qddM6P0ke4bC|xjencbX! zrh?MWlPwpmYs8yB>7+RLFY@Hr#Py{;ea?xO+Ls8JHGF{SNiBmY=}iG_)^aSpM9-SZ(V*g14u5e&xD2*^=2omaJ5QK2qFow9wJkc;{<#@v&^1xh_Ul*FN%WJwgyqU( z$EPm592x|0$Q6#oy+ULV%ZJ-lM77cDl9kck`QwFV z)S|2sf@yoLS)EFXgX2L!8uNhyK48B_@NH^9Z2vn+{YLF=OK7nr=7s=V(+tj`-rPq{ zA-;9Y53jKfu7Xi=Q1lF=FOAc?{4p`ELptGJAckEJvT*%G#i67w4Q0va4t4Qzkg2EI$S;;#R~BLL$ilB>#AE zra*?VdWn#-WGelbFZnszcl?q39nVz;XwpPA#XqjJ$?$`e23vs)uT6pxzgpl?1hE~IoX#6Cx2dL<+>8}0xyIWr! zZ>kHgj7}^^IWe@bQc*y8@fZMo=v&jkX}woHA0a^<$96zi2gq{Ka11*TDj?I|-8*|S zqEOd*4d9DXf9R_Y4jiU8R=1Zc!>U7N9>*3nmUsmlW{&bNk%HWM=!p0198_}@nteZQ zf7wnpearc}_mXut{&^pNMQyRoq6Jpn)UF4|EYmIHEMMyF5Bj@Lbo64bj11?>IJzp} z&J+(&#>mFH?8g9$;}j|M+&o(lLuby_^IE(N=fK4RvUn9jc;DMFQNvRImb%~06!g6H z(nk0CG31^wA1A0sG_Vz4kp0W4_vdNGa%-VZ7=4q)w}LsjaB%!g(z`y@dx8S^KsBk2K9vil;y zc}9F=`te!$Oi=n+JO7N~f;PrN)>A-GrBZ8&mB{OsTFRUK7wHO_GK=57IpN65Gd@}& zw{3Rk2=^ptiO>%O8?D8+Q9*s(?r(CZzW^vo8~W@*D3ZbK7Tc}`C}1ccWNDnShF~C! zAOrlo5uf;QLje!C2{O!*W6%-bc+pYs=(8;kn0;TmAx_CkSvaA{jpQ3Ubk;(=ifgo! zO%>~fj=IT+m)uGId%;KP9itO)83piFt;aikK8uk~U_q;etx|!I69o*!ZV%TTf0?J#-$~P)UikiPaXXbFyyDghgj8gZ(nq)|1e?% zWH3#mJy1uBxI^KneW1!>=AR{yWyCHc1RDP~&BP{_+wpAhq!h@Q3}i)7++5Tfb=4Y& zkQb^*H2ztXnEU%gm()RH%KPE({Z8bdg3sy|XFw>{x0u!@doF9y48eHi&WajAO9IL< zu0qs)3&f*m{d0n~KUp_Fe);j1sv9N{y0HxgP#^^Uxj7AB8+8GpcsujahjFTfp5hO# z)kX^WAr-fnF>}zo6wsC5-%7_%3x|1a( zpe^-nzVu`xyM5XK$p6W-=SuCLxe1`D6q@PBF0?gD&8|wDWXZmfS>RVf$u2*U znu0k||5Lu(^o2n`u<_@-nI65t(GQBADMsj!K{=m6UP zl(r-65N@xVW4kdNN1HK7E(^I}g7j^A<$Z2_iLZd%Ah&dw5Kup~+s-}xCL!Ci^`nGz z^pUeNxI)N0l?T2%C9xi~-mwAlj#u4vtdz^wy_VwwFBcolLZXi*&}v6}>~2Qz1KyZFaR5YACW} zOyot5JY2=85-!C?=Hyh|uC$2ME6gYXxIcCZpNsv%(S;#}fUu&3m~K%XB*Xv)b{__* zKrQ$J3YsmDT%J8&lEVx94UU;|v3|ZLN~-%5r5U|0tqTEGcZZtElP3^ur%U}V0;SzY z@m&t2|Kf8h_x!M}(W~m9%^8U1zYgIFSM_OK#CEYm7J}u(l22DE4#an3SS-Ly>PZx5 z&&=rusDh|5PNr&1>X_$EgPzUgx{DKPsko}cOm$Ktm%}Ae%T945SKZr5{3XjboC#bNEjT_bB^W;H-9FJq&|tgCzp@C{yjY&Br{ zl7_QpZrRo*PFO7(nx+1hQI}RuJVa3?us{=265A9sCK$f097c0(UK?Oyus^Ff>~cN z_S2KoRiU~Sna!D749l2-N(+~csH?Nm(RqH0N%O*x9}P0lgoAg{Z=pA^Ohvt!f0N>$ zbFJ5oE8H`kXZYye=K~xhcaX`I>$<)+83astT@*JZ#b^lsKRkT}TieYOZ2}Z4?(Xhd zoFK)axO;J@c%cxWNMGDti+hWEDDLi1+$mCA0=en`KKFit>~FJsX6DSCv*g7a{Oupe z`=O5&)y_eECg9j_c>-9oQ^t0V>Q_75L$*VdoTTi(>{%?)n4NfMD<0$x(Vd;1Qs_QQT&duXCD_+W4y&Kw(zR4!+cG7y1=>~qt&SIl?%1SffsYX}M zowyj@*TMa`oBPY|(>IFu?$DGgSD7!iNbvin2U!2@wwn`3gD@ka;8qi79SCU9#i0x%mrDslrRJEvF7`sRzU%is#BbA~s`6i&f zY$3~$Vor?&>1WMw?Bv*&QuW81QcS3SypRIEf zk={6eE2YMU{vvpLs{R4ueO{zw{mHX>j%0|6Fb!VHu4=`+{Cq$+cqDT z_&m=UI2o&KpyvaMl4D=!cx<%6N5(#j#6=Z&=bC^m9G+Tlj4{CHn?q9Z=iS|1(>1-x zfOi92ay4_Azi*mrt9;D!uK%9X_uRAJW?jT2biS4nx@uN&EFHD2A`{tOD}@lsiZC_3r3r<$8zB@I5<@kK5BK z>N+nRKU%G*`&Sr} zg4_I%N8Ww%G;VsGTd{T$Z^fewV~|{)0Ud zoYe&=bk0|zYcUtDDGSBatIa~ViWZS9` zhM&D<%x?7CNX^&$c7v2Aht!dQ-Nwi1r<;Kim{N=tk#%oNpX%kt7KNJCl~-B%G>oLP z3nbot{%dDMc7qznnKGw^TmZ;$%mSbTO5aLV8T_^tPPJP5FE3pXBM6XDy0{eePCBE~ zCxuLXF8YQ=LdRc6cQmbrP(#Lvekx4=OknA;a>vu0{L$NV(%|8K?%#-w`k}E%8Fi@C z!sm2`@5%A!X0$i^UROqrZny`NEC8YkcDH&7wDT-d)@z;#-^HB6uXhF?VZsjG;N8~G z)i33&Z=_Bey=NCqMiHF_-z39Xy<-dXIZmSq!3LDDR%9&r(wVExYtc*b~N zCbPM4IzDQd$|?ioM&5hn>c2@H{=`p*qnE2=w{M2UtuGlgis~GAfB*1X#jqFs;yZNRz2K^0?YFt1-n{H1!fJDz3KM%`t7gI3*6l>6x#UsbB_D7lKL= z+~?y60a0hw53;ufVO1Q?{*gKOS^KUA$H^z5W>`gM=P5Rad}Sw_>ZBo8FD;`uy5*%5 z8WPKuLQSrexUcOsRQdiK0ZI$nGPh+>B)uSo*J9KjGC)Pc-=NG2J5_WK{=I7TUKe(x zXc9c&_8jX=Tm0ZkEr?|tdA7UQ>NziZ;+XHiP%84r5!tpSk{`rC&Lo_^ByZS?qxsd$ zWbIBvMrwXoJMilW8(ON>OZQZ4&l!$J*C-5E!ckYZW%Q_nZMDfb29Ha(L@?|7f1Im~ zSv*r2g@H)W3WMVAyO5K*ySqKGDy$7I(p;MyyD0}JP$_DV`YIS5XffqFBJh5f5hSKY z^_0tvmoQJ95N6M8qcz@d{#VOLZMDBBmnq@7x03H3IPe`q=I#rpSJ^5FD%;)ss2vU!yeFv@m)8< zVxd0-1+jHEi>`?$NqTPc%{ zCDXkkG+%{S0RCg*f|zeJ#4DI!jvsBSEv|R(zTRjB3F6%TlxLqa_Y0Z;>o)%E{6cB= zCSfQCy!05F7@v=YK+g8}cyC2S5TQk$CJg`Sz~UoLZ9^tR)TJNObSQVr zZ0zxLz>6#PvVN1IR$y?meN*yu-6`LT@y0ivVK2U8H$ptW#Ts{-N>D+9Qt%vPG;-sy zae70lF@qCRokQCG*@|WFpc+4rHqt>_Cq)bwLP8vlu>noFAPMo6E^x%~594}% zLKshx$=l?3dmh=cQu_`{$=^a$1Ppik$c&nsdYHsgPTE&nl7X%R0EvRej z^$-wF7L<;ew;u==|5#L%(VVeXL7c#x0U=3`IZ=1*g7Xt^fhT|ccN_77XvC!bA2=;V zXT}dQ=3)xMmhm=T_P5Q6?2e^RbtcM*)9mm4%V;0+W6uYMLA{W)6!@Q}^7iH8V!4l6f}AQS58G@flZ8hKSa)QiieUTk4q>PyUlWj z=7T-eu>DG|)5n&Ml}nw(NBDUOb&eCJ&Ok;6rJ6H~l|)^W1?n+9l>aJfvDc8Ct~J_( z%nFM151E*SOzn229$;EqMHNW3f&QJ$hg36e=BjkOm%6m*M`y->p95`oW$8xCZddKM z*DKtNGxj0HcZSc-mj%9VezPFb(Ghd?IG9o2QwB6%Hqr zu8jX|mt7((1s~fch~BGz1R3LG;{?4^PpfzNm;Jd$1DX^l0(I(4hQ6nz&KWbvW{2{k zM~0xH{J}fYH;pyAV}wrWJ_=s(rDVbq!;q)KQipN1s7%&4XPhqcdilT%{!Qg+6htr5W9L=_5e{6Yjm zz=w}{j!GGu>>pL0pX1t2nj));20vX$KfnI!JAWBa zg0+gAQ#N8hd34QFH8R}z3Rc$tsTRdVV|NkJFw&b3_6a{VA^>c*SLg3k3!%!XUFYr# z5|D~T1>Yh{@*=cI(U9PvQIn_RhueG>8bmsXV73VONED5={R5AwYDg>ew?TAH;&9(g zVkb|2@_d_nmI7D&CE zN@-TSi8p$^i$A{Ck}n%XEaCqUZzIh!7#~}Wroq88KyxUezG+f>tgTBz=`+^Sw#!d{ z`4`^N-`cgj5CTu3PP5t}$K;u?0eE$@Hk+R0L*=txsFp@q0F4oVMyCg`KCZV3~sb;HVKB317CR&e9=R+taeEdFq?E;)KFIO^Z@mW zeRyhcL>`xVNN<3-=NKa4m^uPiyp|;u?Tk(?wvVJm$#X|eVV`Wy^K&1YN?4pmszKDz zQs3|2&()UBPltY|WTlYXXhAjH%l=Z|MVi{N5!3TbtKq1=?Kyh;TukJxvydVn(>2f& z&lVIjc+|-W67)DG=;KY`PMN@;DNW?C)yODJk=2ywBr7g+jGjSuh}3bvnGyi9)@fg3 zYgvG1*xnhT`!7UWY>-~)BBJe!h6$2UV!OEQCAY$V%Jg6A+i}I16MsPk6!>}KrjkC! zLYMc5B`6FtGWAOmrephs)gd^y^8PTr;&0Uwto^p?I^V0?K;i_H_xs}aMb53d0$)oG zR=`&{@o6)@CnxgGP&X>m(b2rzvn*1duMo)|r&jpy)0z*o|0~Pl?$Xq?3S4EjK^d}+ zRk?_B>oxbTRt1wb1aq(?$5SmZMzlg8!+6}>I4_NN>7wc2XX!(ukP2e#A8c75&5U{J z3o49wEP6gummP)WbK8bu!-_zz(3Bu3`CYg|&k|ltTz^J|Azk^U795T6-v<*B+_s2r zQ-0)^eXonHz;0RJa7}6B>GwA9fiv01qC@Z$zeMyZuLDR+l>rniYt|3^{xf?1v8)Y8XGrOFl>w(v)kbHuO-Psu;pl4qFT!EZha!FSc_o$ zN~)ZHMK=~PGUQao?3&ZBdc>C$A>zDaq%<2Db!jj2=EFLlLn=J-Kr2Z>)wE5dSV)=( zCX;o0!N+tjt|H3JAL}((EHL|!>GfANMAk<1M&jUk>IWJeZy(OEJ+oZ%oG9K%1O7XH zo2aNxWpJ}!PPe0^8mxpBX#LkjW@z^YbOTd+s_1+H9ofyn-0zk^m1)nXkymGd=pF3P zWaP8a#>2qr8-8lUkeYTQ+=dz+K5xWCt3B#XQvR9p=wmtm6_8py3ih12I?RMf1P;6h zFtaJD()?y{W?tju-kiKk6W>=>y|)bNb2hhe_NRogY+g~%x6t{iw!;b3FV6oM#bxuJ z3z!8`v)JPL3*DW%joFBail{?uau~`!;(@CJ5_tJIl8V^${0Fb|9T_4g-Q3ymnL*1E z+3miy!{gRb_g#Zz986%UzUa-X^%;fA!*9{4Jr^~c;bBaq<3%*l@3?S{)%yiP{KnrK z9=2Pt?pzTb1>x)%IXt|AQV2mRDkwgCiESM^Z;h?7_xzj&Rq@{hn|Kzt=^ z@d^1YCo|2j3T}4t*{{EPRg+!j!fs5gSs?kFr&mpFr*NF^qXS^}4!r?S15yl8UnLft zN}JuSFGjE4lmJqn^Ob2H>xf}8a|>w>3`VyBc9PFQCSIoOj=BBcZxZAwv{ia2Y9SlK__v!Q{i_)I!BKEi0 zfg(4jSp7P&Yc*7=dN6zUR&k2BfUiNm9QcQp4I|><+e_+t7lsUMr2)8KJ~a|BBjYJ0 z#lrF3#96F(0jktA+RS^-H@{FU>BSSA97^L<({Oz(QhI?Yd;SO3vu50au&erC6yvr$ zMk~f5Pa%I8bA4hnu=({~(US=gFfV4!SKw}ga6Lh{I+90hQS(0ki8vih2BA;4T9_Us z0}m%-47@J>t%8dMFqpLjo+d5PG;RivS-uwu)>6g%a6MZ5!}V^?@}4IwIeA-2^n@~^ zXEwDm>+ZTRdu=F^?&uIig^(TeDtk4pX-uY!7VLp38fMe8vc;j+NQXH=nolPDDEptn z@}tQjf|2Ou%1s*u%H*uj*x@numGO1S!}!nD3kkyvD&Zr;rT8&f~PYJ5e zhV++||57$zq~heqZQNl78h*2I3L3het6jrK(5~+1M{~NZ_$c?f7dLW90vaUk+Ud&- zIA?F8uA(iq3N9!uTRORAEFKQ2`jbgMk%yG(P&a3M+fk2xWIq5&TeKckdG5OYF_tw` z$=61U4idKwD*7juo!1vEH8FS4ElCYDMn~Nd@j?CT@d5tPi3osAQre>efPr#bLE>av z>D&IWeVobv4KxQe>R1>Q9I6je2iKRpC? zbrb&n?NE?vQuVHzZ&EZTV&`8tCC-|?^7SLKa{y&RVRFw(q7Eb1tzIKq;$>ExhrTRR zdpQkZ<_3tvW@>^aMe#--wBtq%G_4riU|FF|FtQl=Zho}(?qLDqEbpd;HFdP>nSaP& zufM4ei{;DI6^Ik4K?c8TY-(6BM7=-SQO>rwfqg7ZMJ(mkzON@A4LuYE5$8Vr{sTi@ z5>ziq4p@adY(x*ztFhW-8J7lZ5&M+aI~H{Xn%g`sZ;o8RZvJIebI-PuKXHbugKXRQ zuHSI96Ya{Oh|S=sI6Rg_U=zam``l|8&ty`UUzxKnU!RZvUTW@o`K^i{Q8fxy&JtTO z?(W;@mnPERLOsKXC+_V|;j*;3*0}SLW3bxvR!z%Fb4K5q_?EEz7Ck*q46*84^7U!X z=35iRiO9W2l8Uk}i=FD&pEI?SRyXFKa8AaKKx2qz_HTmQpgxTUoFaC!t3dWe>;#)& zRW64)9^Jqa8Q1S>tS%LR9iv|*R$ID{ouffmaATy0Ae;hZy(S*Bf=W(>wCEe>Ph8Py zkTC&8U#@IBt%xR>wI2y-#@}@mUcpUW$#XqDMZhfwy z{wB43d;Q5%E^-WNbzsT(`5C(~*jMSJ-?FG0bM9`$!TnhEl|U|4&W>(d#phJa%%F;R zvnIxbn}x@@7pH@Is%W)A7$#$Ru^_SG2Y?q{?>0P+oTFBg))^1OXj628Q;t?*%+KER zkr4n_adsRMgpaLL8mlAY3I!wq(}G@1E;aLoAYQ!;Gp^$0js!+2eHnEHqBn-riJtl! za^#zGet^BsGBIL!tD8!Vze3m_F`BID$|rfaaIXb)4YS z)Vh^wQUhuIk(w?@ChPwmB8?J7VB00SQWOl!?-doq3e zwh@+O#J)OAr}M>}e&Rq2S=Fpe*6=DvU`WJeRp^W-%bF3ov|-dVZ}bg5&insOGQZxx z55~%JG4yUv;`u0mb8T^8^r}T=0&D(MOj31ICkj%5d0k%L*lT>&rlN9SE$I`WiXoqc z&U#0_H>Y6d>~BrI`K*Q;Hi}zjy`K{Y4*U=S|5OP%8tX*(B&1qD_0lK$ud`_Ykp2DF zpS_J9rL+Wha@ET}(f4y>3T@<9)N16|Ck{Ppx?&m_4Uzk)Rd{U75myj;Uo;C;8YCe8!gmDU_;wr2i+<$v3yGQ$L}dR1g6m zc|aiLjc{t-_}*KoMZi6?-Er9*b=l?=O!TGwFEt;^%2VbSAVx1O*VHu!c}>%XEB!R+ z-$jH2vBE1L=;ao5Ud%>xw!TI|fXYE zd$If3_(=6x;-VqGHu1zm{n!DoeLp2z^CcHKT%3EydO4gov7Id7%(30{KMOl1>3Mx{ z3*b1Z7*%=gh4|ttZ}RR^mmWXf_LX$HEh&E2s4}loWSWipG_psNZ{iM2Q>h$?PgxXj zkzz0|$;$oF@TBN?X4`022#(&``VFxN%3jr830#M?+|Nl1&mMhcX;cG91!J;^8>JoD zw6Ur8dpP zW!3Qiio$*6Xtcwfz9r*TZuSXD71b=*TN8_(IT8ZY@P!i>CLjMuw;P$rRl$z`{H$K! zk|_+1C(pBUG^SDMP7BjWE-Ya5%(V_84t`* zX$`;l#bdSkzaP)2&%jKAXw&3m;64!Ge)B0LdahCCt-q-Ckgh*tnp*&1Jz%0bF^bCPJSLk*LL)I1L4MB1vEc? zr>Gn?DXc%vywfz;Ww}(WLZ;c`M_O3C2}vIL$&$?{l_AbDE$osd$0m#cE5O#!*Hf&6krKOWcNMEr#xF=Cc-@crTEyz8s z?dzW?f$_QhSNwCRig!tF!P6c2RCm#8;wlbqf2&O>AUvDwixxqV&d3dn zUHwK6U=*1vth!G+^q0qUmz*viOIQU2&NHwIaJ7(bF0(k^NIA`n_ksiRCdt#Y(0Qh# zfWL3PtVC77OZ1hrJCVQ;k{>0L4O?~cO7%OHBo4o#P|Rt_I;9DF)NeRvg2J6|n16+b zqi@d*tct)ka99NC?Gra-yjgEp!az zup$kau}6*~SiMx=sb36q>>2#-Io+M+5InzBo>aL~l4oWv{QD*CozIIWmLS4&B*29= zts!vgCt2PQ9)Ph&Dy=ATj5me3^o^IboM<~)Nm;Vp@$rqrljD=xlkF?r%ciGDq1meu z<)Bp5Idz%&Fq}~T;Qa<*{{4pc`Civ#C;p$4H}&(|KabBUhb?1&+$YTK6}OMrbsebo zicSX%$HXPl5okEU$+;YFeDC5<++m_5b^NhUASww}>`3gd$1)EWV~KBN6si`?ehqW( zg*lhp4)-b<-hPl&3JQ>9&oAH86|$NWR1Wr7`{(FeD@`NM=D;LcNP3+eX#Zo9&x)N# zj{~=SM%~11lH6g#uy|~dq07EIEikyVsP2ZHJ@{~D-I|id7Q@W7up3wfn3b)d3846V zGQa*o>Dk2r@mrksw8d+s9;HiK%#p1g8(y@DZm#M&-T0a$d|CmU6lLMRql-c;&A{^6 zLVzDDdt=#Kf*JEN{bR*6_T7v)9~wJwSyytW3R>*7Va_Y%-QKPF+_Z*#1C%cSzqUD?Tr*dB1eN{&CITHIr3#)Z6Jnw^&IJ{eXqE z=3-doEn30eT~Dt9$l_L6zDjF+@HPvt{LHGdU|zO#g+ixXDk=L>U%+!C$zd|$>XHf0 zGerL5P^gjZAp4xC)@g@Ns3r8JMH^35{^K4X-*RQyA{OQ>-~U!XMXz>ndqZ%F8ka(s zCMt#a=rFAwk^#W}SZV}iCB%Z4oXK>b{goeI{&kVo#E&1Y7Ba>ecF{Y-+=d60Z2GfG zP9`?_!&Iyyc1%`4+O=+$kL_`%CoBF*pI7lqwRcWXNwfb#`|Q(^T5PSd%XHG^X2!^k z5q^kQ&NXw1#dybjM?JjNG|sg$ekK}^tP6M8+b_ahmI-c`dFgUp3p*f_)a+8JN;ky) z?OdEV9yr7Y1Dy{OW1<7lUhfc}VE;Fj7kf!7!MH{a@FYbkPny zx|HL^IN9_R}_T?j4n&j_twz3P0u`jLD!eOw^RghxWCS zXpT@s42iK2+{tw_@o-RDI?QmlPC)&kLUdj8spU6F1#|{ukw~eq;W6QB5nudLBl{UT zbZoGq_;zf&gaaTvC69cvBRe=%YgBxN$sS_Sb0fJg>)ZA3c(|hW>`Xh}>azm<^4^Uf zfmeD%?3m+U&ApjFXEttxmtLAUcJGT*azr?6WR=7bogI12%dhc4Y>#{P-ueqzr`Mnye>#-*r*VU+g2c$}(aCxtNB^>0Sk=@scQ2?siE17t)3Pc^=JSm!622Qe z`S=1K6nD^W6l{`x9a~JQH+ts;0|mG>?+>Ti{70FM$-kxjo=4G^k6lbfH`7$Nask`u zw|`>ZlN`7Lds^SVDJ`$K(x@hhFFO@6Q#FbA;oAuESzxVcPjGMmMhws$v_$!?uXg3# za+{sx52)38=ybl$k5?-yM=n;9=S&8ieFV2OA&>6X1PJ?U5p?qkavH$Covw(SRb@wZ zjPhvk4kp=h9CQBTKiW%N93FUT16XPI<3|$5HNpQlbemu?t2JeyvijIMSv}f?`qM!1 z>7GGcm-wTR36-7QmCe1UTC>0i^S8$fr@*D=%c-iucj*Y<@GJ0m6_cr8!d_8( z!5DJDFVDI_p71fo%-X8`CX=vqkM7Qd=p8&8#KTn~-3T3I9$%?&U(?M`AKvZ5Cf@#R zLW%8pmwV`z0lp#gWV46HT|Qf$qqEhwGte2I}A?Z(fW7fgAIU_pU~QEUz;{_&zy`X-QGq7(_Sv39z8FhbN?0&!NMaq zz6mV;F+~B>F>zXENkO2HCsA(aD2R(durSl0?E>VM@7YTxdF~<8=8v4b+Y=iZ(gI4E zQYCN9UfbmoTm1g?{Cl$#&zK+nXb3_nzz-z6YPbOmF~x}89pPO74>=|pOeWyvth}1< z^wro|w6Z|e@#eK6vP*2A)rUr%e~!IOvra;u(15cv-dv^|`rwo|!IL!ddJt4< zHbkNyH=6`P9&N2D>Cv7O^iqTWl_1t_5%MV5-epvioCu{`G%h!oA#d2$Au(Xunvss_9Bl^LO4W?X;I%sDIL8HuhETC}p=eaWrJw z8MVZ|qj;dO=f;N=U#eF@#_nMBtygtT=~b6*n&%g)@;I;gd+}S2pV6J(CUI;xe5jw- zW*_7F7-u&8abdnwG@EAehnyVnT+?;TrRcIQ*VXjGc)ga=5mnp(X?^VL+Tn9ini~3I zRSkJ-c{r6SVX6-$>I)&>Bcl?>*Y9PEOFZA789A8T`>HLv3{yOtp!v)=ua;^h9`5L4 zFwcG~ZYiqfp2O^a}&MPuCXkBvjf)$687nI-7%I2->i;yNe545 zOiWQu98S%@P?gi{sHZ`c;uI(%hkM}jkwxpo)&5B%b>Hy~poZS1MOHJy-i&tYmXG=^ zV1w7CUQp6&A%z9991!da#k}I&a!cEt^x3^_tQ)C&c3B%*Yp1n9?UX(p=fF5y|tPflsD!@+5iHz0iB5Ucd7XiQrQa*_~thK zQszohkA)qKlw1x2&p*2d$5?x0~)8zq=d)D zRPoWxdL50EM$1sZZ)7t-T@OU4z5Djrxp`$AetR}3f!&8K=_vh@o%w#O zx3?ykMh08=t%oKpDD0YM?~enmuREH$|TqT7O~PkHu_27NI5C^p>Irr z9eC%dQh$1s6^%haH4w6{l7+&c3$fqjfg?D6m#7c-QJt9P?EAJUg};pB?~`TPx=SYb zunQB^g^mdr)4V`;iMG>@qZtn9cGgMd0GjK8z{cqh+qR!I&FH)Ux>A)Y-V1rOO#GG8 zh)BW*_?Iggq{)VT=zW7uH%lYl3h}MhXN9yq=H;(sKMKYusxG(Pyhfd2sA4mO)lSVY zoL(^d8l?S27PwXa!hf)t`h3c_23ij{<>Sqf0bhJU5$>)5gHIXR$|#>)7pq&<-U%XM zgxm)MHiZIbTBb^@Qr3+AL$UP)?UiuJ{$X_lWX|0|hPe1ib~T-?w|RU7s# zVusFg5n_8D-_i!Z#9xGw^s4bGoi9C3$knC4sjLUfZ=2zBY+Fc}9Zu4X?Wvrl=@Ps; zXs`-igK9WpnsVqqWFJy}zq=BUA_VHam9h<1X&ZbMc@G}S`P;FI@?ms$1!@96;&r(0 zp27Fo?c$s@rcS|mvxf(W?e71~-9$w7A=zhD+!9=sU|9842Q4wBW4oB9kqypNu z$@E`5bEyEs`(@nR5{o-Yw2rk#!Fg{le1UIzFmxTc()EoOfI%BNDDGaCB^ZZqeRI1BVl&Qa<YZi%4g?Z z1{qK4mss3xx4RSAKA21W*N@HV@i3rBY}gJDCHR<(vf=2qFLrOT_!;sg&U>ydYF=X= zBlq)5UNcB@7&$W;Vjk^$T5gSd7-2Kvzs-Nt{7V;cacOex=i*IGlZW10WbJZ`=oKvR zb{gQLzTiNs@YXp}fCNWM`0@>fImE=}I=hvKKa>GuZ_K`r5{83k$@NGqZEz1r3fY23 zoXU&t%w%h`OZm@cwBMQjglFkSNUFd~qi=tLvBQIX9~nQ{&@nhl8J=7~bf*eLUyRxc zFZP74_zhl%a9#tO!R=5dmwha_M8d2h|CTW_HQcqYBg?8%ilQx8{$q{jZao1?HVHyL zI`E#2Eue_+ow=5)li7k$2gjEX8KO5_vv@|@8GG^Q!9nZk*AFHQy!>1ZaZ*lcP3tr| z!AifEu_4-_4IfEDij+F3Oi+@En(M+k7mZDqvrW4xZ!K}RuJ<8sCi-vigP5T;!;5 zZ8=B^1aoqJ?%SyBENkA^n+j|F_Ao(?29c;=l&&K#O%=56Lh$3=N>07@48*w%h49H0 z7+Qx7$MFBRBtih_)dFK$2K<)+Zr6y@FgtGaWK(Y+zXQ|Z8<-s3Z31a^+23Z=bbM>H zs;Bt0cT;Nx>fu~th2w<b8 z%f+sRwQvn_v`rh zCvpEG`vf4q;I_|4hB|J{26f5jjq-yg3>%xFLAPj47i=OAJgPZP!iRvg0Y7ELuEYe!(Nru0I_53!Dytc zv%9|aplmWY+@UB0*U_p}XrgUxn!=*kNP8q}=Ro!iZNwQdB(P-z%HWlBZG%@&2IC?H zoOCN4{H?Ys03+hp64gXh_Xw|G9po?#1P;x~*l~jAf~_GNCNc*8{eIX)p39jAuE9(F z4e~noH*`QyPQqk<(yQKsvBeiI6>o<&u721Oug8p+{>p27hu5?3B24W9Xgzd|FW5N)WQZrePDB->Vzn^~msL85D}$|45*cz|#&-AbsPpgH=7Lo_g~j-RS8 zLm4;#MEo$H&cktC*{p>A^P&>Fzkzxvtp+B_)FY1GEZ4G>2N-fYz7m1oKW2@h-bow% z%H;AOj2&~WDspX~VT$OXM9o0h!g6Vxbt8dl1q< zG8thIO@m23hciK~#$lD+S8>iTU(*Wat%A7!EiE4BGA0?qpukL~T-YGEa2W&F**^#} zzvG2Q_EM0)eJ)`%siR#^v}Eg1xkeiP)}OxGoR1u|ZpMOGAAx%`BlG zdlA45koc)~PKhwuBNk_L5nCGEN}IbJ1{4!vggWCBhfCK*iuVNs_F^A`N~l z%W;dMEi6rH%I6LI|K|lz3&q)@g;w2C6FT9MRA)p+#Et-o$HGmxYxl1o@gE(Jm`Co@tf;2brL-X`me znn-BD<2&`Ts(`I;FvggApZ3H7C{Cf5V{H6xDh!O@55;yJxr60#Eqt&-h2t;@P@S8i zVZqk(2ZqWC)7pLpCpYw2g}E%}GY8^{d3g zcQ6EAm~|%=iu>)5U8ptK>yf%}p1R>BzxN7O{`T~3{R=j((~6oXnXET)j0@bDl5Xr3)yyN$iGtG!4e7$}Oe2XBH)h`@9HOlaZ=8E*?r z^!QB2_nvpOh%^8>y)OLWRkn+*Zle1#R^h3XL&Od#LR8U)v9mssPKMnTBX z>9_hANJZgbyod5Ii79^jZZmoJMp5M@R|ZXO3C#3j^_mI1LU0$q+Gc98c`kcZ#8>tR z`AP%s6Llh5uT=Y&Bm!_Q8~fwcI`>={e?l;+qGJG}3sze+8o#v5qfY>GQR*n&_C{np zp(vUPafb^3s4w!%fd>D$PmXcQz$L}F*y5%FZ5@Um6s$0T5Z1}_tV4f^^s~C2gMTy| z{A&9+J5L$YZ7C(dvglKCcGNR@n79j7tV@v2d>60_A|OkB>A&hMAHl`EX?3>GcHbEd zj1$iCxzZ#LHt(%G;gxY~K5F?mQkFDX{m0g$`kE2MbswsR4iVeopBCSK^_v^X;s&d0 zg@nk6NGU?=GiXnrp~{nE;JMZb>ZE)n?5I#KnbuTSLEaq#GSfW2J4lDZTDv)_K#@BC zYpau0n}R=BwW@7#Cn(Mj?EhT?9r+41^OZSKTL#+-o(Ep7(6f9uJeg{P(r@S6J}LA< zNYcP8sTp2LRPM9pd~mz&?5LfG?A#!I zG{a#-uMns%kSbOnZ%M2>D{+6$$KoaGN;r%rzUte_G~ssJQy-(=!`{DecVu8d10{na zr{U^&n8~8Pvm7yEqsATAEY3iumZN6Ccf$#6K zKGJ1vRgXH^tp7#ZXYY~Ik_9G?>3W1$<(j(2-hTJP2y}o_=3iFaGSl~=^MLvs!mFVb zl}mktU*CjNJq_ip=0EwM@U7@WO2e+J=f%{jpIhRdDaq1Y^cj@6Lf zZTa;D2V(k4TEzkhj|?D;9$owJg^d%K)Dc_}Q<|J!IPAO^5jYy3&sEg)S;0bL=IgeW02zQ&Le z09M6XR@x#2yaDw6Cps7RekpN$v<>?Cj`*=}C!bf5(6uKT%x-R#Kt>}T99SQPcDPr$ zl7koA^@Qt~OjKL9oQ46k@x?%v-Lj&QBFb79wgXJSZ!P{K&z;H%Q}1S#RB#0-KPdKbn~#6v+o+gmjI`I9g3jBVVMU!vcPMgR zDBD1SS6y1nQ;5;_1ENEaoA6w_r|EWO2N~#o$hlf*X!RdMb4Lsew0mr4XPgON81U$H z5R!;!1jcGtCK=j9n8{jVY*Sxzj1&N*Sa4GS7!vgP#x$TF#!5sU>R1cIAr@aU*6-|; z`JEr<5~KWmi_l*T z@QHW!4BKi5pL=Cuf?Hq54Gqik>$QOW^Le*7Tg5b6U_SMr3Dz05+aY{S?)N~c0LLKa zv(0J8&kg!;ZX6>7@x8^ZhZ7u2p08)S7w+M;r;fRM!=$Vd^vgd?Oo-6~BlP zk{<^^Tg%#Ny-uWfEH`vTbFvqwh5FK5g5y+SWqioLo>4@iBCZ;so{#m>&amNn)nA)7 z&k963t;)X_nx8vQ4gMEsun~dv;?|8Bs0oW{6nbm*NL8sRT#s5&f5whwY>#znHCNB{ z_q88EQS40!zD4|M$U}SJVs6HrzLie*7A4P^HZAu%>-tlNc@0Tozc^QFc{U7H)l$LG z5?I60(p61of&yQHc^M>O>bi_;4m1YU1m@CH18QJ!esF&i4vi^ct}wL`Zty7u;>tTP z^>Xk;P(GCf{y*&2NBy${))#7(OA+Sc#pn^b8c{MRFrf(tTSFCegI7MX2}P50;y&b$ zW0I1xV#OniC27Y*dFVDr0{mmH#M-rh&~n-`fCEFp%s_>8N7GZ!vx~ z>X4P!lY33*B3s0ZSHWM7gP$r>c-*xhW@|qCfV7Guv!ka18&fn`I0|#ZUd(NQ zCY-W+Hb66WtS=G;R+QK#3ZnChSZ>1%p*id+nN#iHmPjV|efqaDz8+Q*Y)Gc}zzh-q>9oHfwS8OI~e)pk6i;81so8H=-Z~-a=`v= zqpvi(em0AKxa*mD6ZOa`Yte-N>8-Xo4PZH77uBGT?bP2j7|Zd_`i}g|HPzk-ilOQj zQ0g~hYbq`N#0iezciR`T7UA&8PETWXAe%aWG8R2-X)tvwc%24VwBDQihvH<=jY+YL zVbeVoHJt}Gvdbo-reUUJ3WLM%pKZC#25a8IJbG;fb!y(C$sFJVs{NuUum99yccZ{@ zH#k;UA1;-RO55^rdzlKNWVLK7{8v^0l?uQN+z0N{w1$-oF;Br2L>;d<0ZAPq_+b2p z{bB_a3XM0FOYwFaM%nK!UeL_G>AA)`pM5(7<-i(K2vytks_ z>v&2f4V=n=(clB%7`gmpFWYsxV+E(t{*Tgchkpd^zcobkJ;`nn_%?e+@20KCjwDZm zaq*YA!)#GrjA+zyQ1)?_T1_*?5$ z-EQ=m_K@MgDU}}4)L(3`veS3480*Tu;Hxm@FD_-_}*B?T>VW=;6dX!l%1H^y-DD z)&ZEAg$0o%e5&+|g)nKK(VF6L+^r4oq?&N*ETJwZ#v?VqO`CMoRi>Smn& zS9XqJX;^o~Cow2olr!>$zfuA6WlEe;FSy-&%JGQTy`4!`Jt=UyQO)`q7{XW()pYMn zWqSe-AUGRK0n!0!)LZ*|ne(MW#6bN87Bj*@AEB&|$qt3r-f>_z*RQL}?Y4rT0)0UB zOHj&p-!AlqqD?lC&ggA}($X+-y1hU)4KhS$vrC-cyHtpV*N#X7Q^)%aL5c{oy2?!; zte{Vwaf9clhv~o3A5I&{LLNCk64`5%x4iM7s1{hMDzAO9OC$XmA}SvfG>SQEJ58AX zR#km)F1n)q=ZS?O0nnZ@^t(sow0$c4PyCXCAB31xgPIO;h<)>61lmqMV~!B1a`-0< z?r8E@&if*DTvCDQ0RALy2ol+yUuB~74Aqm3JCT{uw9sC3%8CC<=`kz7B8Ex)BPf<;(!^bMvQeXa0Ny>t&AKssKgFfD# zFZ14onv8B1yBl(*mv_X@V(t3o%jAcsa7-XNj!8X&W1OL=*h4*z@PKiS2aMpg9Gtkw z1O>8!EtatlW90jLIn#B!GYGD4n%Mehhj1f|#ueu!BNvX*i$Ux>Nx>@4NDLI|kEyo= zWa;9x*uG9^5ag%Z-|ar?%&l0K7(M!c1Xsr7ud>bwws+Ww)$CvMb}P?T@|Iq->%8fA z^f0h>GD$~Ic=5WbQ(2}>7-MF;Xqgb>W`QU}GveH&NruW}T zy#O zA$fQ+oid-_KT-3CjnlmS7rXw7U~bg}56$0-0=(ftS~X}5&~hVm!OSaLQ-bKm+-bsV zXXgaKIcX^FpOp-~kL_x;^KvdGM2gxc@~oHBzVefQe&sYZFu{Erqaww55c^~U@7p%S zNc06I4|quoEAg*q*nsuJ*5~@>bK{MVFL*g!ua(F16JCE_Nwz1>*=J(DxiN^lSLjC> zgI@ASB2ITKCIRgRBpLZHIMWYh$6g#IH{Dw+!D6j044)gtU?JJQuES*I#6r#61Hm!? zyg0Y-3tlKpoNK8k{NJ6NmM1Dr@VeTQsw?aJFoCw zxqqWjO_C7=pp2L5<~wJ<`+}$pArMnb6KxND zUX0-*;a8=w1XtM8Ye@?{PQeH)NaYcEG3EgxVrYw8@;l9jPkZopW_vB4Ck;4{iUCA> zs*=QGfof8}qBET{a1H~xbS--`tsoY}m%#RM{u&AeM(hT;;IFVxvSW^lGwFa6%!1jp z(fLjVG^ilhZ*8N5O!u;17TWAmKIRV%Z4Mr+l>?(>`kK_w=GdE{hDFq z9Z+6|XkuZMA=^9uwY#W|WGS1pR>+u@rlm3Ml2oYIi00aIeEzH4Dn??9Fl}>eCLGAPF06 zM`b0MH)HS*sVx1ORbJ#z$Kl`e$*z9}uEjrO2GX`a)hS}}Ij*2Mqh(P8mgo;f zq^J7Qccd!G{8t3wEjxUWKE(wT74c7?!}3{P&mDq4%o9%`L!LaY%=K{Y5{2W=cE(>x z<7UzsKQge7-0Pdt@K9Tg3Mlk}tR%g;ym7gW`FwcZQc(dV%msfZ_A^b}O^WmPMyc;2 z(`P^7k~H;{M;O3NBqpfF=w*eC){<+}9%YwmTnwJ7pvZ8ol3RSA?-hm? zs6i|r_0r@GkwEg}@@jjP;R$~PzCeEV2u?qheY4^F7dC+)P;SH#iZqMwtW2{yCy+?NcQdCrMwxnq!gCizVNS#^HFY=sJPeU@A0vx zvNng$#9Q8Wwtn-If?(896*2eG)gz4A^O5u+Y&9LeQnAC-xY?!`NmIBZVV%nv#Z8*S z>eskQNNCNjf23l4CySd;LsJRv3%}_9hTw;-KKlB()_c+9?<5ronCwd7$y;iSxSH6V z=bUoX;Uugt;9Cm2ml1CGl!%WD z^kv5Z_4_^T#Vej8*Q>Q%xYVuh$eG%QJbAlKXj_~2WvkP%#$UeCQ1C)v{xA@%n$$qP zr>K}6Z<`WtlOfBIuM7}ghTGy7hNzMEAItCYk4XRTV+4bxMigBYJ@_p?vGFGbQz9Cs z>2@~~y>_$#VN{7uYdZNYqnqP%?WlCb)a|kMpw$jeY-tey*exf98&n1zJg4CF6lt(N zxbd3P*tZ-dp+Kt@d2xhCKQ6JPDd^KIy)QrmSIW!q4YQBo_dfl<3X9`ODlQg88UWQ~ z)~X~?wIb@X$gPn+q%y_YRJr=bmh6*Y)utj}dYvD4jR83v@aX`aP6bi;btVJkj?lq! z1Vf+eM~MUHMbP3|i}|ooq4q$m7ka24KMS9UO5V{Vx(`3dEvzd`xD?g zmj2CqE<=H>L4^Dek(#p)qO++qRrUNhT)F2t~wF8FBds0Rdy?- zlcXrDO>p{;2fl?0$O7P?L|-6M8}-&JcOl!Cc<|bM-U|qxlN{=kf!cwjhQMK4ANwg* z+&HiGS3+ID4!y|=76a6ac3Xa3a6_u*F}7IzxVR?AiS5SPWVzO7>L;SFi>}_XpJ4}~ zu@H`le4;IS!@W(oujUkXMa<7uFcFlZgj6Llfj~R0RC=N6+m9aXoSdR!pig*m;!C1_ z{pDADNRhL6S(%O59i;g6ENa5O0MRaX>s=R3{>);m<{!Z9L9_!%x+mHtP7_o>r5A(- zE%Nw?T@B5+c`*cII>)uZ0(hfxn*b~w?;nL3=Liq-zIT~s1WdrI5k_#EOkZ+N1Wg(# zCBPCt+%q>gHjWxLVo70pu6kmTVni=37+L8~sL*dx2-=xnx<)0Jk z{Uv(&{jOUuNb#9Np?P`Q)(&4*6L=V8P+)F`dO}_qx^U4pA&M!zL>1lBy`3l-YU;4* zJ_$AOp}V5Y`!rvNZp3CNc>{20ZcVaz#?$UdsC_ztZg(P>Z74GnZi zs-StUpEVJNkMZRFVZ!Shc?I8#hjsfe>y7%Qw>+UA7Z5By;YMTvI)yp90iv3OsjP!<;@oOlXTz@K!V8Ji@fhJ_1Vmww6-}*_bjp0w)=6=W+0`>vXJw)7i@C`(&r% z)mzK6uhX3e&q&w|)ofX(xH|XRQ#=n? zEyivR?ga z{a7Eh`v*0Eaki7tO{e=W=MU#<>GeI^x<9?vHvUE2O(=v2>LX~n>`!kn=Lk4gXFLBi zuBg~Ze9Nyew&oyG(}m7lhWJG|1%N8Eq*(h0Kf_(eZ5;5uJf!!advnHi-4F{CUMR@d zUOb?zoEYj!>IaiQC0$rbQdKP>F27u|H=75gra3nL;4YBPm)cVfrGAL~XZzxqf1O(Z%M(sx=;drdjSvdgP!CjxYgWpr-0+?0M3wrb5YpU)~ zW#{T#K%+8Y%Adn^*~O99%vel4bZMV{19G()CA7u&~I{8XNtxm*bURBpjYO z`%V`iDYRQ-AfAm!C3>_old9lGlH_Npz}QbOtU~=)VdR^V+q{_C>+xjrg)>coW2|}c zi3e9a&%Reovw{)IrmY=i^0zBfyQ9y$^YHRefCKnMlj_R(fPb5ak-%Sm_hp^~OK%1a z%v|DU?pjJqoaT;m9cS81nAC24U_psy-EtS@uZmC3Dx{=wwN>hsMZp0kxEQe1xL$lw7CreZ1i&b&Vo|N8SK6(9k7eBsW&Cx zmb-6|c}3_loiZ|;&xfD(Myex$UcBda^8L_BC$gVib!dFYrXKSL=RcI|oD%n(KN3WZ zip4^)=guHu{A7Qm?IJfiMDLKKR2Lcpo3QSvNXO%}^3m*mb(D-QQa8QVb(!hU#Egj| z31Jpbt{b4s3>!@SxtM2u#AaVj1pQW0)EYn|y5paMjn-+nuQU!WWie>SAmm~OxP;W~f9p!!nt9qC`d>`; z<7f~74oMu$WYbc938y=Ap(GL35&#N{9T=a!aP3%u^eUw=7)|&RT{}3HJD53jfYeLw zOY|vosp8REBw$kp2eZU+ch(Zbvb{7R=cILiShgSKS{50F#~KFy6dg$7os+T<&=-Ku zFmASOp3H}|IV#S2Zj#?8U(Np3Qu{EnL{)YbXK}kXmIuoR!3B%A+h2q7VQFKSF68~Q zXhVV!gxT#*-T{C0352)djkxzlx}PeK#XsB0?TGWTkj`*UDai^*7>G;gNkZr86{21@KvOJ^kOaf4moCloLS{4X$s$`ng%T4}K*OHb= zSgLR*o4w3t5U3FTrT*Xu_aF{UWH?e=k7Mr3;+xr*`?KMF zAJCWuEo#Z~4Qnr`kHbhBHkfWfiS;p|CEt7R-iE<S40s?)zJ0!llZ#B8W$P@(4 z>ofoTCMqQ0e4#F#siWQpRsfumetcN4W%@PQW$7%65^+^z!Jf{mHrR<}w}0L{4i}I zNN+?RNpefXD4d{wUdGLThn4v`qMycEu5-6dNJpcMhd3(MFe8~*S3Lot&sK|36G1H$ zT{=u%@rsAI3M~)_Yp&ikd~(juj^9PyfMp^;n&Sde#%DWl*wm4I0u_QgY)(Bc;V>VlsZ{-_R*Df%|B-Hg-=puxx^1&ywZx30D&gHZm8 z3*s~qz+0-@QIzJ9$o0-R4N@G`juUZJHk}F=MHp}!4{Od<~UY<)C) z%g68Wn%&SCAgnF=Ona-ZjG`*ALN@w2me0hVC*9xbw{Z{dzkLUf6OJ5Av>dLvq+Y&Z z=4kB83A67TqOr&^0Ope&%tv>Ug8C-MKMP}z5g!;TbW$Xcb6a<1@vaFI`RX`jzuegv zetQaVWQ+EkBR~gr4QDz^fSfE(x*q; ze)%=wbEjh4WS~!}N;-{Gsg*iVg_c#-)ax59j}y#|%yeH`Sm9qgGZJ3P5zIcqv{r|M zz&7fS3BOqNoj7sK*NBw%ZlqLWGo5*3N;kwxWXOs?P@DnGF2p^p-#-e$ZcWJl)|$Vp zZE1gc`AjYT%YJ?JjpY>@3o20-A-rW@8^hSmWxkOhbsOS|8`E31VhnV$4>$_u%h1<9<)m&r{|UJ0Q}{#QbP(VRGNonL>1pS#-ark8?jW zU~TXaiJ~NHXhdK7QYn5HmsKF=?`v?0{ZS^8JV_KWmUmn8hak4v+cfLbNZLe(G0BzU|% zcMpv|ud|f8D&*n>jb=Bw|3-ud+-mg5`4MNxWEnJ=>ylH!13PO89R+rP67tma$RM1o zu#JKSiJ}kXRFI~m*;7Q>rqbhC9$P+!Lo$rm{uEccpGaz8fp-fu7BBw|xAkPedHJZr zKL85??T@G9!Xk+9tpN;73r`5K-kV+d;QUW6%p&IboPC#CaDjxInaOyefurIQK?>+y zRxIUDwj;&|`!)i)bLn% zsp&#%5*qqbO{4-zvBcy@gSajQw?&c(fG!!YF5p$$Wh-0~2rR?oqj=Gl8@=uT2P2=W z1v#i#E|+Mf!P4D(^^n*a5#vt!qrWkaveV!pRp|!A-V`5J)pTDvIgw3kJk<0qOKp%X zMX>~rR0-HXMyYw8uQg+CcX?Axtl#%RVT4TIk}Wa{-pOEHk99|$>>Jm{U}aL}sNYc~ z0MIV@xQ(;|N7xO75B+R(pdoP&Mz|2$luPbNJiuPc7ZAWMKT^stL@l}?U}$qXB98g? zL_+AhPsV%xf8Rzj^(>AIgL=MCvF&&Yyg*=Cnn^2(_=@pxNny0Xz{@axC3-F#S_muf zoA`>l=!}kQpG_r^251sj>$Q~15Hi}QO+|aWnCJV zbHRsurfi$P3yo{xB&)z7-A#Mi#*C9*-V5tX&fMPrBJ43l47y^AtcVgS>aC=U!D zOZ@RxZyK~4MQwUk4;_`xlvxs-fO5gzXnM8O=%R3h0E2oE&|J!k$2KP;k0}%GrfM6` zUStvHC16_~)A%c7_+R!blkZEGGE*ojv&ktD{A>xDC#1{7LmY1}Mg}NPN&^!JP*Z^U zNd{$Zkm^OelB3!!M1UT;@>00JanH~ja%^AJhGvl(G0DuAy8Oa#V@|Ge)rGd4&RV3` zYXsPuwQ$MW))b+Syn%37V7>aus*dt1H0Y;jO6pr32Bfs); z-cx&4J{mBZQ0Cnwx_l8LmJiaP09?7I%^Xf zP738~Ia81((TPv{#`wmB*vh2T>yKqqF)`J2otf!EyDWP3;V`mG9p%CLcZ|EqtZ@nc z&&Ofl;4$d=f(37{ORz{rg+24+WAA-&fF+5P4W%uflz{~?nv`Jr+E7~;me|_AaZ)`N zz>?S2err4Zjo%V4ovid@O59m8JLX5x$)s5}02+YG?lp}&a2xi<2a~Hp^@w(`vKUHe zcT%K7t&GZRQt8k`wb{EFxOot^fJsCN^cvYHMSa0iEkuoT6}XznG^c-gaBt2nD2N{eKvN z8Lbp+X^;oNLc(a=&BzIf(t*d(RjKz_UPw;pkfY01=!`vy;ch8x1_aO0+6^S@DE>RMEIlU;ZIg3 z7UHUR#d(@hVJeki3j)Au<4;dcfOXN2pERol@G?;^gpzPXWBR8#foS;sIL3Qi!6|ge zFPIKiIYan6V*E-Y>5>fD+pu%>ugt$-#r3L{th&M0X5;R&iz7I)Pj_>`o;8oYOfwnT z^y~5mF^4l!p?0&Md=@#CM2nUy^Jx4pm!S+F!l)eMB2G9PWQvb?adIzfctqtz}bEKUH)VfSX4AGbL%;IO?+?427G z?ztp<&(ZmVdYv?cOPE9VG>on}g*sOeNmD&AE-A?4K~h$Ufl)VW_XUZqHNA1+xnzPg zuT<=wJaBf=K(BPQYqF;_X#M@a6k$dqRZx$MB?P`qt6%Lg<5g5eF`&bB4B;X??@`6Y z`x?)vfM_l!+7So@c>kL!cB9H|o76Qp z@S{1=Kp?jAk*07$;996#CzGsqajbUx(}Ch&uxmsnvDoLWnJ%@Rg&q$v8H#_V9#%{5Qu&OY!gfCok*Nw<#N-BV*u;RE3Wf%AE&e}(;@SrJ2OqqeJ zI+T%YvlNQwW%7tVCIv_i7V}RsZt+|ax~o@f2ln|zp)?%#!kF%bCh4P4^R0zqy~IN? zls5C)!{TUX1uTL`&5Ny>lY^Vow9bbCorVt(clOGyEJ66ZJ8?{EtrN~0H2H_BU}#fg zI$;kc9NL#B63>tJgkbc<7o%T)4;MXb+l#jag#}JWRt6o;{=U9ahc-2#!@*5>qxKps zMRA=+HyAbYVcC!AQM+_Uv~eK}adBSXFttZ9>d%*4qy;-JxUA{G+>5@G6!YgyTu`RP zB${Tgpj3qvqmtahEZ}!+gy#x2k(As@SW2Xkm5YMtNQ^6_Z*4nuvWaYcV^`9_+W=}snaL}f3tDLw*~svydYW2DUcCO5ZPa<~ycq6JHHgxM@W-l<9e`P$KPx z(bIP7vO*~w9p)LX61D=#+ueC#5uDiVfCE&sp{wcZ!wmls62F8%_U;q2M9wjo z^o6K#*|I=WY8Gm^XGuQq)XimK&+Vz#jHb%<&o|6=qV?V%{)uDu9o|cb%21xQ`QHphUxxx?PN}43 zsoroFXi@1A2Ku`6|0-<8!;9`)3lUaf#_)g3Hx!sX^^blRW`=Weab;1vVapTB2Yob} zsD1m02EITkL^#3Xi*Oiua-3Nad6skjOF8AGd)rm{LyIO)D1Xm=kxd*Se|t}L0Y3{& z&C-X2yq}3fM&g8X1FGP*A(F(G@{sK@BFe~s13i*!;DIuiV;SBYt}fggHgNrSEaYGi zCd*FCeZ48CSmkhuZYWEhCD4*&<)WFcJN-%S_rs5g{;T`9Hm^BsKZ5yPZcP84G)sh# zYb5NmKG6sNdD1}GLMhAjc7MN=&Oy!%|LlafB5yvVpJnRbaLh2zb-M+NF6Au5<_(2i zVemXDQiIrnW>6m$D;L$oIyoX+!qGzBsoWl9t`B_-xLy8n*7of`G*worPqR_rC7tsw z+;%%V+0+yTU=6FlS1ZyXC=QsNRTxA4#Vd<5ihht!LP=L^nk>l1SM~!eTmiev*bwR* zdw4tK9~3S6<`xH~4YvS?INnSLB{M$|(Ew)f!~Pp<+ULEDS0#T?XdJA)OFg+cTa1HW zML+fk`s>eNPNYtgh08v88w>smV-4JP+ZYQ6sR&tuiE@LS(lQ})ImzC8^JAFCW8D(} zm-0MQSat5Cyr$4*nq zR8PUzts)>XUxf%#yw?yKLqU35Gi+y^CXa=_?U8WUVsWd$E7!`1-JM2q?p4d-9Pcb?u+ z3V5Yw-yFKa-AWz~>|d<}vA3(c)I1@ze-lmdHAf?*}e-;Djtim>~MI<4Es2)p#;UG+Pmxrs9$? % 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�m#Pd;Zk2CbxNnRv+Y@*Z*w^9S{T; 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⩔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 z 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 C*Yi*S literal 0 HcmV?d00001 diff --git a/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/Contents.json index 0d49d1d..bd33d12 100644 --- a/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/CloverConnector/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -103,8 +103,9 @@ "scale" : "2x" }, { - "idiom" : "ios-marketing", "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "AppIcon.png", "scale" : "1x" } ], diff --git a/Example/CloverConnector/CloverConnectorListener.swift b/Example/CloverConnector/CloverConnectorListener.swift index acce9a6..ed5c035 100644 --- a/Example/CloverConnector/CloverConnectorListener.swift +++ b/Example/CloverConnector/CloverConnectorListener.swift @@ -11,6 +11,7 @@ import UIKit import CloverConnector public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAlertViewDelegate { + weak var cloverConnector:ICloverConnector? /// View Controller being displayed, used to present alert view controllers @@ -23,7 +24,9 @@ public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAle fileprivate var ready:Bool = false fileprivate var suppressConnectionErrors = false //since connection errors could conceivably occur every few seconds, use this to suppress them after the first has been shown public var getPrintersCallback: ((_ response:RetrievePrintersResponse) -> Void)? //used in the MiscVC to allow the user to select which printer to test on. See: onRetrievePrintersResponse below - public var getPrintJobStatusCallback: ((_ response:PrintJobStatusResponse) -> Void)? //used in the MiscVC to allow the UI to respond to print status. See: onPrintJobStatusResponse below + + /// Dict used in the PrintTestVC to allow the UI to respond to print status. It is the responsibility of the caller to clean up its closure once done. See: onPrintJobStatusResponse below. + public var printJobStatusDict = [String : (PrintJobStatusResponse) -> Void]() public init(cloverConnector:ICloverConnector){ self.cloverConnector = cloverConnector; @@ -41,7 +44,7 @@ public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAle /// - Parameter duration: The duration to display the message in seconds. Defaults to 3 seconds, must be > 0 seconds /// - Parameter afterShow: A closure to run following the successful display of the message /// - Parameter afterDismiss: A closer to run following the successful dismiss of the message - fileprivate func showMessage(_ message:String, duration:Double = 3, afterShow: (()->Void)? = nil, afterDismiss: (()->Void)? = nil) { + func showMessage(_ message:String, duration:Double = 3, afterShow: (()->Void)? = nil, afterDismiss: (()->Void)? = nil) { guard duration > 0 else { return } print("MESSAGE ====> \(message)") showMessageWithOptions(message: message, dismissAfter: duration, inputOptions: nil, completion: afterShow, afterDismiss: afterDismiss) @@ -499,26 +502,9 @@ public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAle } - /* - * called when the device is initially connected - */ - public func onConnected () -> Void {} - - - /* - * called when the device is ready to communicate - */ - public func onReady (_ merchantInfo: MerchantInfo) -> Void {} - - - /* - * called when the device is disconnected, or not responding - */ - public func onDisconnected () -> Void {} - public func onDeviceActivityEnd(_ deviceEvent: CloverDeviceEvent) { DispatchQueue.main.async{ [weak self] in - debugPrint("END -> " + (deviceEvent.eventState ?? "UNK") + ":" + (deviceEvent.message ?? "")) + debugPrint("END -> " + (deviceEvent.eventState?.rawValue ?? "UNK") + ":" + (deviceEvent.message ?? "")) if let alertController = self?.viewController?.presentedViewController as? UIAlertController { if alertController.message == deviceEvent.message { // this check is because the events aren't guaranteed to be in order. could be START(A), START(B), END(A), END(B) alertController.dismiss(animated: false, completion: nil) @@ -532,7 +518,7 @@ public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAle public func onDeviceActivityStart(_ deviceEvent: CloverDeviceEvent) { DispatchQueue.main.async{ [weak self] in - debugPrint("START -> " + (deviceEvent.eventState ?? "UNK") + ":" + (deviceEvent.message ?? "")) + debugPrint("START -> " + (deviceEvent.eventState?.rawValue ?? "UNK") + ":" + (deviceEvent.message ?? "")) self?.showMessageWithEvent(deviceEvent: deviceEvent) } } @@ -672,22 +658,34 @@ public class CloverConnectorListener : NSObject, ICloverConnectorListener, UIAle } public func onRetrievePrintersResponse(_ retrievePrintersResponse: RetrievePrintersResponse) { + guard retrievePrintersResponse.success == true else { + showMessage("Error retrieving printers") + self.getPrintersCallback?(retrievePrintersResponse) + return + } + if let printers = retrievePrintersResponse.printers, let printerName = printers.first?.name { let message = "Retrieved printer: \(printerName) \(printers.count > 1 ? " and \(printers.count - 1) others" : "")" showMessage(message) - self.getPrintersCallback?(retrievePrintersResponse) } + + self.getPrintersCallback?(retrievePrintersResponse) } public func onPrintJobStatusResponse(_ printJobStatusResponse:PrintJobStatusResponse) { - if let jobId = printJobStatusResponse.printRequestId { - let message = "Print job: " + jobId + " status: " + printJobStatusResponse.status.rawValue - showMessage(message) - } else { - showMessage("Print job status: " + printJobStatusResponse.status.rawValue) + DispatchQueue.main.async { + if let printRequestId = printJobStatusResponse.printRequestId, let callback = self.printJobStatusDict[printRequestId] { //check that we have a callback for this specific printRequestId + callback(printJobStatusResponse) + return //since user has provided their own callback to handle this, don't also continue below to fire the default behavior + } + + if let jobId = printJobStatusResponse.printRequestId { + let message = "Print job: " + jobId + " status: " + printJobStatusResponse.status.rawValue + self.showMessage(message) + } else { + self.showMessage("Print job status: " + printJobStatusResponse.status.rawValue) + } } - - self.getPrintJobStatusCallback?(printJobStatusResponse) } fileprivate func formatCurrency(_ amount:Int?) -> String { diff --git a/Example/CloverConnector/Info.plist b/Example/CloverConnector/Info.plist index b49098a..7d297e7 100644 --- a/Example/CloverConnector/Info.plist +++ b/Example/CloverConnector/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleSignature ???? CFBundleVersion diff --git a/Example/CloverConnector/MiscViewController.swift b/Example/CloverConnector/MiscViewController.swift index 4958e0d..90b1b7f 100644 --- a/Example/CloverConnector/MiscViewController.swift +++ b/Example/CloverConnector/MiscViewController.swift @@ -63,12 +63,12 @@ class MiscViewController : UIViewController, UINavigationControllerDelegate { appDelegate?.cloverConnector?.sendMessageToActivity(mta) } - @IBAction func currentStatusClicked(sender: UIButton) { + @IBAction func currentStatusClicked(_ sender: UIButton) { let dsr = RetrieveDeviceStatusRequest(sendLastMessage: sendMsgWithStatusSwitch.isOn) appDelegate?.cloverConnector?.retrieveDeviceStatus(dsr) } - @IBAction func queryPayment(sender: UIButton) { + @IBAction func queryPayment(_ sender: UIButton) { guard let epi = externalPaymentId.text else { debugPrint("Invalid external Id") return diff --git a/Example/CloverConnector/PrintTestViewController.swift b/Example/CloverConnector/PrintTestViewController.swift index 7ea8831..0723cb1 100644 --- a/Example/CloverConnector/PrintTestViewController.swift +++ b/Example/CloverConnector/PrintTestViewController.swift @@ -21,13 +21,11 @@ class PrintTestViewController: UIViewController { var selectedIndexPath: IndexPath? var selectedPrinter: CLVModels.Printer.Printer? { - get { - if let index = self.printerTableView.indexPathForSelectedRow?.row { - return self.printers?[index] - } - - return nil + if let index = self.printerTableView.indexPathForSelectedRow?.row { + return self.printers?.optionalElement(index) } + + return nil } var appDelegate: AppDelegate? { @@ -36,6 +34,12 @@ class PrintTestViewController: UIViewController { } } + var uniquePrintId: String { + get { + return "\(arc4random())" + } + } + var printers: [CLVModels.Printer.Printer]? let reuseIdentifier = "PrinterCell" @@ -68,24 +72,10 @@ class PrintTestViewController: UIViewController { self?.printerTableView.reloadData() } } - - //setup a way to respond to a print job finishing, as a way to cleanup - appDelegate?.cloverConnectorListener?.getPrintJobStatusCallback = { [weak self] (response:PrintJobStatusResponse) -> Void in - DispatchQueue.main.async { - if response.status == .IN_QUEUE || response.status == .PRINTING { - return - } else { - //printing finished, cleanup - self?.spinner.stopAnimating() - UIApplication.shared.isIdleTimerDisabled = false - } - } - } } //MARK: Printing @IBAction func printText(_ sender: UIButton) { - let printRequestID = "testTextPrintJob" let textArray = [ "Congratulations!", "Today is your day.", @@ -99,11 +89,12 @@ class PrintTestViewController: UIViewController { "And YOU are the one who'll decide where to go." ] - if let request = PrintRequest(text: textArray, printRequestId: printRequestID, printDeviceId: self.selectedPrinter?.id), - let appDelegate = self.appDelegate { - appDelegate.cloverConnector?.print(request) - spinner.startAnimating() + guard let request = PrintRequest(text: textArray, printRequestId: self.uniquePrintId, printDeviceId: self.selectedPrinter?.id) else { + debugPrint("Unsuccessfully created text PrintRequest. Was text provided to the request object?") + return } + + self.issuePrintJob(request) } @IBAction func printImage(_ sender: UIButton) { @@ -116,22 +107,17 @@ class PrintTestViewController: UIViewController { } @IBAction func printURL(_ sender: UIButton) { - let printRequestID = "testURLPrintJob" guard let validURL = verifyUrl(urlString: urlTF.text) else { return } - let request = PrintRequest(imageURL: validURL, printRequestId: printRequestID, printDeviceId: self.selectedPrinter?.id) - if let appDelegate = self.appDelegate { - appDelegate.cloverConnector?.print(request) - spinner.startAnimating() - UIApplication.shared.isIdleTimerDisabled = true - } + let request = PrintRequest(imageURL: validURL, printRequestId: self.uniquePrintId, printDeviceId: self.selectedPrinter?.id) + self.issuePrintJob(request) } func retrievePrinters(completion: ((_ response:RetrievePrintersResponse) -> Void)?) { let request = RetrievePrintersRequest(printerCategory: nil) appDelegate?.cloverConnector?.retrievePrinters(request) - //connector listener holds the callback that's passed here, so we can chain together a printer selection with an action + //connector listener holds the callback that's passed here, so we can populate the tableView with the discovered printers appDelegate?.cloverConnectorListener?.getPrintersCallback = completion } @@ -147,6 +133,45 @@ class PrintTestViewController: UIViewController { @IBAction func closeButtonTapped(_ sender: UIButton) { self.dismiss(animated: true, completion: nil) } + + /// Private wrapper around print call that issues the request, configures the app and UI for printing, and sets up a callback for status + /// + /// - Parameter request: PrintRequest object containing the information needed to begin a print job + private func issuePrintJob(_ request: PrintRequest) { + if let appDelegate = self.appDelegate { + //kick off the print request + appDelegate.cloverConnector?.print(request) + + //the rest of this scope works to monitor the print job. This can only be done if a printRequestID exists + guard let printRequestId = request.printRequestId else { return } + + //setup the UI for async waiting on the print job + spinner.startAnimating() + UIApplication.shared.isIdleTimerDisabled = true + + self.queryPrintStatus(printRequestId) + } + } + + private func queryPrintStatus(_ printRequestId: String) { + //this closure is kept on the listener, catches the first status update for this printRequestId (after it hits the Mini's printer spool), and then polls until the print job is done + self.appDelegate?.cloverConnectorListener?.printJobStatusDict[printRequestId] = { [weak self] (response:PrintJobStatusResponse) -> Void in + DispatchQueue.main.async { + if response.status == .IN_QUEUE || response.status == .PRINTING { //since we're not done, perform another query after a short delay + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { + let request = PrintJobStatusRequest(printRequestId) + self?.appDelegate?.cloverConnector?.retrievePrintJobStatus(request) + }) + } else { + self?.spinner.stopAnimating() + UIApplication.shared.isIdleTimerDisabled = false + self?.appDelegate?.cloverConnectorListener?.printJobStatusDict.removeValue(forKey: printRequestId) + } + + self?.appDelegate?.cloverConnectorListener?.showMessage("Print Job: " + printRequestId + " Status: " + response.status.rawValue) + } + } + } } extension PrintTestViewController: UITableViewDataSource, UITableViewDelegate { @@ -159,7 +184,7 @@ extension PrintTestViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let printer = printers?[indexPath.row] else { + guard let printer = printers?.optionalElement(indexPath.row) else { debugPrint("Tried to display printer that didn't exist. Off-by-one error?") return UITableViewCell() } @@ -188,32 +213,23 @@ extension PrintTestViewController: UITableViewDataSource, UITableViewDelegate { extension PrintTestViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { - if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage { - self.spinner.startAnimating() - UIApplication.shared.isIdleTimerDisabled = true - - //dispatch off of main for the re-size operation, which is relatively heavy - DispatchQueue.global().async { [weak self] in - guard let image = self?.resizeImage(image: pickedImage) else { - DispatchQueue.main.async { [weak self] in - self?.spinner.stopAnimating() - UIApplication.shared.isIdleTimerDisabled = false - } - - return - } - - //dispatch back to main because we have to call the app delegate - DispatchQueue.main.async { [weak self] in - let request = PrintRequest(image: image, printRequestId: "testImagePrintJob", printDeviceId: self?.selectedPrinter?.id) - self?.appDelegate?.cloverConnector?.print(request) - } - } - } else { + defer { + dismiss(animated: true, completion: nil) + } + + guard let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { debugPrint("Error loading image") + return } - dismiss(animated: true, completion: nil) + self.spinner.startAnimating() + UIApplication.shared.isIdleTimerDisabled = true + + + self.resizeImage(image: pickedImage) { [weak self] (resizedImage) in + let request = PrintRequest(image: resizedImage, printRequestId: self?.uniquePrintId, printDeviceId: self?.selectedPrinter?.id) + self?.issuePrintJob(request) + } } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { @@ -221,25 +237,54 @@ extension PrintTestViewController: UIImagePickerControllerDelegate, UINavigation } /// Resizes an image to fit within CloverConnector.MAX_PAYLOAD_SIZE - func resizeImage(image:UIImage) -> UIImage { + func resizeImage(image:UIImage, completion: ((_ image: UIImage) -> Void)?) { var scaledImage = image - guard var scaledData = UIImagePNGRepresentation(image) else { return image } - guard let cloverConnector = (UIApplication.shared.delegate as? AppDelegate)?.cloverConnector else { return image } + guard var scaledData = UIImagePNGRepresentation(image) else { + completion?(image) + return + } + + guard let cloverConnector = appDelegate?.cloverConnector else { + completion?(image) + return + } + debugPrint("Start Size: " + String(describing: scaledImage.size)) - while scaledData.count > cloverConnector.MAX_PAYLOAD_SIZE { - var scale = sqrt((CGFloat(cloverConnector.MAX_PAYLOAD_SIZE) / CGFloat(scaledData.count))) - scale = scale > 0.9 ? 0.9 : scale - debugPrint("Scaling " + String(describing: scale) + "%") - let newSize = CGSize(width: scaledImage.size.width * scale, height: scaledImage.size.height * scale) - UIGraphicsBeginImageContextWithOptions(CGSize(width: newSize.width, height: newSize.height), true, 1.0) - scaledImage.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize)) - guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { return scaledImage } - scaledImage = newImage - guard let newData = UIImagePNGRepresentation(scaledImage) else { return scaledImage } - scaledData = newData - UIGraphicsEndImageContext() - } - debugPrint("Final Size: " + String(describing: scaledImage.size)) - return scaledImage + + //throw onto a background queue because of how heavy the resize could be + DispatchQueue.global().async { + while scaledData.count > cloverConnector.MAX_PAYLOAD_SIZE { + var scale = sqrt((CGFloat(cloverConnector.MAX_PAYLOAD_SIZE) / CGFloat(scaledData.count))) + scale = scale > 0.9 ? 0.9 : scale + debugPrint("Scaling " + String(describing: scale) + "%") + let newSize = CGSize(width: scaledImage.size.width * scale, height: scaledImage.size.height * scale) + UIGraphicsBeginImageContextWithOptions(CGSize(width: newSize.width, height: newSize.height), true, 1.0) + scaledImage.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize)) + guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { + DispatchQueue.main.async { completion?(scaledImage) } + return + } + scaledImage = newImage + guard let newData = UIImagePNGRepresentation(scaledImage) else { + DispatchQueue.main.async { completion?(scaledImage) } + return + } + + scaledData = newData + UIGraphicsEndImageContext() + } + + DispatchQueue.main.async { + debugPrint("Final Size: " + String(describing: scaledImage.size)) + completion?(scaledImage) + } + } } } + +fileprivate extension Array { + func optionalElement(_ i: Index) -> Element? { + return indices.contains(i) ? self[i] : nil + } +} + diff --git a/Example/CloverConnector/RegisterViewController.swift b/Example/CloverConnector/RegisterViewController.swift index 47a8b04..f1c2e89 100644 --- a/Example/CloverConnector/RegisterViewController.swift +++ b/Example/CloverConnector/RegisterViewController.swift @@ -141,38 +141,41 @@ class RegisterViewController:UIViewController, POSOrderListener, POSStoreListene } } + //store a human readable copy of the order for use in sending to the CloverDevice var currentDisplayOrder:DisplayOrder = DisplayOrder() - var itemsToDi = NSMutableDictionary() // POSOrderListener func itemAdded(_ item:POSLineItem) { + guard let itemName = item.item.name, let formattedItemPrice = CurrencyUtils.IntToFormat(item.item.price) else { return } - guard let itemName = item.item.name, - let formattedItemPrice = CurrencyUtils.IntToFormat(item.item.price) else { return } - - let displayLineItem = DisplayLineItem(id: String(arc4random()), name:itemName, price: formattedItemPrice, quantity: String(item.quantity)) + let displayLineItem = DisplayLineItem(id: item.item.id, name:itemName, price: formattedItemPrice, quantity: String(item.quantity)) currentDisplayOrder.lineItems.append(displayLineItem) - itemsToDi.setObject(displayLineItem, forKey: item.item.id as NSCopying) updateTotals() - (UIApplication.shared.delegate as? AppDelegate)?.cloverConnector?.showDisplayOrder(currentDisplayOrder) } + func itemRemoved(_ item:POSLineItem) { + if let index = currentDisplayOrder.lineItems.index(where: { $0.id == item.item.id }) { + currentDisplayOrder.lineItems.remove(at: index) + } + updateTotals() (UIApplication.shared.delegate as? AppDelegate)?.cloverConnector?.showDisplayOrder(currentDisplayOrder) } + func itemModified(_ item:POSLineItem) { - if let displayLineItem = itemsToDi.object(forKey: item.item.id) as? DisplayLineItem { + if let index = currentDisplayOrder.lineItems.index(where: { $0.id == item.item.id }) { + let displayLineItem = currentDisplayOrder.lineItems[index] displayLineItem.quantity = String(item.quantity) displayLineItem.name = item.item.name displayLineItem.price = CurrencyUtils.IntToFormat(item.item.price) } - updateTotals() + updateTotals() (UIApplication.shared.delegate as? AppDelegate)?.cloverConnector?.showDisplayOrder(currentDisplayOrder) - } + func discountAdded(_ item:POSDiscount) { updateTotals() } @@ -192,7 +195,6 @@ class RegisterViewController:UIViewController, POSOrderListener, POSStoreListene (UIApplication.shared.delegate as? AppDelegate)?.cloverConnector?.removeDisplayOrder(currentDisplayOrder) currentDisplayOrder = DisplayOrder() currentDisplayOrder.id = String(arc4random()) - itemsToDi.removeAllObjects() // cleanup DispatchQueue.main.async { [unowned self] in self.currentOrderListItems.reloadData() } diff --git a/Example/CloverConnector/TestViewController.swift b/Example/CloverConnector/TestViewController.swift index 090bb9d..6586849 100644 --- a/Example/CloverConnector/TestViewController.swift +++ b/Example/CloverConnector/TestViewController.swift @@ -162,7 +162,7 @@ public class TestViewController: UIViewController, UITableViewDelegate, UITableV var loadData:Data? cases.removeAllObjects() testResultsTable.reloadData() - if testLoadURL.text?.characters.count == 0 { + if testLoadURL.text?.count == 0 { if let path = Bundle.main.path( forResource: "test1", ofType: "json") { if let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let datastring = String(data: data, encoding: String.Encoding.utf8) { @@ -360,7 +360,7 @@ class ResponseCloverConnector : DefaultCloverConnectorListener { } override func onDeviceActivityStart(_ deviceEvent: CloverDeviceEvent) { - if let io = self.ioMap[deviceEvent.eventState ?? ""] { + if let io = self.ioMap[deviceEvent.eventState?.rawValue ?? ""] { cloverConnector?.invokeInputOption(io) } } @@ -569,7 +569,7 @@ class Case { return Mapper().map(JSONString: vcStr) } } else if var vcVarMarker = payload[JSON_KEYS.VAULTED_CARD].string, - vcVarMarker.characters.removeFirst() == "$" { + vcVarMarker.removeFirst() == "$" { return self.caseRunner?.storedValues[vcVarMarker] as? CLVModels.Payments.VaultedCard } return nil diff --git a/Example/CloverConnector/ViewController.swift b/Example/CloverConnector/ViewController.swift index 08bf907..40172e4 100644 --- a/Example/CloverConnector/ViewController.swift +++ b/Example/CloverConnector/ViewController.swift @@ -29,6 +29,8 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.endpointTextField.delegate = self + if let savedEndpoint = UserDefaults.standard.string(forKey: WS_ENDPOINT) { endpointTextField.text = savedEndpoint } @@ -159,7 +161,7 @@ extension ViewController: AVCaptureMetadataOutputObjectsDelegate { cleanedString = components?.url?.absoluteString } - if components?.url?.absoluteString.characters.last == "?" { + if components?.url?.absoluteString.last == "?" { if var string = components?.url?.absoluteString { string.removeLast() cleanedString = string @@ -172,3 +174,11 @@ extension ViewController: AVCaptureMetadataOutputObjectsDelegate { } } +extension ViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.connect(false) + self.view.endEditing(true) + return true + } +} + diff --git a/Example/Tests/TestStub/TestCloverTransport.swift b/Example/Tests/TestStub/TestCloverTransport.swift new file mode 100644 index 0000000..fd0a2f5 --- /dev/null +++ b/Example/Tests/TestStub/TestCloverTransport.swift @@ -0,0 +1,45 @@ +// +// TestCloverTransport.swift +// CloverConnector +// +// +// Copyright © 2017 Clover Network, Inc. All rights reserved. +// + +import Foundation +@testable import CloverConnector + +class TestCloverTransport: CloverTransport { + + var onMessageCallback:((_ message: [String:Any])->())? + + override func initialize() { + debugPrint("TestCloverTransport.initialize") + } + + + @discardableResult + override func sendMessage(_ message: String) -> Int { + if let dictionary = stringToDict(string:message) { + DispatchQueue.global(qos: .default).asyncAfter(deadline: DispatchTime.now() + 0.01, execute: { [weak self] in + self?.onMessageCallback?(dictionary) + }) + } else { + print("Error parsing Input String") + } + return 0 + } + + func stringToDict(string:String) -> [String:Any]? { + guard let data = string.data(using: .utf8) else { return nil } + var dictionary = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String:Any] + if let validDictionary = dictionary { + for (key,value) in validDictionary { + if let value = value as? String { + dictionary?[key] = stringToDict(string: value) ?? value + } + } + } + return dictionary + } +} diff --git a/Example/Tests/TestStub/TestDeviceConfiguration.swift b/Example/Tests/TestStub/TestDeviceConfiguration.swift new file mode 100644 index 0000000..23c13d2 --- /dev/null +++ b/Example/Tests/TestStub/TestDeviceConfiguration.swift @@ -0,0 +1,45 @@ +// +// TestDeviceConfiguration.swift +// CloverConnector +// +// +// Copyright © 2017 Clover Network, Inc. All rights reserved. +// + +import Foundation +@testable import CloverConnector + +class TestDeviceConfiguration: NSObject, CloverDeviceConfiguration { + var remoteApplicationID: String + + var remoteSourceSDK: String = "com.cloverconnector.ios.test" + + public var maxCharInMessage:Int = 50000 + + public init(remoteApplicationID:String) { + self.remoteApplicationID = remoteApplicationID + super.init() + } + + func getTransport() -> CloverTransport? { + return TestCloverTransport() + } + + func getCloverDeviceTypeName() -> String { + return "" + } + + func getMessagePackageName() -> String { + return "com.clover.remote_protocol_broadcast.app" + } + + func getName() -> String { + return "Test Transport" + } + + func getMaxMessageCharacters() -> Int { + return maxCharInMessage + } + + +} diff --git a/Example/Tests/TestSupport.swift b/Example/Tests/TestSupport.swift new file mode 100644 index 0000000..7041674 --- /dev/null +++ b/Example/Tests/TestSupport.swift @@ -0,0 +1,195 @@ +// +// TestSupport.swift +// CloverConnector_Example +// +// Copyright © 2017 Clover Networks, Inc. All rights reserved. +// + +import XCTest +@testable import CloverConnector +import ObjectMapper + + + + +/// This will run a series of tests (basically a deep compare of the objects). In order to pass, all tests have to pass. +/// The test will first serialize the input, then deep compare the resulting object to the output. +/// The input will be mapped using the type of the output as the pattern to map to. +/// +/// - Parameters: +/// - input: A JSON Representation of the object to be serialized. +/// - output: The BaseMappable object to compare the input to. +/// - Returns: True if all parameters of the resulting object are equal to the matching parameters in the output. +func runContentsTestDeserializationPass(input:String,output:T) -> Bool where T : BaseMappable { + guard let message = Mapper().map(JSONString: input) else { + print("Could not deserialize the message") + return false + } + func testChildren(children:Mirror.Children) -> Bool { + for outputProperty in children { + guard let inputProperty = Mirror(reflecting: message).children.filter({$0.label == outputProperty.label}).first?.value ?? Mirror(reflecting: message).superclassMirror?.children.filter({$0.label == outputProperty.label}).first?.value else { + print("Could not Match Property for Label \(outputProperty.label ?? "nil")") + return false + } + guard let comp = compareAny(lhs: outputProperty.value, rhs: inputProperty) else { + print("Could not Compare Any for Label \(outputProperty.label ?? "nil")") + return false + } + if !comp { + print("Comparison failed for \(outputProperty.label ?? "nil")") + return false + } + } + return true + } + + if !testChildren(children: Mirror(reflecting: output).children) { return false } + if let children = Mirror(reflecting: output).superclassMirror?.children { + if !testChildren(children: children) { return false } + } + + return true +} +/// Compares two Any objects for Equality. +/// Checks for the following types/cases: +/// nil (Any can be nil) +/// Int +/// String +/// Double +/// Method +/// +/// - Parameters: +/// - lhs: Any object to compare +/// - rhs: Any object to compare +/// - Returns: True if the two objects are equal, False if they are not equal, and nil if equality cannot be determined. +func compareAny(lhs:Any,rhs:Any) -> Bool? { + +// print("lhs: \(lhs), rhs: \(rhs)") + if isAnyNil(any: lhs) { + return isAnyNil(any: rhs) + } else { + if isAnyNil(any: rhs) { + return false + } + } + + if let lhsVal = lhs as? Int { + if let rhsVal = rhs as? Int { + return lhsVal == rhsVal + } + } else if let lhsVal = lhs as? String { + if let rhsVal = rhs as? String { + return lhsVal == rhsVal + } + } else if let lhsVal = lhs as? Double { + if let rhsVal = rhs as? Double { + return lhsVal == rhsVal + } + } else if let lhsVal = lhs as? CloverConnector.Method { + if let rhsVal = rhs as? CloverConnector.Method { + return lhsVal.rawValue == rhsVal.rawValue + } + } + + return nil +} + +/// Tests two objects for equality when the type of one side is not yet known. +/// Attempts to cast the test value to the same type as the valid value, and performs an equality test. +/// Also checks for nil for each object. +/// +/// - Parameters: +/// - test: The unknown object of type Any to test for equality +/// - valid: The known object of type T (Equatable) to test against +/// - pass: Whether the equality test should result in a true or a false outcome +/// - Returns: True if the equality test passes, false if it fails, and nil if the two objects are not equatable. +func objectTest(test:Any,valid:T,pass:Bool) -> Bool? where T : Equatable { + if isAnyNil(any: test) { + return isAnyNil(any: valid) + } else { + if isAnyNil(any: valid) { + return false + } + } + + guard let test = test as? T else { + print("Types do not match") + return nil + } + return pass ? test == valid : test != valid +} + + +/// Checks if an Any object is really nil +/// Any is technically a Protocol, not a type, and can therefore hold an Optional, despite not being defined as one. This function checks for that case. +/// +/// - Parameter any: Any... thing +/// - Returns: true if nil, false if not nil +func isAnyNil(any:Any) -> Bool { + let mirror = Mirror(reflecting:any) + return mirror.displayStyle == .optional && mirror.children.count == 0 +} + + + + + + + + + + + + + +/// Takes a BaseMappable object as input, maps that to a JSON String, then uses the JSONSerialization to map back to a JSON Dictionary, and finally compares the results to the passed in dictionary. +/// +/// - Parameters: +/// - input: The object to test +/// - output: A dictionary containing the specific tests to run against the resulting dictionary +/// - Returns: True if all tests pass, False if any test fails +func runContentsTestSerialization(input:T,output:[String:(test:Any?,pass:Bool)]) -> Bool where T : BaseMappable { + guard let messageJSON = Mapper().toJSONString(input) else { + print("Failed to map Object to JSON String") + return false + } + guard let data = messageJSON.data(using: .utf8) else { + print("Failed to write JSON String to Data") + return false + } + guard let dictionary = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String:Any] else { + print("Failed to parse Data to JSON Dictionary") + return false + } + for thisTest in output { + if let validAny = dictionary[thisTest.key], + let validTest = thisTest.value.test { + switch validAny { + case let valid as Int: + if let pass = objectTest(test: validTest, valid: valid, pass: thisTest.value.pass) { + if !pass { return false } + } else { return false } + case let valid as String: + if let pass = objectTest(test: validTest, valid: valid, pass: thisTest.value.pass) { + if !pass { return false } + } else { return false } + default: + print("Could not match a type for \(thisTest.key)") + return false + } + } else { + if thisTest.value.test == nil { + if dictionary[thisTest.key] != nil { return false } + } else { + print("Missing value for key \(thisTest.key)") + return false + } + } + } + return true +} + + + + + diff --git a/Example/Tests/Test_cloverconnector_DefaultCloverConnectorV2.swift b/Example/Tests/Test_cloverconnector_DefaultCloverConnectorV2.swift new file mode 100644 index 0000000..7c23313 --- /dev/null +++ b/Example/Tests/Test_cloverconnector_DefaultCloverConnectorV2.swift @@ -0,0 +1,225 @@ +// +// TestDefaultCloverConnectorV2.swift +// CloverConnector_Tests +// +// Copyright © 2017 Clover Networks, Inc. All rights reserved. +// + +import XCTest +@testable import CloverConnector + +class Test_cloverconnector_DefaultCloverConnectorV2: XCTestCase { + + let remoteApplicationID = "TEST" + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + + // MARK: - Setup Connector + func setupConnector() -> (connector:ICloverConnector, transport:TestCloverTransport)? { + let configuration = TestDeviceConfiguration(remoteApplicationID: remoteApplicationID) + guard let connector = CloverConnectorFactory.createICloverConnector(config: configuration) as? DefaultCloverConnectorV2 else { XCTFail("Failed to instantiate connector"); return nil } + connector.initializeConnection() + connector.isReady = true + guard let transport = connector.device?.transport as? TestCloverTransport else { XCTFail("Failed to instantiate Transport"); return nil } + return (connector,transport) + } + + // MARK: - >> Sale and Auth Fail Validity Checks << + // + // These tests implement an ICloverConnectorListener to listen for validation failures on the initial sale and auth requests being passed into the ICloverConnector + // + // This Test <───────────────┐ + // │ │ + // │ ICloverConnectorListener + // V │ + // DefaultCloverConnectorV2 ───────────┘ + // + + // MARK: Tests + func testSaleValidityCheckFailure() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestFailureValidityCheck(sale:true, saleAmount: 0, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestFailureValidityCheck(sale:true, saleAmount: -1, externalId: "1", onConnection: connection)], timeout: 1) + } + func testAuthValidityCheckFailure() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestFailureValidityCheck(sale:false, saleAmount: 0, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestFailureValidityCheck(sale:false, saleAmount: -1, externalId: "1", onConnection: connection)], timeout: 1) + } + + // MARK: Support + func singleTestFailureValidityCheck(sale:Bool, saleAmount:Int, externalId:String, onConnection connection:(connector:ICloverConnector,transport:TestCloverTransport)) -> XCTestExpectation { + class CCL: ICloverConnectorListener { + init(expectation:XCTestExpectation, connector:ICloverConnector) { + self.expectation = expectation + self.connector = connector + } + var expectation:XCTestExpectation? + var connector:ICloverConnector + func onSaleResponse(_ response: SaleResponse) { + XCTAssertEqual(response.result, ResultCode.FAIL) + expectation?.fulfill() + connector.removeCloverConnectorListener(self) + } + func onAuthResponse(_ authResponse: AuthResponse) { + XCTAssertEqual(authResponse.result, ResultCode.FAIL) + expectation?.fulfill() + connector.removeCloverConnectorListener(self) + + } + func onPreAuthResponse(_ preAuthResponse: PreAuthResponse) { } + func onCapturePreAuthResponse(_ capturePreAuthResponse: CapturePreAuthResponse) { } + func onTipAdjustAuthResponse(_ tipAdjustAuthResponse: TipAdjustAuthResponse) { } + func onVoidPaymentResponse(_ voidPaymentResponse: VoidPaymentResponse) { } + func onRefundPaymentResponse(_ refundPaymentResponse: RefundPaymentResponse) { } + func onManualRefundResponse(_ manualRefundResponse: ManualRefundResponse) { } + func onCloseoutResponse(_ closeoutResponse: CloseoutResponse) { } + func onVerifySignatureRequest(_ signatureVerifyRequest: VerifySignatureRequest) { } + func onVaultCardResponse(_ vaultCardResponse: VaultCardResponse) { } + func onDeviceActivityStart(_ deviceEvent: CloverDeviceEvent) { } + func onDeviceActivityEnd(_ deviceEvent: CloverDeviceEvent) { } + func onDeviceError(_ deviceErrorEvent: CloverDeviceErrorEvent) { } + func onDeviceConnected() { } + func onDeviceReady(_ merchantInfo: MerchantInfo) { } + func onDeviceDisconnected() { } + func onConfirmPaymentRequest(_ request: ConfirmPaymentRequest) { } + func onTipAdded(_ message: TipAddedMessage) { } + func onPrintManualRefundReceipt(_ printManualRefundReceiptMessage: PrintManualRefundReceiptMessage) { } + func onPrintManualRefundDeclineReceipt(_ printManualRefundDeclineReceiptMessage: PrintManualRefundDeclineReceiptMessage) { } + func onPrintPaymentReceipt(_ printPaymentReceiptMessage: PrintPaymentReceiptMessage) { } + func onPrintPaymentDeclineReceipt(_ printPaymentDeclineReceiptMessage: PrintPaymentDeclineReceiptMessage) { } + func onPrintPaymentMerchantCopyReceipt(_ printPaymentMerchantCopyReceiptMessage: PrintPaymentMerchantCopyReceiptMessage) { } + func onPrintRefundPaymentReceipt(_ printRefundPaymentReceiptMessage: PrintRefundPaymentReceiptMessage) { } + func onRetrievePrintersResponse(_ retrievePrintersResponse: RetrievePrintersResponse) { } + func onPrintJobStatusResponse(_ printJobStatusResponse: PrintJobStatusResponse) { } + func onRetrievePendingPaymentsResponse(_ retrievePendingPaymentResponse: RetrievePendingPaymentsResponse) { } + func onReadCardDataResponse(_ readCardDataResponse: ReadCardDataResponse) { } + func onCustomActivityResponse(_ customActivityResponse: CustomActivityResponse) { } + func onResetDeviceResponse(_ response: ResetDeviceResponse) { } + func onMessageFromActivity(_ response: MessageFromActivity) { } + func onRetrievePaymentResponse(_ response: RetrievePaymentResponse) { } + func onRetrieveDeviceStatusResponse(_ response: RetrieveDeviceStatusResponse) { } + } + let expectation = self.expectation(description: "Fail Validation") + connection.connector.addCloverConnectorListener(CCL(expectation:expectation, connector:connection.connector)) + if sale { + connection.connector.sale(SaleRequest(amount: saleAmount, externalId: externalId)) + } else { + connection.connector.auth(AuthRequest(amount: saleAmount, externalId: externalId)) + } + return expectation + } + + + + // MARK: - >> Sale and Auth Valid Messages << + // These tests utilize TestCloverTransport to short circuit the actual transport and provide the message intended for transmission back to this test for analysis + // + // This Test <───────────────┐ + // │ │ + // V │ + // DefaultCloverConnectorV2 │ + // │ onMessageCallback + // V │ + // DefaultCloverDevice │ + // │ │ + // V │ + // TestCloverTransport ────────────┘ + // + + + // MARK: Tests + func testSingleValidSale() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestSaleAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + } + func testMultipleValidSale() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestSaleAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(500, externalId: "abcdefghijklmnopqrstuvwxyz", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(500, externalId: "100000", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(500, externalId: "🍔", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(1, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(50000, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestSaleAmount(5000000000000, externalId: "1", onConnection: connection)], timeout: 1) + } + func testSingleValidAuth() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestAuthAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + } + func testMultipleValidAuth() { + guard let connection = setupConnector() else { XCTFail("Failed to Initialize Connection"); return } + + wait(for: [singleTestAuthAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(500, externalId: "abcdefghijklmnopqrstuvwxyz", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(500, externalId: "100000", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(500, externalId: "🍔", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(1, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(500, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(50000, externalId: "1", onConnection: connection)], timeout: 1) + wait(for: [singleTestAuthAmount(5000000000000, externalId: "1", onConnection: connection)], timeout: 1) + } + + // MARK: Support + func singleTestSaleAmount(_ saleAmount:Int, externalId:String, onConnection connection:(connector:ICloverConnector,transport:TestCloverTransport)) -> XCTestExpectation { + let expectation = self.expectation(description: "Sale Return") + connection.transport.onMessageCallback = setupTransportOnMessageCallbackSale(sale: true, saleAmount: 500, externalId: "1", expectation: expectation) + connection.connector.sale(SaleRequest(amount: 500, externalId: "1")) + return expectation + } + func singleTestAuthAmount(_ saleAmount:Int, externalId:String, onConnection connection:(connector:ICloverConnector,transport:TestCloverTransport)) -> XCTestExpectation { + let expectation = self.expectation(description: "Auth Return") + connection.transport.onMessageCallback = setupTransportOnMessageCallbackSale(sale: false, saleAmount: 500, externalId: "1", expectation: expectation) + connection.connector.auth(AuthRequest(amount: 500, externalId: "1")) + return expectation + } + func setupTransportOnMessageCallbackSale(sale:Bool,saleAmount:Int, externalId:String, expectation:XCTestExpectation) -> ((_ message: [String:Any])->()) { + return { (message:[String:Any]) in + guard let defaultData = self.checkMessageDefaults(message) else { return } + if defaultData.type == "COMMAND" && defaultData.method == "TX_START" { + guard let payload = message["payload"] as? [String:Any] else { XCTFail("Failed to Parse Payload"); return } + guard let requestInfo = payload["requestInfo"] as? String else { return } // don't need to fail for this one + if requestInfo == (sale ? "SALE" : "AUTH") { + guard let payIntent = payload["payIntent"] as? [String:Any] else { XCTFail("Failed to Parse Pay Intent"); return } + guard let transactionType = payIntent["transactionType"] as? String else { XCTFail("Failed to Parse Transaction Type"); return } + XCTAssertEqual(transactionType, "PAYMENT") + guard let amount = payIntent["amount"] as? Int else { XCTFail("Failed to Parse Amount"); return } + XCTAssertEqual(amount, saleAmount) + guard let externalPaymentId = payIntent["externalPaymentId"] as? String else { XCTFail("Failed to Parse External Id"); return } + XCTAssertEqual(externalPaymentId, externalId) + expectation.fulfill() + } + } + } + } + func checkMessageDefaults(_ message:[String:Any]) -> (id:String, type:String, method:String)? { + guard let method = message["method"] as? String else { XCTFail("Failed to Parse Message Method"); return nil } + guard let id = message["id"] as? String else { XCTFail("Failed to Parse ID"); return nil } + guard let type = message["type"] as? String else { XCTFail("Failed to Parse Message Type"); return nil } + + guard let packageName = message["packageName"] as? String else { XCTFail("Failed to Parse Package Name"); return nil } + XCTAssertEqual(packageName, "com.clover.remote_protocol_broadcast.app") + + guard let remoteSourceSDK = message["remoteSourceSDK"] as? String else { XCTFail("Failed to Parse remoteSourceSDK"); return nil } + XCTAssertEqual(remoteSourceSDK, "com.cloverconnector.ios.test") + + guard let remoteApplicationID = message["remoteApplicationID"] as? String else { XCTFail("Failed to Parse remoteApplicationID"); return nil } + XCTAssertEqual(remoteApplicationID, self.remoteApplicationID) + + return(id,type,method) + } + +} diff --git a/Example/Tests/Test_cloverconnector_WebSocketDeviceConfiguration.swift b/Example/Tests/Test_cloverconnector_WebSocketDeviceConfiguration.swift new file mode 100644 index 0000000..a69fd0c --- /dev/null +++ b/Example/Tests/Test_cloverconnector_WebSocketDeviceConfiguration.swift @@ -0,0 +1,40 @@ +// +// TestRemoteSourceSDK.swift +// CloverConnector_Tests +// +// Copyright © 2017 Clover Networks, Inc. All rights reserved. +// + +import XCTest +@testable import CloverConnector + +class Test_cloverconnector_WebSocketDeviceConfiguration: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - remoteSourceSDK + // + // This test examines the remoteSourceSDK in the WebSocketDeviceConfiguration, and compares it to a separately generated + // string based on the main version string. This comparison validates that the remoteSourceSDK is properly extracted + // from the framework bundle, and tangentially checks that both the framework and the example app have been set to + // the same value. + // + func testRemoteSourceSDK() { + guard let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { XCTFail("Failed to get Test Application Version Number"); return } + let remoteSourceSDK = "com.cloverconnector.ios.ws:\(appVersion)" + + class PDC:PairingDeviceConfiguration { + func onPairingCode(_ pairingCode: String) { } + func onPairingSuccess(_ authToken: String) { } + } + let webSocketDeviceConfiguration = WebSocketDeviceConfiguration(endpoint: "192.168.1.1", remoteApplicationID: "TEST", posName: "TEST", posSerial: "TEST", pairingAuthToken: nil, pairingDeviceConfiguration: PDC()) + + XCTAssert(remoteSourceSDK == webSocketDeviceConfiguration.remoteSourceSDK) + } +} diff --git a/Example/Tests/Test_remotepaylib_TerminalMessage.swift b/Example/Tests/Test_remotepaylib_TerminalMessage.swift new file mode 100644 index 0000000..54d6253 --- /dev/null +++ b/Example/Tests/Test_remotepaylib_TerminalMessage.swift @@ -0,0 +1,81 @@ +// +// Test_remotepaylib_TerminalMessage.swift +// CloverConnector_Tests +// +// Copyright © 2017 Clover Networks, Inc. All rights reserved. +// + +import XCTest +import CloverConnector + +class Test_remotepaylib_TerminalMessage: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Serialization + // + // This test takes a TerminalMessage object, serializes it to JSON, and compares the results using introspection to a + // set of tests designed to check that the output JSON is properly formatted. + // + func testSerialization() { + let testMessage = TerminalMessage() + testMessage.text = "Test Message" + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"Test Message",pass:true)])) + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:2,pass:false),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"Test Message",pass:true)])) + + testMessage.text = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",pass:true)])) + + testMessage.text = nil + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:nil,pass:true)])) + + testMessage.text = "" + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"",pass:true)])) + + testMessage.text = "🍔" + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"🍔",pass:true)])) + + testMessage.text = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + XCTAssert(runContentsTestSerialization(input: testMessage, output: ["version":(test:1,pass:true),"method":(test:"TERMINAL_MESSAGE",pass:true),"text":(test:"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",pass:true)])) + + + + } + + // MARK: - Serialization + // + // This test takes a JSON representation of a TerminalMessage object, deserializes it into a TerminalMessage, + // and compares it to an actual TerminalMessage object. + // + func testDeserialization() { + let message = TerminalMessage() + message.text = "Test Message" + message.version = 1 + XCTAssert(runContentsTestDeserializationPass(input: "{\"version\":1,\"method\":\"TERMINAL_MESSAGE\",\"text\":\"Test Message\"}", output: message)) + XCTAssert(!runContentsTestDeserializationPass(input: "{\"version\":2,\"method\":\"TERMINAL_MESSAGE\",\"text\":\"Test Message\"}", output: message)) + message.text = nil + XCTAssert(runContentsTestDeserializationPass(input: "{\"version\":1,\"method\":\"TERMINAL_MESSAGE\"}", output: message)) + message.version = -1 + XCTAssert(runContentsTestDeserializationPass(input: "{\"version\":-1,\"method\":\"TERMINAL_MESSAGE\"}", output: message)) + message.version = 99999999999999 + XCTAssert(runContentsTestDeserializationPass(input: "{\"version\":99999999999999,\"method\":\"TERMINAL_MESSAGE\"}", output: message)) + + // version wrong type + XCTAssert(!runContentsTestDeserializationPass(input: "{\"version\":\"a\",\"method\":\"TERMINAL_MESSAGE\"}", output: message)) + // invalid JSON + XCTAssert(!runContentsTestDeserializationPass(input: "{\"version\":a,\"method\":\"TERMINAL_MESSAGE\"}", output: message)) + + XCTAssert(runContentsTestDeserializationPass(input: "{\"version\":99999999999999,\"method\":\"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\"}", output: message)) + + print("\(#file.components(separatedBy: "/").last ?? "") \(#function):\(#line)") + } + + + +} diff --git a/Example/Tests/Tests.swift b/Example/Tests/Tests.swift deleted file mode 100644 index cb9c390..0000000 --- a/Example/Tests/Tests.swift +++ /dev/null @@ -1,29 +0,0 @@ -import UIKit -import XCTest -import CloverConnector - -class Tests: XCTestCase { - - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() - } - - func testExample() { - // This is an example of a functional test case. - XCTAssert(true, "Pass") - } - - func testPerformanceExample() { - // This is an example of a performance test case. - self.measure() { - // Put the code you want to measure the time of here. - } - } - -} diff --git a/README.md b/README.md index 66585bf..257a7fa 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,13 @@ A Swift 4 implementation of the CloverConnector to enable iOS and MacOS to commu ## Version -Current version: 1.4.0 +Current version: 1.4.1 NOTE: Full support for version 1.4 of the SDK requires version 143 or higher of the Remote Pay app. -NOTE: To use the Swift 2.3 compatible version of this library, you will need to point your Podfile at the [1.4.0-swift2.3](https://github.com/clover/remote-pay-ios/tree/1.4.0-swift2.3) branch as listed below in the code sample. +NOTE: To use the Swift 2.3 compatible version of this library, you will need to point your Podfile at the [1.4.1-swift2.3](https://github.com/clover/remote-pay-ios/tree/1.4.1-swift2.3) branch as listed below in the code sample. ### Dependencies - - ObjectMapper - Provides JSON serialization and deserialization. - SwiftyJSON - Provides simple JSON parsing. - Starscream - provides websocket client capabilities. NOTE: we have forked this and made some small tweaks that improve large-file handling, so be sure to point to our fork (example below). @@ -36,7 +35,7 @@ NOTE: To use the Swift 2.3 compatible version of this library, you will need to ## Using CloverConnector in your project - Update your Podspec to include the queuePriority branch of Starscream, 1.4 branch of CloverConnector, and the Swift 4.0 post_install script - pod 'Starscream', :git => 'https://github.com/clover/Starscream.git', :branch => 'queuePriority' -- pod 'CloverConnector', :git => 'https://github.com/clover/remote-pay-ios.git', :tag => '1.4.0' +- pod 'CloverConnector', :git => 'https://github.com/clover/remote-pay-ios.git', :tag => '1.4.1' - Add the post_install script (see example) to set the Swift version of the pods to 4.0 - Example cocoapod (http://cocoapods.org/) `Podfile` snippet --- @@ -165,8 +164,8 @@ class ConnectionManager : DefaultCloverConnectorListener, PairingDeviceConfigura ## Additional Resources - [Release Notes](https://github.com/clover/remote-pay-ios/releases) -- [Tutorial for the iOS SDK](https://docs.clover.com/build/getting-started-with-cloverconnector/?sdk=ios) -- [API Documentation](https://clover.github.io/remote-pay-ios/1.4.0/docs/index.html) +- [Tutorial for the iOS SDK](https://docs.clover.com/build/getting-started-with-clover-connector/?sdk=ios) +- [API Documentation](https://clover.github.io/remote-pay-ios/1.4.1/docs/index.html) - [Clover Developer Community](https://community.clover.com/index.html) ## License