Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
695 changes: 251 additions & 444 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -127,23 +127,23 @@ class CollectAndRevealViewController: UIViewController {
stackView.addArrangedSubview(collectExpMonth!)
stackView.addArrangedSubview(collectExpYear!)
stackView.addArrangedSubview(collectButton)

stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 5
stackView.alignment = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false

let scrollView = UIScrollView(frame: .zero)
scrollView.isScrollEnabled = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)

scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 2).isActive = true
scrollView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 2).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true

scrollView.addSubview(stackView)
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -10).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
Expand All @@ -153,16 +153,27 @@ class CollectAndRevealViewController: UIViewController {
}
}
@objc func revealForm() {
self.revealContainer?.reveal(callback: ExampleAPICallback())
let revealCallback = Skyflow.RevealCallback(
onSuccess: { response in print("reveal success:", response) },
onFailure: { error in print("reveal failure:", error) }
)
self.revealContainer?.reveal(callback: revealCallback)
}
@objc func submitForm() {
let exampleAPICallback = ExampleAPICallback(updateSuccess: updateSuccess, updateFailure: updateFailure)
container!.collect(callback: exampleAPICallback, options: Skyflow.CollectOptions(tokens: true))
let collectCallback = Skyflow.CollectCallback(onSuccess: updateSuccess, onFailure: updateFailure)
container!.collect(callback: collectCallback, options: Skyflow.CollectOptions())
}
internal func updateSuccess(_ response: SuccessResponse) {
internal func updateSuccess(_ response: Skyflow.CollectResponse) {
print(response)
retryCount = 0
updateRevealInputs(tokens: response.records[0].fields)
for result in response.records {
if let error = result.error {
print("Record failed:", error, "httpCode:", result.httpCode)
}
}
if let fields = response.records.first?.fields {
updateRevealInputs(tokens: fields)
}
print("Successfully got response:", response)
}
internal func updateFailure(error: Any) {
Expand All @@ -172,7 +183,12 @@ class CollectAndRevealViewController: UIViewController {
}
print("Failed Operation", error)
}
internal func updateRevealInputs(tokens: Fields) {
// fields is [String: Any] - column name -> array of {"token","tokenGroupName"} dicts.
internal func firstToken(_ fields: [String: Any], column: String) -> (token: String, tokenGroupName: String?) {
guard let entries = fields[column] as? [[String: Any]], let first = entries.first else { return ("", nil) }
return (first["token"] as? String ?? "", first["tokenGroupName"] as? String)
}
internal func updateRevealInputs(tokens: [String: Any]) {
let revealBaseStyle = Skyflow.Style(
borderColor: UIColor.black,
cornerRadius: 20,
Expand All @@ -189,39 +205,42 @@ class CollectAndRevealViewController: UIViewController {
self.revealed = true
}
let revealCardNumberInput = Skyflow.RevealElementInput(
token: tokens.card_number,
token: self.firstToken(tokens, column: "card_number").token,
inputStyles: revealStyles,
label: "Card Number",
redaction: .REDACTED
redaction: "REDACTED",
tokenGroupName: self.firstToken(tokens, column: "card_number").tokenGroupName
)
self.revealCardNumber = self.revealContainer?.create(
input: revealCardNumberInput,
options: Skyflow.RevealElementOptions()
)
let revealCVVtInput = Skyflow.RevealElementInput(
token: tokens.cvv,
token: self.firstToken(tokens, column: "cvv").token,
inputStyles: revealStyles,
label: "CVV",
redaction: .MASKED
redaction: "MASKED",
tokenGroupName: self.firstToken(tokens, column: "cvv").tokenGroupName
)
self.revealCVV = self.revealContainer?.create(input: revealCVVtInput)
let revealNameInput = Skyflow.RevealElementInput(
token: tokens.cardholder_name,
token: self.firstToken(tokens, column: "cardholder_name").token,
inputStyles: revealStyles,
label: "Card Holder Name",
redaction: .DEFAULT

redaction: "DEFAULT",
tokenGroupName: self.firstToken(tokens, column: "cardholder_name").tokenGroupName
)
self.revealName = self.revealContainer?.create(input: revealNameInput)
let revealExpirationMonthInput = Skyflow.RevealElementInput(
token: tokens.expiry_month,
token: self.firstToken(tokens, column: "expiry_month").token,
inputStyles: revealStyles,
label: "Expiration Month",
redaction: .PLAIN_TEXT
redaction: "PLAIN_TEXT",
tokenGroupName: self.firstToken(tokens, column: "expiry_month").tokenGroupName
)
self.revealExpirationMonth = self.revealContainer?.create(input: revealExpirationMonthInput)
let revealExpirationYearInput = Skyflow.RevealElementInput(
token: tokens.expiry_year,
token: self.firstToken(tokens, column: "expiry_year").token,
inputStyles: revealStyles,
label: "Expiration Year"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,6 @@
* Copyright (c) 2022 Skyflow
*/

import Foundation
import Skyflow

public class ExampleAPICallback: Skyflow.Callback {
private var updateSuccess: ((SuccessResponse) -> Void)?
private var updateFailure: ((Any) -> Void)?
private var decoder: JSONDecoder?

internal init(updateSuccess: @escaping (SuccessResponse) -> Void, updateFailure: @escaping (Any) -> Void) {
self.updateSuccess = updateSuccess
self.updateFailure = updateFailure
self.decoder = JSONDecoder()
}

internal init() {
}

public func onSuccess(_ responseBody: Any) {
if updateSuccess == nil {
print("success:", responseBody)
return
}
do {
let dataString = String(data: try! JSONSerialization.data(withJSONObject: responseBody), encoding: .utf8)
let responseData = Data(dataString!.utf8)
let jsonResponse = try decoder!.decode(SuccessResponse.self, from: responseData)

updateSuccess!(jsonResponse)

print("success:", jsonResponse)
} catch {
print("error deserializing", error)
}
}

public func onFailure(_ error: Any) {
print(error)
if updateFailure != nil {
print("failure:", error)
return
}
print("onfailure", error)
}
}
// No longer needed - use Skyflow.CollectCallback / Skyflow.RevealCallback directly
// (see CollectAndRevealViewController.swift), which already deliver typed responses
// (Skyflow.CollectResponse / Skyflow.RevealResponse) without a custom Callback subclass.
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,6 @@
* Copyright (c) 2022 Skyflow
*/

import Foundation

struct SuccessResponse: Codable {
let records: [Records]
}

struct Records: Codable {
let fields: Fields
let table: String
}

struct Fields: Codable {
let cardholder_name: String
let card_number: String
let expiry_month: String
let expiry_year: String
let cvv: String
let skyflow_id: String
}
// No longer needed - the SDK now provides typed responses directly
// (Skyflow.CollectResponse / Skyflow.RevealResponse), so this sample no longer
// needs to declare its own local response structs.
3 changes: 1 addition & 2 deletions Samples/CollectAndRevealSample/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ source 'https://github.com/CocoaPods/Specs.git'

target 'CollectAndRevealSample' do
#use_frameworks!
pod 'AEXML', '4.6.1'

# Pods for skyflow-iOS-sample-app
pod 'Skyflow', ">= 1.23.0"
pod 'Skyflow', ">= 1.25.0"

end
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,6 @@
* Copyright (c) 2022 Skyflow
*/

import Foundation
import Skyflow

public class ExampleAPICallback: Skyflow.Callback {
private var updateSuccess: ((SuccessResponse) -> Void)?
private var updateFailure: ((Any) -> Void)?
private var decoder: JSONDecoder?

internal init(updateSuccess: @escaping (SuccessResponse) -> Void, updateFailure: @escaping (Any) -> Void) {
self.updateSuccess = updateSuccess
self.updateFailure = updateFailure
self.decoder = JSONDecoder()
}

internal init() {
}

public func onSuccess(_ responseBody: Any) {
if updateSuccess == nil {
print("success:", responseBody)
return
}
do {
let dataString = String(data: try! JSONSerialization.data(withJSONObject: responseBody), encoding: .utf8)
let responseData = Data(dataString!.utf8)
let jsonResponse = try decoder!.decode(SuccessResponse.self, from: responseData)

updateSuccess!(jsonResponse)

print("success:", jsonResponse)
} catch {
print("error deserializing", error)
}
}

public func onFailure(_ error: Any) {
print(error)
if updateFailure != nil {
print("failure:", error)
return
}
print("onfailure", error)
}
}
// No longer needed - use Skyflow.CollectCallback / Skyflow.RevealCallback directly
// (see ViewController.swift), which already deliver typed responses
// (Skyflow.CollectResponse / Skyflow.RevealResponse) without a custom Callback subclass.
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,6 @@
* Copyright (c) 2022 Skyflow
*/

import Foundation

struct SuccessResponse: Codable {
let records: [Records]
}

struct Records: Codable {
let fields: Fields
let table: String
}

struct Fields: Codable {
let cardholder_name: String
let card_number: String
let expiry_month: String
let expiry_year: String
let cvv: String
let skyflow_id: String
}
// No longer needed - the SDK now provides typed responses directly
// (Skyflow.CollectResponse / Skyflow.RevealResponse), so this sample no longer
// needs to declare its own local response structs.
Loading
Loading